Expand All/ Collapse All

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
Kratos101Asked:
Who is Participating?
 
hieloCommented:
.
<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
 
David H.H.LeeCommented:
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
 
Kratos101Author Commented:
Sorry.. it's not working that way...  Can you please check  the question again?
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
hieloCommented:
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
 
Kratos101Author Commented:
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
 
hieloCommented:
>>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
 
Kratos101Author Commented:
Thanks for the comments..
I noticed your comments on opacity in your previous post.. I will take that path...
0
 
hieloCommented:
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
 
Kratos101Author Commented:
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
 
Kratos101Author Commented:
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
 
Kratos101Author Commented:
Great work Hielo ! This should be useful to many people !
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.