knot22 knot22 - 4 months ago 10
Javascript Question

event delegation on parent element for dynamically created child elements

I am attempting to attach an on click event to dynamically created li tags to call a function which takes one argument. The argument to be passed is whatever string is in each li's value property. Below are snippets of code from my program.



<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

//this is a sample of the format of data in fileList
{"files":["backups","FilesAndFolders.php"]}

//this data is made usable in the the JS code like so

var extracted = JSON.parse(data);
var fileList = extracted.files;


//the li's are being generated by this code which is called by a main function within the JS script
function pathContents(fileList)
{
var list = $('<ul/>').addClass('files');
$.each(fileList, function (_, file) {
$('<li/>').addClass('file').attr('value', file).text(file).appendTo(list);
});
return list;
}

//after main function gets list back from pathContents() it calls this function
function addOnClickToPathContents(fileList)
{
$('.files').on('click', '.file', function(){
var file = fileList[this.value];
pathBuilder(file);
});
}

<ul class="files">
<li value="backups" class="file">backups</li>
<li value="FilesAndFolders.php" class="file">FilesAndFolders.php</li>
</ul>





The problem with this code is it's assigning the event to the ul rather than to each li. Is there a way to modify it so it assigns the on click event to each child li?

Answer

The real problem is that li element has no property called value, this.value will always return 0. Instead, you can use attr() method:

$('.files').on('click', '.file', function(){
    var file = $(this).attr("value");
    pathBuilder(file);
});

If you want to access the file from your fileList array by using the li index, you can use index() method:

$('.files').on('click', '.file', function(){
    var file = fileList[$(this).index()];
    pathBuilder(file);
});

I hope this will help.

Comments