The Bndr
The Bndr

Reputation: 13394

change different element on .click()

I'm not sure, how to use .click in the right way.

I looked at the manual (http://api.jquery.com/click/) but could not find the answer for my problem:

I'm generating an div structure with JS like this:

<div>
   <img id='img_1' src="click.gif">
</div>
<div id='content_1'> Text</div>

Lots of those blocks are generated with the following function. At the end, each image gets an click event to change the css of the related text: click on img_1 changes css on content_1. I try this code (simplified version):

$.each(data, function(selector,content) {
     id=prepare(selector);
     $('#boxDiv').append('    <div>\
                               <img id="img_'+id+'" src="click.gif">\
                             </div>\
                             <div id="content_'+id+'"> Text</div>');
     $('#img_'+id).click(function(a) {
                         $('#content_'+id).css('height','100px');});
});

But this code does not work as I exacted.

Every 'img_'+id Element gets his related click event (so far, so god) But the function does not change the css of the related 'content_'+id! All the time, the last content element is changed. It looks like, that the .click call-back function does not get the idat the time of adding click event, but at the time of execution the callback function. At this time, the id is (of course) always the last element.

So the question is, how to bring the current (related) id inside the .click -callback function?

//Update: I'm not sure, if using live() could help in this case: i tried this, without any success. The problem is not an missing click event. The Problem is, that at every click, the callback-function is fired by using the last id. Example. The generated content looks like this:

<div>
   <img id='img_1' src="click.gif">
</div>
<div id='content_1'> Text</div>
<div>
   <img id='img_2' src="click.gif">
</div>
<div id='content_2'> Text</div>
<div>
   <img id='img_3' src="click.gif">
</div>
<div id='content_3'> Text</div>

The JS code binds one click event to img_1, one click event to img_2 and one click event to img_3. I changed the content of the callback function to:

$('#expand_'+id).live('click',function() {console.info(id);});

SO i see the content of ID: by clicking img_1 or img_2 id is 3. Probably because, 3 is the last value for the each loop. So how can i get the related id inside the call-back?

Thank you for any kind of help.

Upvotes: 0

Views: 340

Answers (4)

Felix Kling
Felix Kling

Reputation: 816930

Found the problem in your fiddle (and your updated code):

You forgot to put varin front of id, which makes it global. All event handlers reference the same id and its value is the one from the last iteration.

Declare it as

var id = ....;

to make it local.


That said, I would use jQuery to create all the elements:

$.each(data, function(selector,content) {
     var id = selector;

     var $img = $('<span />', {
         id: 'img_' + id,
         text: 'click'
     }).click(function() {
          $('#content_'+id).css('height','100px');
     });

     var $div = $('<div />', {
         id: 'content_' + id,
         text: 'Text'
     });

     $('<div />').append($img).append($div).appendTo('#boxDiv');
});

There are also other ways to find the #content_X elements. In your structure, this element is always the next sibling of the parent of the image. So instead searching for the element with this ID, inside the event handler, you could do:

$(this).parent().next().css(...);

Or even bind the event handler to the parent div instead directly to the image.

Upvotes: 1

genesis
genesis

Reputation: 50982

Don't you mean

$.each(data, function(id,content) {
     $('#boxDiv').append('    <div>\
                               <img id="img_'+id+'" src="click.gif">\
                             </div>\
                             <div id="content_'+id+'"> Text</div>');
     $('#img_'+id).click, function(a) {
                         $('#content_'+id).css('height','100px');
     });
});

? There were two missing # before ID

Upvotes: 0

jtsao22
jtsao22

Reputation: 1972

Instead of using the .click call-back function, you should use the .live call-back function. Quoting the jquery docs:

"Description: Attach a handler to the event for all elements which match the current selector, now and in the future."

Try this:

$.each(data, function(id,content) {
 $('boxDiv').append('    <div>\
                           <img id="img_'+id+'" src="click.gif">\
                         </div>\
                         <div id="content_'+id+'"> Text</div>');
 $('#img_'+id).live('click', function() {
                     $('content_'+id).css('height','100px');});
});

Upvotes: 0

James Allardice
James Allardice

Reputation: 166031

The click event handler will have access to the id (and content) variable, as it's defined in the parent function. In JavaScript, inner functions have access to all the variables of the function in which they are defined.

The problem is simply that you are missing the # ID selector from a couple of your jQuery selector string:

$('#boxDiv').append('...');
//some code removed
$('#content_' + id).css('height', '100px');

Upvotes: 0

Related Questions