Ask Ben: Displaying The Next Hidden Element Using jQuery (Update)

Posted January 28, 2009 at 3:15 PM by Ben Nadel

Tags: Javascript / DHTML, Ask Ben

This is just a quick update to my previous post on iterating over an array in jQuery. After I posted the solution this morning, it was mentioned that we might want to update it to allow visible elements to be hidden and then re-shown via the button click. The update to this is small and actually simplifies the code - rather than keeping an internal index of the next item to be shown, we are simply going to show the first hidden element in our jquery stack:

 
 
 
 
 
 
 
 
 
 

The updated code is as follows:

  • <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  • <html>
  • <head>
  • <title>jQuery Data Demo With Iterative Click</title>
  •  
  • <script type="text/javascript" src="jquery-1.3.1.pack.js"></script>
  • <script type="text/javascript">
  •  
  • // When the document loads, initialize the button.
  • $(
  • function(){
  • var jButton = $( "button" );
  •  
  • // First, hide all the list items.
  • $( "li" ).hide();
  •  
  • // Hook up the "close" links.
  • $( "li a" )
  • .attr( "href", "javascript:void( 0 )" )
  • .click(
  • function(){
  • $( this ).parent().slideUp();
  • }
  • )
  • ;
  •  
  •  
  • // Now, we are going to bind data to the button.
  • // Since we want to be able to add/remove the
  • // elements, we are not going to deal with an
  • // index. Rather, we are gonna go by the first
  • // hidden element in the collection.
  • jButton.data(
  • "config",
  • {
  • Collection: $( "li" )
  • }
  • );
  •  
  • // Now that we have our data bound, let's bind
  • // the click event.
  • jButton.click(
  • function( objEvent ){
  • var jThis = $( this );
  •  
  • // Get the config data out of the button.
  • var objConfig = jThis.data( "config" );
  •  
  • // Find the first hidden element in the
  • // jQuery stack.
  • var jHidden = objConfig.Collection.filter( ":hidden:first" );
  •  
  • // Try to show the hidden one (if none
  • // were returned, this will simply get
  • // passed over.
  • jHidden.slideDown();
  •  
  • // Prevent default event (form submit).
  • objEvent.preventDefault();
  • return( false );
  • }
  • );
  • }
  • );
  •  
  • </script>
  • </head>
  • <body>
  •  
  • <h1>
  • jQuery Data Demo With Iterative Click
  • </h1>
  •  
  • <form>
  • <button>Show List Item</button>
  • </form>
  •  
  • <ul>
  • <li>
  • I am list item One. <a>close</a>.
  • </li>
  • <li>
  • I am list item Two. <a>close</a>.
  • </li>
  • <li>
  • I am list item Three. <a>close</a>.
  • </li>
  • </ul>
  •  
  • </body>
  • </html>

The magic sauce here is the way in which we locate the element to show once the button has been clicked:

  • var jHidden = objConfig.Collection.filter( ":hidden:first" );

The filter() method takes our original collection and returns a sub-collection of elements that match the given selectors. This filter uses two selectors, :hidden, which finds all invisible elements (or Inputs of type=hidden), and :first, which limits the collection to the first match. Now, because jQuery methods are not destructive (meaning that they return a new jQuery stack leaving the original jQuery stack unaltered), we can be sure that this filter does not change our Collection variable in any way. Thanks to this behavior, we can call this filter() method each time the button is clicked and it will always be searching the same master collection.




Reader Comments

Jan 29, 2009 at 10:41 AM // reply »
4 Comments

Ben...this is incredible, and so are you. Thank you for everything.


Jan 29, 2009 at 10:43 AM // reply »
11,314 Comments

@Kevin,

Glad to help!


Jul 17, 2009 at 5:00 PM // reply »
1 Comments

This is great!

How would I apply this to two or more seperate lists?


Aug 26, 2009 at 8:39 AM // reply »
1 Comments

thanx its usefull


Sep 6, 2009 at 1:23 PM // reply »
1 Comments

This is great!

How would I apply this to two or more seperate lists?


Sep 15, 2009 at 1:53 PM // reply »
1 Comments

And in 1.3.2?? Do we have to resort to using .filter to get just the elements that have css visibility=hidden?


Sep 18, 2009 at 4:45 PM // reply »
11,314 Comments

@Richard,

It depends on what your code is doing I guess. You can always use the :hidden pseudo select in the main selector. I guess, I'm not sure what you're asking?


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Jun 20, 2013 at 3:15 AM
A Billion Wicked Thoughts By Ogi Ogas And Sai Gaddam
nice post i love it thanks 4 u :) ... read »
seb
Jun 20, 2013 at 2:32 AM
Working With Inherited Collections In AngularJS
@mike, @ben, The best article about scope and prototypal prototypical inheritance in angularjs is http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical- ... read »
Jun 20, 2013 at 2:17 AM
ColdFusion NumberFormat() Exploration
Nice read thanks Ben, Is there a way to mask a negative number? Long story short in the finance sector when you go 'short' on a stock you want the price to fall this is a good thing because you are ... read »
Jun 20, 2013 at 1:09 AM
The Beauty Of The jQuery Each() Method
my html code : <html> <head> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="nss.js"> ... read »
Jun 19, 2013 at 11:31 PM
Directive Link, $observe, And $watch Functions Execute Inside An AngularJS Context
@Ben, bunch to learn indeed, but thats fun part : ) ... read »
Jun 19, 2013 at 10:41 PM
Referencing ColdFusion Query Columns In A Loop Using Both Array And Dot Notation
Burdock-roots Are you going fat day by day? You need to be good for your family and make some money too. So we bring for you a best product that helps you to be more energetic every day. You will b ... read »
Jun 19, 2013 at 9:52 PM
Working With Inherited Collections In AngularJS
I recognize the applicability of your solution, and how easy it makes to share data across multiple views or even "submodules" of rather simple application. But it seems to me that it creat ... read »
Jun 19, 2013 at 9:38 PM
Directive Link, $observe, And $watch Functions Execute Inside An AngularJS Context
@Alesei, Glad you like it. Even after working with AngularJS for months, I still get a bunch of unexpected, "$digest is already in progress". So hard to debug sometimes! ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools