Event handlers within a loop / event delegation

I currently use javascript to create a html table.

When the user clicks on a button. It appends a tr to the table.

Inside the tr I also append a select2 <select> element.

The method I did so far was to make the id of the select element to be accompanied by a number. It was something like item-project-no-0 and item-project-no-1.

But now I need to register the event listener for all the select elements in that table. Initially, I thought that it would be something like this:

$('#item-project-no-' + x).on('select2:select', function (e) {    
});

There is another method another person that had suggested was to use something like this:

$(document).on("select2:select", ".myClass", function() {
console.log("event fired");
}

I am not sure is it because I don’t have a very good understanding of jquery/javascript. Because I assumed that only when a selection is made then the string “event fired” will be logged on the console? Its seems that even when the select element is being created and appended to the tr, the string “event fired” was also logged on the console.

I also need assistance related to this problem. I currently initialise the select element I was talking about above like this:

    $("#item-project-no-" + numberCounter).select2({
        ajax: {
            url: currentUrl + "api/INV_API/projSelect2",
            data: function (params) {
                return {
                    q: params.term, // search term

                };
            },
            dataType: 'json',
            type: "GET",
            processResults: function (data) {
                return {
                    results: $.map(data, function (obj) {
                        if (obj.SUBNO == "") {
                            return { id: obj.JOBNO, text: obj.JOBNO + "-" + obj.SHORTNM };
                        } else {
                            return { id: obj.JOBNO, text: obj.JOBNO + "-" + obj.SHORTNM + ":" + obj.SUBNO };
                        }
                    })
                };
            }


        }
    });

When using the method below, how do I access the selected option’s value? Does it involve the use of $(this) ?

$(document).on("select2:select", ".myClass", function() {
}

There’s a lot to tackle here, but I’ll try:

  1. The reason the other person suggested you use the $('document').on(...) jQuery method is that it creates a single instance of the select2:select event handler to handle all of your select elements (this is called “event delegation” in jQuery). In your approach, each Select2 widget has its own copy of the event handler, which takes more memory and can potentially cause memory leaks. I’m not sure why the “delegated” version seems to fire the select2:select event when the Select2 widget is initialized, but you could easily detect this situation (and ignore it) since there would not be an actual selection—unless you’re pre-selecting one of the items in your data (but that doesn’t seem to be the case from the code you posted above). The select2:select event that is passed to your event handler contains an object that allows your handler to determine (a) the <select> element where the selection occurred and (b) the actual selection that was made (see the example at the link I provided, and investigate the e.params object in your browser’s console to see all the data it provides).

  2. The answer to your second question is to use the e.params object that Select2 passes to your select2:select event handler. When using jQuery event delegation, this refers to the DOM element on which the event handler is attached (in this case, the document element). You could use the target field of the event object, but the params object provides the select element (in `e.params.data.element, I believe) plus a lot of other useful data.

Good luck!