0

I'm aware similar questions have been asked and answered but I can't seem to get them to apply to my issue.

Below is the code that sends an ajax post when the form is submitted

  $form.on("submit", function(event) {
    event.preventDefault();

    $.ajax({
      url: url,
      data: JSON.stringify({ description: desc }),
      type: "POST",
      contentType: "application/json",
      dataType: "json",
      success: function(data) {

        $(".list").append(
          '<li><input type="checkbox" value="' +
            data.id +
            '">description</li>"
        );
        createOnClicks(data.id);
      },
      error: function(error) {
        //list errors      },
      complete: function() {
       //reset form
      }
    });
  });

this is part of the createOnClicks() function:

function createOnClicks(id) {
    var listId = "#" + id;

    $(listId).on("click", function(event) {
      var value = $(this).is(":checked");

      if (value) {
        console.log("checked");
        $.ajax({
          url: "/listapi/" + id + "/complete",
          type: "POST",
          contentType: "application/json",
          dataType: "json",
          success: function(data) {
            console.log(data);
            $(listId)
              .parent("li")
              .addClass("complete");
          }
        });
      } else { ... 
    }
});

createOnClicks works correctly when it is called on elements that are there when the page loads, but won't work on elements that are added with the ajax post.

$(listId) returns an empty object when called within createOnClicks(), despite on the line above `console.log(listID) shows the appropriate value.

1 Answers1

1

This should apply a click handler to all elements with matching selector even if added after pageload.

$(document).on('click', '#list_id', (event)=>{/* some code */})

Per comments, this should help do what you need:

<html>
<body>
    <button id="add">add</button>
    <div id="container">
    </div>
    <script type="text/javascript">
    var postHandler = (event)=>{
        console.log('my id is', event.currentTarget.getAttribute('data-postid'));
    }
    var number_of_elements = 0;
    document.getElementById('add').addEventListener('click', (event)=>{
        let new_element = document.createElement('div');
        new_element.innerText = "hello";
        new_element.className = "cool_element";
        new_element.setAttribute('data-postid', number_of_elements++);
        new_element.addEventListener('click', postHandler);
        document.getElementById('container').appendChild(new_element);
    })
    </script>
</body>
</html>
Gavin
  • 2,214
  • 2
  • 18
  • 26
  • they all have a different id, list_1, list_2 etc.. – Samantha Aug 23 '19 at 10:10
  • Then use the same class on them all – Rory McCrossan Aug 23 '19 at 10:10
  • @Samantha if you have many elements that need identifying for the same thing use a class instead of IDs. `class="cool_list"` in the element, and `.cool_list` in the selector. – Gavin Aug 23 '19 at 10:11
  • if you look at the `createOnClicks` function, I need to add an id specific post request for each element. – Samantha Aug 23 '19 at 10:13
  • 2
    @Samantha try using attributes to store data like that. Perhaps `data-postid="1"` when creating the element. Then access in the handler with `event.currentTarget.getAttribute('data-postid');` not ideal using substrings of element IDs for that. – Gavin Aug 23 '19 at 10:15
  • I've tried that, the attribute is available in the function if I do `console.log(listId)` but as soon as it is passed through to `$(listId).on("click", function(event)` it shows an empty object. presumably because the dynamic element hasn't been created yet – Samantha Aug 23 '19 at 10:26
  • Try accessing through the event passed through. The scope of the variable 'listId' probably not available to the function – Gavin Aug 23 '19 at 10:39