listening for click event on dynamic content and determining parent element

622 views Asked by At

I have a wall of posts that are dynamically generated, and with it I am trying to reproduce the same functionality Facebook has when you click the comment link it puts the focus on the textarea below it. However, I can't seem to get a hold of the right textarea within that wall. Let's say we have 15 posts, and therefore we have 15 of those comment links, and textareas to comment with. Now, I use jquery to listen for that event...

$(".wall-post").on("click", ".comment", function (event) {

event.preventDefault();

var id = $(".wall-post").attr("id");

//this keeps logging the same id
//I have also tried referring to 'this' but that does not work 
console.log(id);    

$("#"+id+ " .post-comment").focus();

});

I thought perhaps bubbling could be used to get an id of the parent element of the actual link that was clicked. I unfortunately don't think I can actually use bubbling for this purpose though. So now I am just shooting in the dark.

Any suggestions are welcome

3

There are 3 answers

0
GregL On BEST ANSWER

I believe that the markup is going to be something like this (in shorthand):

.wall-post#<id>
    .content (or whatever)
    .comments
        .comment <-- [1]
    .post-comment

Inside your click handler, this will refer to the comment node itself, shown at [1] above.

So what you would want to do is go from there back up to the .wall-post that contains it, and then find within that the .post-comment node.

That would be:

$(this).closest('.wall-post').find('.post-comment').focus();

You don't even need to mess around with extracting the id at all!

0
Gareth Alined On

You problem lays with

var id = $(".wall-post").attr("id");

With this line your searching for objects with the class "wall-post" and getting their ID's. Rather what you need to be doing is getting the object that was actually clicked.

Try using

var id = $(this).attr("id");

"this" relates to the object that that was actually clicked.

What I recommend doing though is

$(this).find(".post-comment").focus();

Using "this" you can then use find to search for elements (eg post-comment) and focus on them.

0
nbrooks On

You can use closest to find the parent post, and then use find within the context of the parent element to find the text-area. See the demo below.

$(function() {
  $("#wall").on('click', '.add-comment', function(e) {
    e.preventDefault();
    $(this)
      .closest('.post')
      .find('.post-comment')
      .focus();
  });
});
.post {
  width: 300px;
  padding: 2px;
  margin: 4px;
  border: 1px solid lightblue;
}
.post-text {
  margin-top: 0px;
  margin-bottom: 2px;
  padding: 0px;
}
.add-comment {
  display: block;
  margin-top: 0px;
  margin-bottom: 15px;
}
.comment {
  display: block;
  border-top: 1px solid lightgray;
  background-color: #f6f7f8;
}
.post-comment {
  margin-top: 5px;
  border-radius: 4px;
  width: 95%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="wall">
  <div class="post">
    <p class="post-text">The rain in spain falls mainly on the plain.</p>
    <a href="#" class="add-comment">comment</a>
    <div class="comment-section">
      <span class="comment">This is cool!</span>
      <span class="comment">I like it!</span>
      <textarea class="post-comment" placeholder="Add a comment..."></textarea>
    </div>
  </div>
  <div class="post">
    <p class="post-text">Super-cali-fragialistic-expi-ali-docious</p>
    <a href="#" class="add-comment">comment</a>
    <div class="comment-section">
      <span class="comment">That's weird!</span>
      <textarea class="post-comment" placeholder="Add a comment..."></textarea>
    </div>
  </div>
</div>