1

I've got some trouble building a select all checkbox inside a table. Originally the table has several rows and the first checkbox should be used to select all options.

I built a small example, but still could not figure out my mistake.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "httpd://www.w3.org/TR/html4/loose.dtd">
<html><head>
<script language="JavaScript">
function allClicked(clickedId)
{
  var divId = "div-" + clickedId.substring(4);
  var child = document.getElementById( divId );
  var tdChildren = child.getElementsByTagName("td"); // appears to be empty
  var allCheckBox = document.getElementById( clickedId );
  var setTo = allCheckBox.checked ? true : false;
  for (var i=0; i<tdChildren.length; ++i) {
    tdChildren[i].elements.checked = setTo;
  }
}
</script>
</head><body>
<div id="div-a">
  <table>
    <tr>
      <td><input id="all-AP" onClick="javascript:allClicked('all-AP')" type="checkbox">Select All</td>
      <div id="div-AP">
      <td><input id="AP_A1K" checked="checked" type="checkbox"></td>
      <td><input id="AP_A2K" checked="checked" type="checkbox"></td>
      <td><input id="AP_A3K" type="checkbox"></td>
      </div>
    </tr>
  </table>
</div>
</body></html>

During debugging the div with id="all-AP" is retrieved but appears to be empty. I expected it to have three td-elements in it.

Is a div separating the td's valid? What should I fix?

Bodo
  • 172
  • 10
  • 5
    _"Is a div separating the td's valid? "_ No. You can always check this by running your code through a HTML validator. – j08691 Apr 14 '15 at 12:21
  • 1
    Give them a class & `getElementsByClassName()` – Alex K. Apr 14 '15 at 12:26
  • 1
    This might help you with [select all](http://stackoverflow.com/questions/386281/how-to-implement-select-all-check-box-in-html) checkbox – Greenhorn Apr 14 '15 at 12:28
  • user514 thanks for the link, there are some interesting examples. The example with the lists looks really good. But I still like to have the select all in a table. I'll try @Alex K. suggestion to use a class next. – Bodo Apr 14 '15 at 12:35
  • 1
    the IDs `div-a` and `div-A` are different – Fares M. Apr 14 '15 at 12:44
  • You mean div-a and div-AP? That is by intention - but you are right here it confuses. I should drop the div-a – Bodo Apr 14 '15 at 12:50
  • 1
    Ok, you have to change your `html` structure to get this script to work. – Fares M. Apr 14 '15 at 13:05

4 Answers4

1

No it isn't. You can either put another table inside the second cell or have some javascript to hide/display the other cells.

Rohit Gupta
  • 4,022
  • 20
  • 31
  • 41
1

You don't need a div either to perform a "select all".

Have a look on this fiddle.

First :

<body>
    <table id="checkboxtable">
        <tr>
            <td>
                <input onClick="javascript:allClicked()" type="checkbox" />Select All</td>
            <td>
                <input id="AP_A1K" checked="checked" type="checkbox" />
            </td>
            <td>
                <input id="AP_A2K" checked="checked" type="checkbox" />
            </td>
            <td>
                <input id="AP_A3K" type="checkbox" />
            </td>
        </tr>
    </table>
</body>

Each input has its own id (you CANNOT affect one id to more than one element).

Then allClicked() :

function allClicked() {
    var checkBoxTable = document.getElementById("checkboxtable");
    var checkBoxes = checkBoxTable.getElementsByTagName("input");
    for (var i = 0; i < checkBoxes.length; ++i) {
        // if (/^AP_.*/.test(checkBoxes[i].id)) // getting them by regular expression
        if (checkBoxes[i].getAttribute("type") == "checkbox") // getting them by type
            checkBoxes[i].checked = true;
    }
}

The code retrieve the table element by its id. Then it gets all its <input type="checkbox"> elements. Depending on your needs, you can also catch them by their id with a [Regexp][2].test() method (here it catches element whose id begins with "AP_").

This is just one example implementation. You can achieve it in many ways.

Amessihel
  • 5,891
  • 3
  • 16
  • 40
1

My final result and working example looks like this:

<!DOCTYPE HTML>
<html><head>
<meta charset="utf-8" />
<title>Testpage</title>
<script type="text/javascript">
function allClicked(clickedId)
{
  var divId = "div-" + clickedId.substring(4);
  var child = document.getElementById( divId );
  var children = child.getElementsByClassName("AP");
  var allCheckBox = document.getElementById( clickedId );
  var setTo = allCheckBox.checked ? true : false;
  for (var i=0; i<children.length; ++i) {
    children[i].checked = setTo;
  }
}
</script>
</head><body>
  <table>
    <tr id="div-AP">
      <td><input id="all-AP" onClick="javascript:allClicked('all-AP')" type="checkbox">Select All</td>
      <td><input class="AP" checked="checked" type="checkbox"></td>
      <td><input class="AP" checked="checked" type="checkbox"></td>
      <td><input class="AP" type="checkbox"></td>
    </tr>
  </table>
</body></html>

I used a validator to check the document. (http://validator.w3.org/check)

Using a class feature allows me to place the select all inside the same row.

Bodo
  • 172
  • 10
  • 1
    `allClicked()` in this case toggles checkboxes, doesn't check them all. Anyway if ids aren't necessary, you can indeed use a class. – Amessihel Apr 14 '15 at 13:04
1

The div doesn't work across table elements. Try this for your allClicked function instead:

function allClicked(clickedId)
{
  var prefix = clickedId.substring(4);
  var allCheckBox = document.getElementById( clickedId );
  var setTo = allCheckBox.checked ? true : false;
  var checkboxes = document.getElementsByTagName("input");
  for (var i=0; i<checkboxes.length; ++i) {
      var boxid = checkboxes[i].id;
      if (boxid.indexOf(prefix)===0) {
          checkboxes[i].checked = setTo;
      }
  }
}

This assumes your grouping of checkboxes have a common prefix. Just remove your div lines from the table entirely and rely on the id prefix of the input fields.

Always Learning
  • 5,510
  • 2
  • 17
  • 34