?
Solved

Expand All/ Collapse All

Posted on 2009-12-17
11
Medium Priority
?
645 Views
Last Modified: 2012-05-08
All,

I have the following code where categories expand and collapse upon click of the arrow images next to them. The arrow images also change, based on the status of the row. I want to implement a function so that:

1. On click of a link "Expand All/Collpase All", all categories should be expanded or collapsed. Please keep in mind that the respective arrow images also should change accordingly.

Thanks

<html>
<head>

<script src="http://www.google.com/jsapi"></script>

<script>
google.load("jquery", "1.3.2");
google.load("jqueryui", "1.7.2");
</script>

<script language="JavaScript">
function toggleTableRows()
{
  $(document).ready(function() {


    $('img.parent')
      .css("cursor","pointer")
      .toggle(
        function() {
          $(this).attr("title","Click to Expand")
          $(this).attr("src","arrow_collapsed.gif");
          $('tr').siblings('#child-'+this.id).toggle();
        },
        function() {
          $(this).attr("title","Click to Collapse");
          $(this).attr("src","arrow_expanded.gif");
          $('tr').siblings('#child-'+this.id).toggle();
        }
      ); 
    initCheckBoxes("frmDinnerMenu");


  });

} 
function toggleCheckboxes(current, form, field) {
  $(document).ready(function() {
    $("#"+ form +" :checkbox[name^='"+ field +"[']")
      .attr("checked", current.checked);
  });
} 
function toggleParentCheckboxes(current, form) {
  var totalCheckboxes = $("#"+ form +" :checkbox[name='"+ current.name +"']").length;
  var numChecked = $("#"+ form +" :checkbox[name='"+ current.name +"']:checked").length;
  var checked = (totalCheckboxes == numChecked );
    if(numChecked !=0 && (totalCheckboxes!=numChecked))
	{
	       $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").css({"opacity":"0.3"});
	}
	else
	{
	       $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").css({"opacity":"100"});
	}
  // replace '[anything]' with '' instead of just '[]'
  $("#"+ form +" :checkbox[name='"+ current.name.replace(/\[[^\]]*\]/, "") +"']")
    .attr("checked", checked);
} 
function initCheckBoxes(form) {
  $("#"+ form +" :checkbox:checked").each(function() {
    if (this.name.match(/chk[0-9]\[.*\]/)) {
      toggleParentCheckboxes(this, form);
    }
  });
}
</script>
<script language="JavaScript">toggleTableRows();</script>
<style type="text/css">tr.c1 {display: none;}</style>
</head>
<body>

<form name="frmDinnerMenu" id="frmDinnerMenu" method="POST" action="">
<table border=1>
<tr>
    <td><img class="parent" id="0" src="arrow_collapsed.gif" title="Click to Expand">Category - Fruits</td>
    <td><input type="checkbox" name="chk0" onclick="toggleCheckboxes(this, 'frmDinnerMenu', 'chk0');"/></td>
</tr>
<tr class="c1" id="child-0">
    <td>Apple</td>
    <td><input type="checkbox" value="true" name="chk0[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr class="c1" id="child-0">
    <td>Banana</td>
    <td><input type="checkbox" value="false" name="chk0[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr class="c1" id="child-0">
    <td>Orange</td>
    <td><input type="checkbox" checked value="true" name="chk0[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr>
    <td><img class="parent" id="1" src="arrow_collapsed.gif" title="Click to Expand">Category - Vegetables</td>
    <td><input type="checkbox" name="chk1" onclick="toggleCheckboxes(this, 'frmDinnerMenu', 'chk1');"/></td>
</tr>
<tr class="c1" id="child-1">
    <td>Eggplant</td>
    <td><input type="checkbox" value="true" name="chk1[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr class="c1" id="child-1">
    <td>Tomato</td>
    <td><input type="checkbox" value="false" name="chk1[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr class="c1" id="child-1">
    <td>Cabbage</td>
    <td><input type="checkbox" checked value="true" name="chk1[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
</table>
</form>
</body>
</html>

Open in new window

arrow-collapsed.gif
arrow-expanded.gif
0
Comment
Question by:Kratos101
  • 6
  • 4
11 Comments
 
LVL 29

Expert Comment

by:David H.H.Lee
ID: 26077643
Hi Kratos101,
Re-order your existing toggle code, that should solve the problem.
$('img.parent')
      .css("cursor","pointer")
      .toggle(
        function() {
          $(this).attr("title","Click to Collapse");
          $(this).attr("src","arrow_expanded.gif");
          $('tr').siblings('#child-'+this.id).toggle();
        },
        function() {
          $(this).attr("title","Click to Expand")
          $(this).attr("src","arrow_collapsed.gif");
          $('tr').siblings('#child-'+this.id).toggle();
        }
      ); 

Open in new window

0
 

Author Comment

by:Kratos101
ID: 26078002
Sorry.. it's not working that way...  Can you please check  the question again?
0
 
LVL 82

Expert Comment

by:hielo
ID: 26081746
you are developing "design habits" that will lead to headaches down the road, specifically:
>> <tr class="c1" id="child-0">
You have multiple elements with id="child-0". The same goes for id="child-1". You are only allowed to have UNIQUE ids per page. So you can only have ONE item with id="child-0". What you CAN have multiple times are classes. Furthermore you CAN have multiple classes per element. So instead of:
<tr class="c1" id="child-0">

use:
<tr class="c1 child-0">


The corrected code is below:

<html>
<head>

<script src="http://www.google.com/jsapi"></script>

<script>
google.load("jquery", "1.3.2");
google.load("jqueryui", "1.7.2");
</script>

<script language="JavaScript">
function toggleTableRows()
{
  $(document).ready(function() {


    $('img.parent')
      .css("cursor","pointer")
      .toggle(
        function() {
          $(this).attr("title","Click to Expand")
          $(this).attr("src","arrow_collapsed.gif");
          $('tr').siblings('.child-'+this.id).toggle();
        },
        function() {
          $(this).attr("title","Click to Collapse");
          $(this).attr("src","arrow_expanded.gif");
          $('tr').siblings('.child-'+this.id).toggle();
        }
      ); 
    initCheckBoxes("frmDinnerMenu");


  });

} 
function toggleCheckboxes(current, form, field) {
  $(document).ready(function() {
    $("#"+ form +" :checkbox[name^='"+ field +"[']")
      .attr("checked", current.checked);
  });
} 
function toggleParentCheckboxes(current, form) {
  var totalCheckboxes = $("#"+ form +" :checkbox[name='"+ current.name +"']").length;
  var numChecked = $("#"+ form +" :checkbox[name='"+ current.name +"']:checked").length;
  var checked = (totalCheckboxes == numChecked );
    if(numChecked !=0 && (totalCheckboxes!=numChecked))
        {
               $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").parent().css({"opacity":"0.3","background-color":"#aeaeae"});
        }
        else
        {
               $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").parent().css({"opacity":"100","background-color":"#fff"});
        }
  // replace '[anything]' with '' instead of just '[]'
  $("#"+ form +" :checkbox[name='"+ current.name.replace(/\[[^\]]*\]/, "") +"']")
    .attr("checked", checked);
} 
function initCheckBoxes(form) {
  $("#"+ form +" :checkbox:checked").each(function() {
    if (this.name.match(/chk[0-9]\[.*\]/)) {
      toggleParentCheckboxes(this, form);
    }
  });
}
$(document).ready(
	function(){
		$("#toggler").bind("click",function(){
			if(this.innerHTML.indexOf("Expand")!=-1)
			{
				$("img.parent").each(function( index, item){
					item.src="arrow_expanded.gif";
					$("tr.child-"+item.id).show();
				});
				this.innerHTML="Collapse All";
			}
			else
			{
				$("img.parent").each(function( index, item){
					item.src="arrow_collapsed.gif";
					$("tr.child-"+item.id).hide();
				});
				this.innerHTML="Expand All";
			}
		});
	}
);
</script>
<script language="JavaScript">toggleTableRows();</script>
<style type="text/css">tr.c1 {display: none;}</style>
</head>
<body>
<a href="#" id="toggler">Expand All</a>
<form name="frmDinnerMenu" id="frmDinnerMenu" method="POST" action="">
<table border=1>
<tr>
    <td><img class="parent" id="0" src="arrow_collapsed.gif" title="Click to Expand">Category - Fruits</td>
    <td><input type="checkbox" name="chk0" onclick="toggleCheckboxes(this, 'frmDinnerMenu', 'chk0');"/></td>
</tr>
<tr class="c1 child-0">
    <td>Apple</td>
    <td><input type="checkbox" value="true" name="chk0[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr class="c1 child-0">
    <td>Banana</td>
    <td><input type="checkbox" value="false" name="chk0[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr class="c1 child-0">
    <td>Orange</td>
    <td><input type="checkbox" checked value="true" name="chk0[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr>
    <td><img class="parent" id="1" src="arrow_collapsed.gif" title="Click to Expand">Category - Vegetables</td>
    <td><input type="checkbox" name="chk1" onclick="toggleCheckboxes(this, 'frmDinnerMenu', 'chk1');"/></td>
</tr>
<tr class="c1 child-1">
    <td>Eggplant</td>
    <td><input type="checkbox" value="true" name="chk1[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr class="c1 child-1">
    <td>Tomato</td>
    <td><input type="checkbox" value="false" name="chk1[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr class="c1 child-1">
    <td>Cabbage</td>
    <td><input type="checkbox" checked value="true" name="chk1[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
</table>
</form>
</body>
</html>

Open in new window

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:Kratos101
ID: 26081989
Thanks Hielo for pointing that out ! The fact is in my original code, I don't use "class="c1" at all.. I have to display alternate row colors and hence had to use something like <tr style="display:none" class="alt" id="child-0"> for even rows and <tr style="display:none" id="child-1"> for odd rows.

I can move style="display:none" to a new css class. I am not sure if this is the best way to do it, but I am using it like this as I know we cannot have two css class attributes for a single element.

Please let me know if I can fix issues like this in a good design manner.

Thanks
0
 
LVL 82

Expert Comment

by:hielo
ID: 26082038
>>as I know we cannot have two css class attributes for a single element.
This you CANNOT do:
<td class="c1" class="child-0">...</td>

This you CAN do:
<td class="c1 child-0">...</td>

Noticed that this is what I did on the last segment of code I posted. I also changed the part where you are adding the opacity. Not sure if you missed my last comment on yesterday's problem. To add the color, you need to add it to the TD not to the INPUT itself. Again, notice that all you need to do is add precede the .css(...) with .parent()
0
 

Author Comment

by:Kratos101
ID: 26082270
Thanks for the comments..
I noticed your comments on opacity in your previous post.. I will take that path...
0
 
LVL 82

Expert Comment

by:hielo
ID: 26082429
the code above should be fully functional since I also changed:
$('tr').siblings('#child-'+this.id).toggle();

to:
$('tr').siblings('.child-'+this.id).toggle();

(notice how the # was changed to a dot) since I changed your code to:
<tr class="c1 child-0">

Regards,
Hielo
0
 

Author Comment

by:Kratos101
ID: 26082721
I noticed one bug in the above code...  Follow these steps to replicate:

1. When the page loads, click "Expand All"..
2. Click "Collapse All".
3. Expand one of the categories by clicking on the arrow next to it.

Notice that the category expands, but the arrow image doesn't change to the expanded image.

How can we fix this?
0
 
LVL 82

Accepted Solution

by:
hielo earned 2000 total points
ID: 26083238
.
<html>
<head>

<script src="http://www.google.com/jsapi"></script>

<script>
google.load("jquery", "1.3.2");
google.load("jqueryui", "1.7.2");
</script>

<script language="JavaScript">
function toggleTableRows()
{
  $(document).ready(function() {


    $('img.parent')
      .css("cursor","pointer")
      .toggle(
        function() {
	   	if($(this).attr("src").indexOf("expanded")!=-1)
		{
          	$(this).attr("title","Click to Expand")
          	$(this).attr("src","arrow_collapsed.gif");
          	$('tr').siblings('.child-'+this.id).toggle();
		}
		else
		{
	          $(this).attr("title","Click to Collapse");
     	     $(this).attr("src","arrow_expanded.gif");
          	$('tr').siblings('.child-'+this.id).toggle();
		
		}
        },
        function() {
	   	if($(this).attr("src").indexOf("collapsed")!=-1)
		{
          	$(this).attr("title","Click to Collapse");
          	$(this).attr("src","arrow_expanded.gif");
          	$('tr').siblings('.child-'+this.id).toggle();
		}
		else
		{
          	$(this).attr("title","Click to Expand")
          	$(this).attr("src","arrow_collapsed.gif");
          	$('tr').siblings('.child-'+this.id).toggle();
		}
        }
      ); 
    initCheckBoxes("frmDinnerMenu");


  });

} 
function toggleCheckboxes(current, form, field) {
  $(document).ready(function() {
    $("#"+ form +" :checkbox[name^='"+ field +"[']")
      .attr("checked", current.checked);
  });
} 
function toggleParentCheckboxes(current, form) {
  var totalCheckboxes = $("#"+ form +" :checkbox[name='"+ current.name +"']").length;
  var numChecked = $("#"+ form +" :checkbox[name='"+ current.name +"']:checked").length;
  var checked = (totalCheckboxes == numChecked );
    if(numChecked !=0 && (totalCheckboxes!=numChecked))
        {
               $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").parent().css({"opacity":"0.3","background-color":"#aeaeae"});
        }
        else
        {
               $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").parent().css({"opacity":"100","background-color":"#fff"});
        }
  // replace '[anything]' with '' instead of just '[]'
  $("#"+ form +" :checkbox[name='"+ current.name.replace(/\[[^\]]*\]/, "") +"']")
    .attr("checked", checked);
} 
function initCheckBoxes(form) {
  $("#"+ form +" :checkbox:checked").each(function() {
    if (this.name.match(/chk[0-9]\[.*\]/)) {
      toggleParentCheckboxes(this, form);
    }
  });
}
$(document).ready(
	function(){
		$("#toggler").bind("click",function(){
			if(this.innerHTML.indexOf("Expand")!=-1)
			{
				$("img.parent").each(function( index, item){
					item.src="arrow_expanded.gif";
					$("tr.child-"+item.id).show();
				});
				this.innerHTML="Collapse All";
			}
			else
			{
				$("img.parent").each(function( index, item){
					item.src="arrow_collapsed.gif";
					$("tr.child-"+item.id).hide();
				});
				this.innerHTML="Expand All";
			}
		});
	}
);
</script>
<script language="JavaScript">toggleTableRows();</script>
<style type="text/css">tr.c1 {display: none;}</style>
</head>
<body>
<a href="#" id="toggler">Expand All</a>
<form name="frmDinnerMenu" id="frmDinnerMenu" method="POST" action="">
<table border=1>
<tr>
    <td><img class="parent" id="0" src="arrow_collapsed.gif" title="Click to Expand">Category - Fruits</td>
    <td><input type="checkbox" name="chk0" onclick="toggleCheckboxes(this, 'frmDinnerMenu', 'chk0');"/></td>
</tr>
<tr class="c1 child-0">
    <td>Apple</td>
    <td><input type="checkbox" value="true" name="chk0[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr class="c1 child-0">
    <td>Banana</td>
    <td><input type="checkbox" value="false" name="chk0[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr class="c1 child-0">
    <td>Orange</td>
    <td><input type="checkbox" checked value="true" name="chk0[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr>
    <td><img class="parent" id="1" src="arrow_collapsed.gif" title="Click to Expand">Category - Vegetables</td>
    <td><input type="checkbox" name="chk1" onclick="toggleCheckboxes(this, 'frmDinnerMenu', 'chk1');"/></td>
</tr>
<tr class="c1 child-1">
    <td>Eggplant</td>
    <td><input type="checkbox" value="true" name="chk1[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr class="c1 child-1">
    <td>Tomato</td>
    <td><input type="checkbox" value="false" name="chk1[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
<tr class="c1 child-1">
    <td>Cabbage</td>
    <td><input type="checkbox" checked value="true" name="chk1[]" onclick="toggleParentCheckboxes(this, 'frmDinnerMenu');"/></td>
</tr>
</table>
</form>
</body>
</html>

Open in new window

0
 

Author Comment

by:Kratos101
ID: 26083364
Perfect.. Thanks a bunch for the great work !! I am new to Jquery and am learning as much as possible... Thanks for all the help.. :)
0
 

Author Closing Comment

by:Kratos101
ID: 31667606
Great work Hielo ! This should be useful to many people !
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

CSS is a visual language used to classify objects and define rules about how they should be displayed. CSS skills aren’t restricted to developers anymore, there is a big benefit to having a basic understanding of the language, regardless of your occ…
Why do we like using grid based layouts in website design? Let's look at the live examples of websites and compare them to grid based WordPress themes.
In this tutorial viewers will learn how to position overlapping items using z-index in CSS. They will also learn the restrictions on the z-index property.  Create a new HTML document with an internal stylesheet.: Create a div in CSS and name it Red.…
In this tutorial viewers will learn how to style a corner ribbon overlay for an image using CSS Create a new class by typing ".Ribbon":  Define the class' "display:" as "inline-block": Define its "position:" as "relative": Define its "overflow:" as …
Suggested Courses

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question