2

I am creating a web page, and populating values in that page based on a CSV file.

Depending on the number of columns in the CSV file, I want to generate a list of checkboxes with those values. I have that working:

function updateKey() {
    var key = '';
    for (var item in data[0])
    {
        key += '<input type="checkbox" name="' + item + '" value="' + item +'"> '
        key += item + "<br>\r\n"
    }
    document.getElementById('key').innerHTML = key
}

Now I want to detect when a user checks these checkboxes, and run functions based on that. For example, let's say I want to only show the rows in the CSV file that are checked. I would need to listen for the checkbox state to change, and then calculate which checkboxes are checked, and then update the HTML accordingly.

I was looking on stackoverflow and found a function like this:

var selected = [];
$('#key input[type="checkbox"]:checked').each(function () {
    selected.push($(this).attr('name'));
});

However, it does not seem to trigger when I check the boxes. I added an alert window right after the push function, and nothing seems to happen. Is it because these check boxes are generated after the page loads? Is there a way to listen to these dynamically created checkboxes?

Shawn Tabrizi
  • 9,495
  • 1
  • 22
  • 50
  • 2
    You're looking for a delegated event handler. `$(document).on('change', '#key input[type=checkbox]', function() { //One of the checkboxes changed })` - You can capture the checkbox that got changed within this function by using `$(this)`. [I've made a small example for you](https://jsfiddle.net/gddqtbyt/1/). – Tyler Roper Jun 20 '17 at 20:15
  • Santi, this worked perfectly! If you turn it into a post, I will give you the answer :) – Shawn Tabrizi Jun 20 '17 at 20:18

2 Answers2

2

What you're looking for is a simple event binding.

The only slight hiccup you may come across is that your elements are dynamically created, so you'll either have to individually attach an event to each and every one of them when they're created (don't do this) or you can use what's known as Event Delegation.

Rather than bind the event to the element itself, we just put a listener on its container. This one listener will handle all of the checkboxes.

A basic example might look as follows:

$("#key").on('change', 'input[type=checkbox]', function() { 
    var selected = [];
    $('#key input[type="checkbox"]:checked').each(function () {
        selected.push($(this).attr('name'));
    });
    console.log(selected);
})

$("#key").append("<input type='checkbox' name='check1'>");
$("#key").append("<input type='checkbox' name='check2'>");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Check the boxes below.

<div id="key"></div>
Tyler Roper
  • 20,529
  • 6
  • 30
  • 51
0

Take a look at the .on() function. You have to bind a change event to all generated checkboxes after adding them. Your posted example will only trigger if you call it separately (on a button handler or something).

Example:

var selected = [];

function updateKey() {
    var key = '';
    for (var item in data[0])
    {
        key += '<input type="checkbox" name="' + item + '" value="' + item +'">'
        key += item + "<br>\r\n"
    }
    document.getElementById('key').innerHTML = key

    $('#key input[type="checkbox"]').change(function () {
        // your stuff
    });
}

Additional information for the change handler: How to handle change of checkbox using jQuery?

Tyr
  • 2,779
  • 1
  • 10
  • 21
  • I think you are coming to the same conclusion as [this post](https://stackoverflow.com/questions/27650787/how-to-detect-select-elements-created-from-javascript-jquery). Is that correct? I need to attach it to the containing div? – Shawn Tabrizi Jun 20 '17 at 20:15
  • No, you are attach the handler to the checkbox directly. – Tyr Jun 20 '17 at 20:22