Ask Ben: Iterating Over An Array In jQuery, One Index Per Click
Ben, I'm desperate. I've been all over the Internet looking for some clue how to do this: How would I use .each() with .click to have a single button that would iterate through an array, one object at a time, each time it is clicked? I tried something like:
var myarray = [(#div0),(#div1),(#div2)];
$( myarray ).each(
But, obviously that doesn't work. I need the one button, to slide one panel at a time, per each click, in succession. Does that make sense?
When I read your question, the first thing that immediately popped into my mind was jQuery's data() method. I discovered the data() method recently and it blew my mind! If you have not seen it before, jQuery's data() method allows us to associate arbitrary data with any of our DOM elements. What I'm thinking is that if we bind an "Index" value and the actual collection of jQuery elements to our button, then we can easily iterate over the collection, one index per click:
As seen in the video, each time we click the button, a new item in our unordered list is shown (using slideDown()). The code for this is quite straightforward:
As you can see in the code, we are associating a "config" structure with our DOM element, the button. Then, whenever the button is clicked, we retreive that associated "config" data and use the contained "Index" and "Collection" data as needed. jQuery is so powerful, I'd be surprised if there wasn't an even easier way to do this; but, this was the first thing that popped into my mind.
Want to use code from this post? Check out the license.
If I wanted to utilize more specifically the IDs of certain objects, instead of the list items, how would I do that?
If you wanted to use IDs, you could simply build the Collection element the same way you did in the question:
Collection: [$("#div0"), $("#div1"), $("#div2")]
The only difference now is that each element in the array contains a jQuery object. As such, when you reference later on, you wouldn't need to re-wrap it in the $() method:
$( objConfig.Collection[ objConfig.Index++ ] ).slideDown();
... vs. ...
objConfig.Collection[ objConfig.Index++ ].slideDown();
Notice that the latter does not use the $() before calling .slideDown(). This has to do with the fact that you are using a jQuery stack in the first and standard array in the second.
Thank you very much. I'm going to spend a lot of time on your blog. Your articles have been the most productive learning on jQuery I've found. Keep up the good work...
Always glad to help. Please feel free to ask me for any demos - it's how I spend my mornings :)
Now I'm really going to get confusing.
Each of the DIVs in my array have "X" buttons, where I use slideUp() to remove them. If I have iterated through all of the array objects, then remove one or more of the DIVs, how can I "reset" the array so that I can click and add them back, if need?
The difference here is that you have to use a jQuery stack - you can't just use an array for your collection (since we need to filter on it). You can still add arbitrary elements to the same jQuery stack:
Hope that helps.
Hi Ben. Great script. It has very nearly helped me to get exactly what I need. However, I need to tweak it and I just can't get it to work. What I am looking for is a way to hide all but the first three items on load (as opposed to hiding all items). Then I need a way to reduce the number of items back down to a minimum of three. I am trying to reproduce something similar to the BBC home page (bbc.co.uk) where clicking the plus/minus buttons shows/hides additional items. Any help to finish this off would be most appreciated. I can email you the code I have so far if required?
To hide everything after 3rd element, you can use the selector: gt():
$( "div:gt(2)" ).hide()
Since gt() is zero-based, greater than 2 will exclude 0, 1, and 2.
Many many thanks, Ben. I never knew about using :gt in JQuery. That makes things a lot simpler...
was looking for a simple approach to showing and hiding individual profiles on a click of an anchor. This gave me a massive input.
I know this thread is a few years old but the script is doing exactly what I want to do. However, I need to create a backbutton as well that goes reverse through the divs.
I have created the same exact function but used ++backorder.Index for the backwards instead of forwardorder.Index++ for forwards. However, this is not working as expect. It seems that the two data arrays need to relate to eachother so they can tell where in the index each is.
Articulating this is helping but if anyone has any ideas, I am alle ears.
Hi Ben, thank you for your excellent Blog first. Then i wanted with your code create one site with 2 Buttons "back" and "next". And use for each element their own css code from extern css-file, but until now after a week still no solution. is it possible? in wich direction should i research? i'm new in jquery and in big trouble, :(. Please help!? Thank you!