WebDevDanno WebDevDanno - 6 months ago 20
HTML Question

jQuery get data attribute on click not working

I have a script that will append to two places on my web application. One is a list item and the other is a hidden field on a HTML form (which I process the data in a PHP service file).

However, I want that if a user clicks the 'x' icon that all the elements are removed that have the same ID.

I have a good idea how to do this but my script below doesn't even log the ID. The

.control
block is giving me the issue. The
#add
code block successfully appends the HTML.

Am I missing something obvious?

$("#add").click(function() {

// RENDER LIST
var playerList = ""; //
playerList += "<li class='selection'>" + $("#player").val() + "<i class='fa fa-close control' data-id='" + $("#playerGUID").val() + "'> </i>" + "</li>";

$(playerList).appendTo("#playerList");

// ADD GUID TO SUBMISSION VALUES
var playerHTML = "";
playerHTML += "<input data-id='" + $("#playerGUID").val() + "' type='hidden' name='playerGUID[]' value='" + $("#playerGUID").val() + "' />";

$(playerHTML).appendTo("#selected-players");

// CLEAR INPUT FIELD
$("#player").val('');
});

$(".control").click(function() {
$targetID = $(this).attr('data-id');
console.log("Selected ID:" + $targetID);

// REMOVE WILL COME HERE
});

Answer

$(".control") doesn't exist at the time you bind the click event. You will need to delegate the event like so:

$(document).on("click", ".control", function() {
    $targetID = $(this).attr('data-id');
    console.log("Selected ID:" + $targetID);
   // REMOVE WILL COME HERE
});

What happens here is that jQuery will bind a listener on the document (which always exists) rather than the .control which will not exist until you create it via a click to the #add. That way if can catch events on elements with class control even if the elements themselves were added later.

Check jQuery.on under Direct and delegated events for more details.

Note: Instead of using $(document) you can bind the event on any element which will be a parent of .control and is available when you bind the event (e.g. body). Ideally you'd want to bind it to the closest parent element which is present when the document is loaded.