0

I have dynamically added content with data stored in jQuery's .data() cache. When the content is dynamically created there is also a dynamically created button for each div (Note that each generated div is storing the data mentioned above). When I try to click on one of the buttons, the event listener that is set up for the button click event says that the value of $(this) is the Window and not the button that was clicked.

I ultimately want to call this $(this).parent().data('commentID') to get the stored id value from the parent div so that the modal that pops up as a confirmation of deletion can simply make an AJAX call to a URL that ends with commentID (I have commented out what I would call if the $(this) was selecting the correct thing).

Here is a CodePen of the working example. Please note that you will have to open the Dev Tools Console to see that the $(this) yields the Window instead of the button that was clicked. https://codepen.io/anon/pen/pBXaKw?editors=1010

Here is the HTML

<button type="button" value="Search" class="btn btn-primary" id="searchCommentBtn">Generate comments</button>

<section id="commentsSection">

</section>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title" id="myModalLabel">Modal title</h4>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>

Here is the JS

$('#searchCommentBtn').click(() => {
  for(let i=0; i<4;i++) {
    let WFTComment = $('<div class="work-task-comment-div">'+i+'</div>').data('commentID', i);
    WFTComment.append('</br>', createBtn('myModal', 'Remove'));
    $('#commentsSection').append(WFTComment);
  }
});


var createBtn = (targetModal, btnName) => {
    let btn = $('<button type="button" class="btn btn-sm btn-dark removeCommentBtn" data-toggle="modal" data-target="#' + targetModal + '">' + btnName + '</button>');
    return btn;
}

$('#commentsSection').on('click', 'button', (e) => {
    console.log($(this));
    // let commentID =  $(this).parent().data('commentID');
    // $('#confirmDelete').on('click', () => {
    //   $.ajax({
    //     method: 'POST',
    //     url: 'api/CommentsAPI/' + commentId
    //   })
    // })
});
prestondoris
  • 339
  • 4
  • 11
  • 1
    Possible duplicate of [Are 'Arrow Functions' and 'Functions' equivalent / exchangeable?](https://stackoverflow.com/questions/34361379/are-arrow-functions-and-functions-equivalent-exchangeable) – Taplar May 01 '19 at 22:37
  • 2
    Arrow functions do not change context. Use normal functions for the bindings if you want `this` to reflect the element the event is being processed for – Taplar May 01 '19 at 22:38
  • Thank you! I didn't realize this about Arrow Functions. That fixes the problem. – prestondoris May 01 '19 at 22:44

1 Answers1

0

The fix is to simply remove the Arrow Function from the event listener and use a traditional function call.

$('#commentsSection').on('click', 'button', function(e) {
    console.log($(this));
    // let commentID =  $(this).parent().data('commentID');
    // $('#confirmDelete').on('click', () => {
    //   $.ajax({
    //     method: 'POST',
    //     url: 'api/CommentsAPI/' + commentId
    //   })
    // })
});
prestondoris
  • 339
  • 4
  • 11