greatFritz
greatFritz

Reputation: 201

Using Jquery to dynamically create Divs with Buttons that have a function to close the div

So I am trying to create new divs of a fruit, but I am added an X to help call a special function that will delete it. My only problems is when I dynamically create my div+span I end up with problems when I try to use the onclick function

Here is my HTML code

<html>
    <div id="listContents">

    </div>
</html>

Also below is my script code

    list = ["apple", "strawberry", "banana"]
for(var i = 0; i < list.length; i++){
    $("#listContents").append('<div>' + list[i] + '<span class="picker" id="close" onclick="removeFruit(list[i].toString())"> (X)</span></div>');
}


function removeFruit(fruit){
    console.log("Here is the fruit you selected");
}

Obviously I want to be able to delete these when the X button is clicked but right now I am having trouble getting the onclick function to work correctly. Also here is a jsfiddle I quickly made

Upvotes: 0

Views: 650

Answers (3)

Bryan Dellinger
Bryan Dellinger

Reputation: 5294

you could add the id while you are doing the map.

["apple", "strawberry", "banana"].map(x => {
  $("#listContents").append(`<div id="${x}"> 
    							${x}
                                <span 
                                  class="picker"
                                   onclick="(() => document.getElementById('${x}').remove())()">
                                  (X)
                                  </span>
                                </div>`)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="listContents">

Upvotes: 0

Israel Medina
Israel Medina

Reputation: 1

Similar to what others are saying, id should be reserved for only one-time use.

Also, when you are dynamically creating the items you give each onClick the string "removeFruit(list[i].toString())" so it is not actually looking for a function called removeFruit but instead it has the actual string "removeFruit".

When creating the html you could instead give each item a fruitName attribute equal to the fruit name like so.

list = ["apple", "strawberry", "banana"]
        for (var i = 0; i < list.length; i++) {
            $("#listContents").append('<div>' + list[i] + '<span class="picker" fruitName='+ list[i] + '>(X)</span></div>');
        }

and then we can target these using a click listener rather than an onClick and use what fruitName is equal to by using the $(this).attr('fruitName').

$("#listContents").on('click', '.picker', function(e) {
            removeFruit($(this).attr('fruitName'))
        })


        function removeFruit(fruit) {
            console.log('You clicked ' + fruit);
        }

$(this) will reffer to whichever span you clicked on and the .attr() will look for the fruitName and find what it is equal to.

Upvotes: 0

mgarcia
mgarcia

Reputation: 6325

You are creating an span with id close for each item in your list. Ids should be unique throughout the whole document. Since you are not using the id attribute, I suggest you delete it.

Also, you are appending an onclick event in all your span items. I would use event delegation.

Furthermore, since you are converting the elements in your array into HTML elements, you could use map method to do the transformation and generate all the HTML for your items.

Lastly, you can add a data attribute to account for the item index. You can then read that attribute using jQuery data method.

Having that into account, the code could look like:

var list = ["apple", "strawberry", "banana"];
var $list = $("#listContents");
$list.on('click', '.picker', function(ev) {
    var idx = $(ev.target).data('idx');
    removeFruit(list[idx]);
});

$list.append(list.map(function(item, idx) {
    return '<div>' + item + '<span class="picker" data-idx="' + idx + '"> (X)</span></div>';
}).join(''));

function removeFruit(fruit) {
    console.log("Here is the fruit you selected");
}

Upvotes: 2

Related Questions