SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    752
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    jQuery: Hiding Select Boxes

    HI jQuery Experts,

    I have a problem with hiding and unhiding the select boxes.

    In the code below, by default the first select box is displayed. Selecting any option, will display the next select box, and so on.

    I problem comes when I want it such that, if 4 select boxes are displayed and I change the first select box, i need to hide all select boxes after the second one, similarly if I change the second one, the fourth should be removed.


    Pls take a look into the entire code:

    Code:
      <script src="http://code.jquery.com/jquery-latest.js"></script>
    <style>
    .hidden{display: none;}
    </style>
    <table border=1>
    	<tr>
    		<td>
    			<select id="aa" class="mySelect">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv1">Test 1</div>
    		</td>
    	</tr>
    	<tr>
    		<td>
    			<select id="bb" class="mySelect hidden">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv2">Test 1</div>
    		</td>
    	</tr>
    	<tr>
    		<td>
    			<select id="cc" class="mySelect hidden">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv3">Test 1</div>
    		</td>
    	</tr>
    	<tr>
    		<td>
    			<select id="dd" class="mySelect hidden">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv4">Test 1</div>
    		</td>
    	</tr>
    
    </table>
    
    <script>
    	$(document).ready(function(){
    		
    		$('.mySelect').change(function(){
    			$(this).nextAll('select:first').removeClass('hidden');
    		});
    
    
    	});	
    </script>

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by cancer10 View Post
    problem comes when I want it such that, if 4 select boxes are displayed and I change the first select box, i need to hide all select boxes after the second one, similarly if I change the second one, the fourth should be removed.
    The standard technique to achieve this is to hide all of them when any change occurs, and then to only show the ones up to and including the one that was changed.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    752
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    yes and how do you show all the select boxes thats prior to the ones that changed?

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by cancer10 View Post
    yes and how do you show all the select boxes thats prior to the ones that changed?
    After hiding them you loop through them one by one, possibly by using the .each() method, unhiding them as you go. When you come across the current select field, you can cancel the rest of them by returning false from the function.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Hi Cancer10

    This isn't something that's too hard to achieve

    The way it will need to work is:
    • We'll need to get a reference to all the selects
    • When we have that reference, we'll be able to figure out what the index was of the one that changed (in the change event handler)
    • Now that we know which one changed, it's trivial to unhide the next element, and make sure that the elements after the next one remain (or become) hidden
    Code JavaScript:
    $(document).ready(function(){
     
        // let's get a reference to all the selects.
        // this is actually an array of DOM elements
        var $mySelects = $(".mySelect");
        var idx = 0;
     
        $('.mySelect').change(function(){
     
             // find the index of the changed element
             var idx = $mySelects.index(this);
     
            // now set the next select to visible
            $mySelects.eq(idx+1).removeClass("hidden");
     
            // make sure that all selects that come *after* the next element are hidden
            $(".mySelect:gt("+(idx+1)+")").addClass("hidden");
        });
     
     });
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  6. #6
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    752
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Thank you AussieJohn,

    Your solution works like a charm.

    I have a question just to make myself clear.

    What does the $ symbol do in var $mySelects

    Thanks

  7. #7
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Whenever I assign a jQuery object to a variable, I tend to prefix that variable with a $ - it doesn't do anything extra, but it's kind of a personal code convention so that I can easily identify variables that are cached jQuery objects in my code.
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  8. #8
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    752
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Thanks for explaining that.

    Now, that I understood the basics of this, I ahve a more complex structure. Where I have 3 sets of select boxes with 4 select box in each set. With select class named as "mySelectA", "mySelectB", "mySelectC",

    These sets are independednt of each other. The concept I mentioned in my first post applies to all of these but these sets should work independly. But I need to pull all the code under a single CHANGE event.

    Whats the most efficient code to make this happen without much duplication of variables or codes. Or is it not possible at all?


    Code:
    <table border=1>
    	<tr>
    		<td>
    			<select id="aa" class="mySelectA">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv1">Test 1</div>
    		</td>
    	</tr>
    	<tr>
    		<td>
    			<select id="bb" class="mySelectA hidden">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv2">Test 1</div>
    		</td>
    	</tr>
    	<tr>
    		<td>
    			<select id="cc" class="mySelectA hidden">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv3">Test 1</div>
    		</td>
    	</tr>
    	<tr>
    		<td>
    			<select id="dd" class="mySelectA hidden">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv4">Test 1</div>
    		</td>
    	</tr>
    
    ------------
    	<tr>
    		<td>
    			<select id="ee" class="mySelectB">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv1">Test 1</div>
    		</td>
    	</tr>
    	<tr>
    		<td>
    			<select id="ff" class="mySelectB hidden">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv2">Test 1</div>
    		</td>
    	</tr>
    	<tr>
    		<td>
    			<select id="gg" class="mySelectB hidden">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv3">Test 1</div>
    		</td>
    	</tr>
    	<tr>
    		<td>
    			<select id="hh" class="mySelectB hidden">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv4">Test 1</div>
    		</td>
    	</tr>
    ---
    	<tr>
    		<td>
    			<select id="ii" class="mySelectC">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv1">Test 1</div>
    		</td>
    	</tr>
    	<tr>
    		<td>
    			<select id="jj" class="mySelectC hidden">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv2">Test 1</div>
    		</td>
    	</tr>
    	<tr>
    		<td>
    			<select id="kk" class="mySelectC hidden">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv3">Test 1</div>
    		</td>
    	</tr>
    	<tr>
    		<td>
    			<select id="ll" class="mySelectC hidden">
    				<option>123</option>
    				<option>456</option>
    			</select>
    			<div class="dv4">Test 1</div>
    		</td>
    	</tr>
    
    
    </table>

    Thanks for all your help.

  9. #9
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by cancer10 View Post
    These sets are independednt of each other. The concept I mentioned in my first post applies to all of these but these sets should work independly. But I need to pull all the code under a single CHANGE event.
    Yeah, this is definitely within the realms of the achievable, it is a little bit more complicated though.

    Firstly, I'd suggest some changes to the markup, so it will be a bit easier to work this out. Essentially what we want is to get groups of select boxes. So, just staying with your currently table layout, I've create 3 tables, each with a class of "mySelectGroup" so we can identify them.

    Code HTML4Strict:
    <table border="1" class="mySelectGroup">
        <tr>
            <td>
                <select id="aa" class="mySelect"> 
                    <option>123</option>
                    <option>456</option>
                </select>
                <div class="dv1">Test 1</div>
            </td>
        </tr>
        <tr>
            <td>
                <select id="bb" class="mySelect hidden">
                    <option>123</option>
                    <option>456</option>
                </select>
                <div class="dv2">Test 1</div>
            </td>
        </tr>
        <tr>
            <td>
                <select id="cc" class="mySelect hidden">
                    <option>123</option>
                    <option>456</option>
                </select>
                <div class="dv3">Test 1</div>
            </td>
        </tr>
        <tr>
            <td>
                <select id="dd" class="mySelect hidden">
                    <option>123</option>
                    <option>456</option>
                </select>
                <div class="dv4">Test 1</div>
            </td>
        </tr>
    </table>
     
    <hr>
     
    <table border="1" class="mySelectGroup">
        <tr>
            <td>
                <select id="ee" class="mySelect">
                    <option>123</option>
                    <option>456</option>
                </select>
                <div class="dv1">Test 1</div>
            </td>
        </tr>
        <tr>
            <td>
                <select id="ff" class="mySelect hidden">
                    <option>123</option>
                    <option>456</option>
                </select>
                <div class="dv2">Test 1</div>
            </td>
        </tr>
        <tr>
            <td>
                <select id="gg" class="mySelect hidden">
                    <option>123</option>
                    <option>456</option>
                </select>
                <div class="dv3">Test 1</div>
            </td>
        </tr>
        <tr>
            <td>
                <select id="hh" class="mySelect hidden">
                    <option>123</option>
                    <option>456</option>
                </select>
                <div class="dv4">Test 1</div>
            </td>
        </tr>
     </table>
     
     <hr>
     
    <table border="1" class="mySelectGroup">
        <tr>
            <td>
                <select id="ii" class="mySelect">
                    <option>123</option>
                    <option>456</option>
                </select>
                <div class="dv1">Test 1</div>
            </td>
        </tr>
        <tr>
            <td>
                <select id="jj" class="mySelect hidden">
                    <option>123</option>
                    <option>456</option>
                </select>
                <div class="dv2">Test 1</div>
            </td>
        </tr>
        <tr>
            <td>
                <select id="kk" class="mySelect hidden">
                    <option>123</option>
                    <option>456</option>
                </select>
                <div class="dv3">Test 1</div>
            </td>
        </tr>
        <tr>
            <td>
                <select id="ll" class="mySelect hidden">
                    <option>123</option>
                    <option>456</option>
                </select>
                <div class="dv4">Test 1</div>
            </td>
        </tr>
    </table>

    Secondly, we'll have to treat the way the event handling is done a bit differently.
    • We'll bind an event handler on the groups and watch for changes on the select.
    • Then, once a select has changed, we can find out what group it belongs to, and get all the selects in that group
    • From here, it's pretty much the same as before, find the index of the changed select and hide/show other selects in the group accordingly
    • Extra bonus: I've added in some extra code to cache the selects that belong to a group so that jQuery doesn't need to find those selects every time one changes. It does this by storing the selects that it found on the mySelectGroup that it belongs to.
    Code JavaScript:
    $(document).ready(function(){
     
        // We'll bind an event handler on the selects in each group
        // This uses jQuery 1.7's new .on() method
        $('.mySelectGroup').on("change", "select", function(e){
     
            var $group, $mySelects;
     
            //find our current group
            $group = $(this).closest(".mySelectGroup");
     
            //let's cache our set of selects at first use
            if ( typeof $group.data("mySelects") ===  'undefined' ){
     
                //find all the selects for the current group
                $mySelects = $group.find(".mySelect");
     
                //assign the selects to a data object stored on the group for later use
                $group.data("mySelects", $mySelects)
     
            }
            else {
                //we can use the cached data.
                $mySelects = $group.data("mySelects");
            }
     
            // find the index of the changed element
            idx = $mySelects.index(this);
     
            // now set the next select to visible
            $mySelects.eq(idx+1).removeClass("hidden");
     
            // make sure that all selects that come *after* the next element are hidden
            //
            // we're now using .slice() rather than :gt() as we're no longer selecting from a parent, 
            // but rather getting a "slice" of an array. This also means we're slicing the index + 2 
            // because the next element (from the index) needs to remain visible
            $mySelects.slice(idx+2).addClass("hidden");
        });
     
    });

    See:
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  10. #10
    SitePoint Guru phantom007's Avatar
    Join Date
    May 2008
    Posts
    752
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Many thanks sir.

    I will give this a try and shall come back to you if i face any problem.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •