Link to home
Start Free TrialLog in
Avatar of Kratos101
Kratos101

asked on

Change Checkbox CSS Style

All,

I have the attached code snippet where a category checkbox is checked if all items underneath it are checked. How can I modify the code such that:

1. If any checkbox underneath any category is checked, the CSS Style of it's parent "Category" checkbox should look greyed out. (I do not want to disable the checkbox. Just look grey or any color through CSS). This will denote some items are checked if the category is collapsed.

2. If all items are checked underneath a category, then the checkbox doesn't have to look greyed out as it will be checked too.

All the existing code functionality should be maintained as it works great..

Any suggestions,
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();
  });
} 
function toggleCheckboxes(current, form, field) {
  $(document).ready(function() {
    $("#"+ form +" :checkbox[name^='"+ field +"[']")
      .attr("checked", current.checked);
  });
} 
function toggleParentCheckboxes(current, form) {        
  var checked = $("#"+ form +" :checkbox[name='"+ current.name +"']").length == 
                $("#"+ form +" :checkbox[name='"+ current.name +"']:checked").length;
  // 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

Avatar of hielo
hielo
Flag of Wallis and Futuna image

Noticed that I added tbody to group the sections of your table:
<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();
  });
} 
function toggleCheckboxes(current, form, field) {
  $(document).ready(function() {
    $("#"+ form +" :checkbox[name^='"+ field +"[']")
      .attr("checked", current.checked);
  });
} 

function toggleParentCheckboxes(current, form) {


  var checked = $("#"+ form +" :checkbox[name='"+ current.name +"']").length == 
                $("#"+ form +" :checkbox[name='"+ current.name +"']:checked").length;

if(checked)
{
	$( ":checkbox:eq(0)", $(current).closest("tbody")).css({"background-color":"gray"});
}
else
{
	$( ":checkbox:eq(0)", $(current).closest("tbody")).css({"background-color":"white"});
}

  // 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>
<tbody>
<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');"/>c</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>
</tbody>

<tbody>
<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');"/>c</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>
</tbody>
</table>
</form>
</body>
</html>

Open in new window

Avatar of Kratos101
Kratos101

ASKER

I think I understamd what you are doing, but it's not working...  I just want the checbox css changed... not tbody !

Thanks
I added the tbody because:
IMHO it makes the syntax simpler. I it bothers you that much, then try:
if(checked)
{
        //$( ":checkbox:eq(0)", $(current).closest("tbody")).css({"background-color":"gray"});
       $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").css({"background-color":"gray"});
}
else
{
        //$( ":checkbox:eq(0)", $(current).closest("tbody")).css({"background-color":"white"});
       $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").css({"background-color":"white"});
}

Open in new window

Hello Hielo !

Thanks for the answer.. It doesn't seem to be changing the CSS of the checkbox... Can you please try out the entire code in the browser and check?

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 checked = $("#"+ form +" :checkbox[name='"+ current.name +"']").length == 
                $("#"+ form +" :checkbox[name='"+ current.name +"']:checked").length;

	if(checked)
	{
	       $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").css({"background-color":"red"});
	}
	else
	{
	       $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").css({"background-color":"white"});
	}
  // 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

>>the CSS of the checkbox
What do you mean by that? You can change the background color on a TEXT box, but not on a checkbox. What you can do is change the background of the element on which the checkbox is located.

Other than that, after a closer look at your question, I see "..If any checkbox underneath any category is checked".
so change line 42:
if(checked)

to:
if( !checked )
Hi Hielo !

By CSS of the checkbox, I meant that:

1. When some items under a category are checked,  and if the category is collapsed, the user doesn't know if any items under the category are checked.  Hence, to provide a visual indication that some items are checked underneath a category, I am looking into modifying the style of the "Category" checkbox. This can be a "border:1px; background-color:red" or some thing like that.

Thanks.
I said:
change line 42:
if(checked)

to:
if( !checked )

did you?
yes I did.. Sorry to say, but still doesn't work.. If you have a screenshot of this stuff working on your end, please attach it..

Thanks !
ASKER CERTIFIED SOLUTION
Avatar of hielo
hielo
Flag of Wallis and Futuna image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you...This works great in Internet explorer and I will give you points for that..

 Is it possible to make it work for firefox ? Please... :)
Also, I noticed one bug.. After the page loads, in the second category, if you uncheck all the checkboxes, we still see the background-color as red.

Thanks
I'll look into this with FF. I need to leave for a few mins...
okay.. I fixed the bugs I found.. Following is the modified code..  All we need now is to make it to work in Firefox and other Mozilla based browsers..

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({"background-color":"red"});
	}
	else
	{
	       $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").css({"background-color":"white"});
	}
  // 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

do you have a link to your page? I don't have the arrow images so FF is not giving a "clickable" image/area.
I don't have a link to the page, but please find the attached images.

Thanks
arrow-collapsed.gif
arrow-expanded.gif
change:
if(numChecked !=0 && (totalCheckboxes!=numChecked))
	{
	       $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").css({"background-color":"red"});
	}
	else
	{
	       $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").css({"background-color":"white"});
	}

to:
    if(numChecked !=0 && (totalCheckboxes!=numChecked))
	{
	       $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").parent().css({"background-color":"red"});
	}
	else
	{
	       $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").parent().css({"background-color":"white"});
	}

Open in new window

hmm.. okay.. I changed the "Opacity" property and it looks okay.. That's the closest I could get for what I want... Thanks for the inputs...
if(numChecked !=0 && (totalCheckboxes!=numChecked))
    {
           $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").css({"opacity":"0.5"});             
    }
    else
    {
           $("#"+ form +" :checkbox[name='chk"+ current.name.match(/(\d+)/)[1] +"']").css({"opacity":"100"});           
    }

Open in new window

noticed that I used:
.parent().css({"background-color":"red"});

you need to apply the color to the TD, not to the INPUT, since the TD contains the INPUT.