2

Probably beginner jquery question... Here is my problem:

I have dynamically created list of div elements. Each has its' specific content, id and a toggle icon in the corner. When I press toggle icon it causes the following: expands/hides the content of the div and changes the icon.

My initial thinking was to call 2 custom jquery functions something like this (the number is dynamically inserted by PHP):

<div id="div152" >
  <div id="content152">some content</div>
  <a id="toggle-icon152" href="javascript:void(0);" onclick="togglemydiv(content152); changeicon(icon152)">
    <div id="icon152">someicon</div>
  </a>
</div>

Now this works in some browsers but obviously it is not how it should be done as it doesn't work in FF in windows or in fiddle. Any help would be appreciated.

4 Answers 4

4

I suggest that you don't hardcode your ids into js.

Here is a suggestion how to do it simpler:

html:

<div id="div152" >
  <div id="content152">some content</div>
  <a id="toggle-icon152" data-bind-action="toggle-content" href="#">
    <div id="icon152">someicon</div>
  </a>
</div>​

js:

$("a[data-bind-action='toggle-content']").click(toggleContent);

function toggleContent(){
    var a = $(this);
    var div = a.prev();
    div.toggle();
    e.preventDefault();
    return false;
}

Se how it works on jsfiddle.

Here is version which does not assume your content is prev element to a, but you add attribute to your link so it knows what to toggle: http://jsfiddle.net/PrmX5/4/

I have added html5 data- attribute to identify anchor to which toggle function needs to be attached from js, you can do this different, of course, using class or other (faster?) jQuery selector.

As @coosal said in its answer, if divs are dynamically generated (ajax or on client), you need to use live instead of binding on document.ready, so here is version which uses live: http://jsfiddle.net/PrmX5/5/

Sign up to request clarification or add additional context in comments.

3 Comments

cool thanks, one more question, what do you use if you can't use element.prev(). It is common that you have content or icon nested in something else.
Goran, just another maybe question. I've done it as you suggested and it works, but I can't help myself it looks like the whole think is slower than using inline call from onclick.
If you are using live version, it probably is slower, but if you are generating html on server, and loading it all at once, you can use normal binding (version 4). If you are generating it on the server like I'm thinking you are, but loading with ajax, you need to attach event handler in callback function. Try first using version 4 to see if performance is better?
3

I would recommend use external script instead of inline JS

$('#toggle-icon152').on('click', function(e){ 
   $('#content152').toggle();  // or do something else
   e.preventDefault();
}

reference http://api.jquery.com/toggle/

3 Comments

thanks, just one detail which is not clear to me - how do I pass the dynamically created ID in the function.
in that case you need to do some detection. Is link id number 152 and content number 152 always matches? If yes, then you can do some regex
You can add data- attribute into a tag which contains id of target div to toggle.
2

As the divs are dynamically generated, we need live() function to trigger any event . . Check live() function of jquery

jQuery("#toggle-icon152").live("click",function(){
togglemydiv("content152");
changeicon("icon152");
})

2 Comments

+ for being the first who noticed that he may need $.live, but it is also possible that he is referring to php or other server generation as dynamic.
thanks, good to know. in this case it's all done on server in php.
0

Assuming you've written togglemydiv somewhere and it takes an id as its parameter, you'd need to put 'content152' in quotation marks - otherwise its trying to pass an object that doesn't exist into your function (it probally is coming through as type undefined)

As alex suggested above, you should separate your javascript from your HTML tags - its best practice..

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.