开发者

jQuery toggle() with dynamic div ID's

I need some help with some dynamic jQuery - if thats what it would be called. Basically, I have a number of DIVs, each with the same name, except an increasing number is added on the end - for example:

<div id="category-1"></div>
<div id="category-2"></div>
<div id="category-3"></div>

....so and and so forth. On the main menu, I want to create buttons that toggle each item, so there would be a button to toggle category-1, category-2, and so forth.

The ability to add/remove categories is going to be part of a CMS (wordpress), so the jQuery needs to somehow count how many "category-" there are on the page, and then create a button for each one in the main menu.

I know how to create a toggle button in jQuery, however I have had no luck getting the dynamic-ness that I need (if thats even a word!). My first and only attempt so far has been to use inline jQuery encased in PHP tags, so that a jQuery toggle button is generated for each category DIV - it seemed to generate the code correctly when I viewed source, but the buttons didn't work, probably because PHP is server side and jQuery is clie开发者_Python百科nt side. (thats just a guess).

Does anyone know how I create the jQuery code I need?

Thanks Zach


This is the best way I could come up with:

var divs = $('div[id^="category-"]');
var num = divs.length;

for (i=1; i<=num; i++) {
    $('<button class="toggles" />')
        .text('Toggle div ' + i)
        .appendTo('#divToAddButtonsTo');
}

$('.toggles').live('click',
                   function(){
                       var thisIs = $(this).index();
                       $('div[id^="category-"]').eq(thisIs).toggle();
                   });

JS Fiddle demo.

Obviously this is run inside the $(document).ready().

References:

  • attribute-starts-with ^= selector.
  • toggle().
  • live().
  • appendTo().
  • index().


Start with getting the category ids, so we can build buttons accordingly (If you're building buttons on the server side, just ignore the first step, and do it on the server side instead.)

So we'll give the category divs a class like this

<div id="category-1" class="category-class"></div>

Then each over the divs to get their id stored in an array

var categories = [];
$(".category-class").each(function(i) {
     categories[i] = $(this).attr("id").replace("category-", "");
});

Now that we have all the category ids and we know how many they are, let's create the buttons dynamically

$.each(categories, function(i) {

  // append buttons with the same id number as the category divs
  $("#someDiv").append("<a id='button_"+categories[i]+"' href='/something' class='toggle-button'>button "+i+"</a>");

});


$(".toggle-button").live("click", function (event) {
      //prevent propagation
      event.preventDefault();

      // get the matching id
      var id = $(this).attr("id").replace("button_", "");

      // toggle the div with the same id as the button 
      $("#category-"+id").toggle();
});

I haven't tried the code, so I don't know if the syntax is 100% right, but you get the point I hope!

We just each over the category divs which now has a class, we'll fetch the ids in an array. Now we build the buttons accordingly to the category divs, with a matching id.

Then we create a live handler for the click event, so when someone clicks a button, we'll fetch the id from it, which matches with a category div, and we'll toggle the div with the matching id.

Good luck!


Give your div elements a common class attribute, which you can then use in a single jQuery selector to find all of them in one go, e.g.

$('.cat').each(function() {       // for each element with class "cat"
    $('<button>')                 // create a button
    .text($(this).attr('name'))   // whose text is the cat element's "name" attribute
    .click((function(div) {       // with a click handler
        return function() {
            $(div).toggle();      // that toggles 'div'
        }
    })(this)                      // which is bound to 'this'
    .appendTo('#container');      // and the button added to a container
});

Working example at http://jsfiddle.net/ax2UR/1/

Note the use of the automatically invoked anonymous function in the click handler which is necessary to create a locally scoped copy of 'this' to represent the div that's being iterated over in the .each() loop.

EDIT - modified to follow the OP's mark up where he's used <div name="..."> to pass the label for each div's toggle button.


You can certainly count the number of item which has names that includes "category". Then you create a button for each of them. the code for finding all elements with id like category is something like: $(div[id='category']); //starts with

You can look up the pattern of JQuery if you are interested in more complex patterns.


Create button for each

$('div[id^="category-"]').each(function(index,value){
$(this).after('<a href="#" id="toggle-"'+index+'>toggle</a>');
});

attach toogle event

$('a[id^="toggle-"]').live('click',function(){
$("#"+this.id.replace("toggle-","category-")).toggle();
});


Assuming you can create a corresponding button for each div on the server side:

  1. Create a button for each div on the server side with a rel attribute that contains the id for the corresponding button. i.e.

<input type="button" rel="1">

So the rel attribute stores the corresponding div id. 2. Loop through the buttons with .each and assign the click handler:

    $('.my_buttons').each(function () {
    $(this).click( function () {
        $('#category-' + $(this).attr('rel')).toggle();
    });
});

If you for some reason can't generate the buttons on the server side (I can't think of a logical reason why you couldn't though), then simply loop through each div using .each and create a corresponding button with a click handler attached.

Edit: Here's a JSFiddle that shows a working concept.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜