0

I make an AJAX call to a PHP file, and then create formatted HTML if the data was successfully retrieved.

//Function called after AJAX success
function createHTML(data) {
    for( var i = 0; i <= data.length; i++) {
        var label = $("<label>").addClass("checkbox-inline");

        var input = $("<input>").attr("type", "checkbox");
        input.attr("name", "date[]");
        input.attr("class", "date");
        input.attr("value", data[0]['date']);
        label.append(input);
        label.append("data[0]['date']");

        $(".checkboxes").append(label);
        $(".checkboxes").append("<br />");
    }
}

The resulting HTML will look something like this:

 <div class="checkboxes">
    <label class="checkbox-inline">
        <input type="checkbox" name="date[]" class="date" value="2018-01- 
        01">2018-01-01
    </label>
    <br />
    <label class="checkbox-inline">
        <input type="checkbox" name="date[]" class="date" value="2018-01- 
        02">2018-01-02
    </label>
    <br />
  </div>

enter image description here

What I want to do is grab the value of one of the newly created check boxes once it's clicked, but whenever I try to do it nothing happens.

This is what I'm trying to call:

$(".date").on("click", function(){
    console.log(this.value);
});

Is it because the HTML is created after an AJAX call that you can't use an "on click" event?

Bpicks
  • 33
  • 1
  • 5
  • you're going to have to re-register your click events on your newly added elements. making sure you don't double apply it to existing elements. – Scuzzy Oct 12 '18 at 05:55
  • I think you need to check if the CB was checked, look at this post: https://stackoverflow.com/questions/7031226/jquery-checkbox-change-and-click-event – tomer raitz Oct 12 '18 at 05:58
  • You must append '$(".date").on("click", function(){ console.log(this.value); });' to function createHTML() after other her code. – Choo Hwan Oct 12 '18 at 06:06
  • You have logical errors BTW. You're using data.length for your for loop when you should be using data.length-1 so that you don't throw, Arrays start at 0. You should also be using [i] instead of [0] to loop over all items. – Canolyb1 Oct 12 '18 at 06:27

4 Answers4

3

You can use it as

$("body").on("click", '.date', function(){
    console.log(this.value);
});

Which can bind the click function on 'date' class whenever it is created in DOM.

balakrishnan
  • 383
  • 4
  • 12
1
  1. for( var i = 0; i <= data.length; i++) { ==> for( var i = 0; i < data.length; i++) {
  2. input.attr("value", data[0]['date']); ==> input.attr("value", data[i]['date']);
  3. label.append("data[0]['date']"); ==> label.append(`${data[i]['date']}`);

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>

<div class="checkboxes"></div>

<script type="text/javascript">
    //Function called after AJAX success
    function createHTML(data) {
        for (var i = 0; i < data.length; i++) {
            var label = $('<label>').addClass('checkbox-inline');

            var input = $('<input>').attr('type', 'checkbox');
            input.attr('name', 'date[]');
            input.attr('class', 'date');
            input.attr('value', data[i]['date']);
            label.append(input);
            label.append(`${data[i]['date']}`);

            $('.checkboxes').append(label);
            $('.checkboxes').append('<br />');
        }
        $(".date").on("click", function(){
            console.log(this.value);
        });
    }

    window.onload = setTimeout(createHTML([{'date': '2018-01-01'}, {'date': '2018-01-02'}]), 1000)
</script>
</body>
</html>
ChengWei
  • 46
  • 5
  • Format your code and explain why is this an answer to the question. – Jeroen Heier Oct 12 '18 at 07:12
  • Format my code? it's formatted already. And I fix some bugs ( or typo? ) of the original code. Then I add a click handler to these new dynamic created radio buttons through class selector just after they all appended to the container, a div element with the class name 'checkboxes'. It's no need to use delegated event handler. Generally speaking, using delegated event handler is a best practice. In this case, I don't think it's the cause. – ChengWei Oct 12 '18 at 08:41
  • But i don't see any value in repeating the images at the end of the post. Start your post with a sentence explaining that 1,2,3 are the corrections you have made. See also [here](https://codeblog.jonskeet.uk/2009/02/17/answering-technical-questions-helpfully/). – Jeroen Heier Oct 12 '18 at 09:37
  • Oh, the last two images are evidence to proof my code is correct. Both element tree and console log match original request. It's my habit to capture running result and attach it to the code. If any question, I'll remove them. – ChengWei Oct 12 '18 at 16:04
0

Works Fine with me.

You have to use $('body')

$('body') actually selects the element by the tag name

$("#showcheckbox").click(function(){
  $("#opDiv").html('<input type="checkbox" name="date[]" class="date" value="2018-01-01"> 2018-01-01');  
});

$("body").on("change", '.date', function(){
    
    alert(this.value);
    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<span id="showcheckbox">Click me</span>
<br><br>
<div id = "opDiv"></div>
TarangP
  • 2,711
  • 5
  • 20
  • 41
0

When an element is created dynamically, any predefined event does not get attached to it. hence required to register event listener on parent element, like below.

$("body").on("click", '.date', function(event) {
    alert( $(event.currentTarget).attr('value'));
});

second parameter for on is the target on which you want to trigger event(dynamically created element's class).

Madhura KM
  • 140
  • 1
  • 10