views:

11349

answers:

6

I'm working with jQuery for the first time and need some help. I have html that looks like the following:

<div id='comment-8' class='comment'>
    <p>Blah blah</p>
    <div class='tools'></div>
</div>

<div id='comment-9' class='comment'>
    <p>Blah blah something else</p>
    <div class='tools'></div>
</div>

I'm trying to use jQuery to add spans to the .tools divs that call variouis functions when clicked. The functions needs to receive the id (either the entire 'comment-8' or just the '8' part) of the parent comment so I can then show a form or other information about the comment.

What I have thus far is:

<script type='text/javascript'>

    $(function() {
        var actionSpan = $('<span>[Do Something]</span>');
        actionSpan.bind('click', doSomething);

        $('.tools').append(actionSpan);
     });

     function doSomething(commentId) { alert(commentId); }

</script>

I'm stuck on how to populate the commentId parameter for doSomething. Perhaps instead of the id, I should be passing in a reference to the span that was clicked. That would probably be fine as well, but I'm unsure of how to accomplish that.

Thanks, Brian

+1  A: 
andy
A: 

You don't have a lot of control over the arguments passed to a bound event handler.

Perhaps try something like this for your definition of doSomething():

function doSomething() { 
  var commentId = $(this).parent().attr('id');
  alert(commentId); 
}
Adam Bellaire
Check the HTML, it's actually the grandparent that has the id attribute, not the parent.
Jim
Indeed, the object with the trigger is inserted into the 'tools' div, I missed that. Thanks.
Adam Bellaire
+5  A: 

Event callbacks are called with an event object as the first argument, you can't pass something else in that way. This event object has a target property that references the element it was called for, and the this variable is a reference to the element the event handler was attached to. So you could do the following:

function doSomething(event)
{
    var id = $(event.target).parents(".tools").attr("id");
    id = substring(id.indexOf("-")+1);
    alert(id);
}

...or:

function doSomething(event)
{
    var id = $(this).parents(".tools").attr("id");
    id = substring(id.indexOf("-")+1);
    alert(id);
}
Jim
A: 

It might be easier to loop through the comments, and add the tool thing to each. That way you can give them each their own function. I've got the function returning a function so that when it's called later, it has the correct comment ID available to it.

The other solutions (that navigate back up to find the ID of the parent) will likely be more memory efficient.

<script type='text/javascript'>

$(function() {
  $('.comment').each(function(comment) {
    $('.tools', comment).append(
      $('<span>[Do Something]</span>')
          .click(commentTool(comment.id));
    );
  });
});

function commentTool(commentId) {
  return function() {
    alert('Do cool stuff to ' + commentId);
  }
}

</script>
Nick
A: 

Getting a little fancy to give you an idea of some of the things you can do:

var tool = $('<span>[Tool]</span>');

var action = function (id) {
    return function () {
        alert('id');
    }
}

$('div.comment').each(function () {
    var id = $(this).attr('id');

    var child = tool.clone();
    child.click(action(id));

    $('.tools', this).append(child);
});
neouser99
A: 

The function bind() takes, takes the element as a parameter (in your case the span), so to get the id you want from it you should do some DOM traversal like:

function doSomething(eventObject) { 
    var elComment = eventObject.parentNode.parentNode; //or something like that, 
                                                       //didn't test it
    var commentId= elComment.getAttribute('commentId')
    alert(commentId); 
}
Victor