How can I toggle multiple rows in a table if the <td>
class is set to an specific class. For instance toggle all rows if they contain the class="foo"
.
<table id="bar">
<tr>
<td>hello</td>
<td class="foo">there</td>
<td class="foo">bye</td>
</tr>
</table>
How can I toggle multiple rows in a table if the <td>
class is set to an specific class. For instance toggle all rows if they contain the class="foo"
.
<table id="bar">
<tr>
<td>hello</td>
<td class="foo">there</td>
<td class="foo">bye</td>
</tr>
</table>
Share
Improve this question
edited Jan 4, 2011 at 15:05
Phrogz
304k113 gold badges667 silver badges758 bronze badges
asked Jan 4, 2011 at 14:25
delimiter01delimiter01
111 silver badge3 bronze badges
6
- 1 What do you mean by "toggle"? Change the visibility of the entire row, to either show or hide them all at the same time? – Phrogz Commented Jan 4, 2011 at 14:27
- @Phrogz: yes, show/hide. – delimiter01 Commented Jan 4, 2011 at 14:31
- 1 Forgot to mention, no framework, pure JS – delimiter01 Commented Jan 4, 2011 at 14:37
-
1
I echo the suggestion by @Hogsmill: you should consider using jQuery. More than half the JS in my suggestion is just to implement a not-as-flexible-as-jQuery selector function. (Although it could be shorter if you know your browser base will have
querySelectorAll
.) If you use CDN hosted jQuery your customers may even have it in their caches already, so it's 'free'. – Phrogz Commented Jan 4, 2011 at 14:48 - 100% agree that you should be using a framework for this sort of thing, otherwise it's all too easy to stumble over browser inpatibilities. – MarkXA Commented Jan 4, 2011 at 14:53
6 Answers
Reset to default 2Here's a non-jQuery solution, written just for you: http://phrogz/tmp/toggling_rows_with_class.html
Here's the relevant JS:
window.onload = function() {
var visible = true;
document.getElementById('toggle').onclick = function() {
visible = !visible;
var tds = findElementsWithClass('td', 'foo');
for (var i=0, len=tds.length; i<len; ++i) {
tds[i].parentNode.style.display = visible ? '' : 'none';
}
};
}
function findElementsWithClass(tagName, className) {
if (document.querySelectorAll) {
return document.querySelectorAll(tagName + "." + className);
} else {
var results = [];
var all = document.getElementsByTagName(tagName);
var regex = new Regexp("(?:^|\\s)" + tagName + "(?:\\s|$)");
for (var i=0, len=all.length; i<len; ++i) {
if (regex.test(all[i].className)) {
results.push(all[i]);
}
}
return results;
}
}
Modify the class
Why is everyone using selectors? There is already a class attached to all the appropriate elements, so why not just modify the class?
This function will find the class of a given name, and set an attribute for that class. Be careful if you have multiple classes with coincident names in different stylesheets, because the function isn't!
function changeStyle(stylename,attribute,newvalue) {
var cssRules = 'rules';
if(document.styleSheets[0].cssRules) {
cssRules = 'cssRules';
}
for(var sheetId=0; sheetId<document.styleSheets.length; sheetId++) {
var sheet = document.styleSheets[sheetId];
for(var ruleId=0; ruleId<sheet[cssRules].length; ruleId++) {
var rule = sheet[cssRules][ruleId];
if(rule.selectorText == "."+stylename) {
rule.style.setProperty(attribute,newvalue,"");
}
}
}
return false;
}
Now, just call
changeStyle('foo','display','none');
and the cells should disappear, then with 'block'
to get them back (IE can't do the more recent display styles like ). I suspect that in a table you'll want to hide entire rows rather than just cells, but you can also make them disappear by setting visibility
to hidden
- they will still take up space, but not draw.
See, no jquery, no homemade element selectors. Just a slightly annoying bit of javascript to loop through the stylesheets and their rules...
td = document.getElementsByTagName('td');
for (var i = 0; i < td.length; i++) {
if (td[i].className === 'foo')
if (!td[i].style.display)
td[i].style.display = 'none';
else
td[i].style.display = '';
}
}
http://jsfiddle/qwertymk/cyZn9/2/
Something like this should do it:
var trs = document.getElementsByTagName("tr");
for (var i in trs) {
var tr = trs[i];
if (tr.getElementsByClassName("foo").length > 0)
tr.style.display = (tr.style.display == "none" ? "block" : "none");
}
This will toggle the display on any TR that contains a child with class="foo".
Something like this?
$("table td.specific_class").toggle();
Edit
/* Go through the table rows */
var trs = document.getElementsByTagName("tr");
for (var i = 0; i < trs.length; i++ ) {
var myClass, tds, line_done = false;
/* Go through the table cells */
tds = trs[i].getElementsByTagName("td");
for ( var k = 0; k < tds.length; k++ ){
/* Check each class of each cell */
myClasses = tds[k].className.split(' ');
for ( var j = 0; j < myClasses.length; j++ ){
/* If the class corresponds we toggle the row and break until the next row */
if ( myClasses[j].className == "foo" ){
trs[i].style.display = trs[i].style.display == "none" ? "block" : "none";
line_done = 1;
break;
}
}
if ( line_done ){
break;
}
}
}
try this one
<html>
<head>
<title>test</title>
<script type="text/javascript">
var toggle = function (action) {
var trs = document.getElementById('bar').getElementsByTagName('tr'),
trs_count = trs.length,
needed = [],
total = 0,
pattern = /\bfoo\b/g,
initial= 'show';
for (i=0; i<trs_count; i++) {
var tds = trs[i].getElementsByTagName('td'),
tds_count = tds.length;
for (j=0; j<tds_count; j++) {
if (pattern.exec(tds[j].className)) {
needed.push(tds[j]);
total++;
}
}
}
toggle = function (action) {
if (this.display == null) {
this.display = initial;
}
if (action == null) {
this.display = (this.display == 'hide') ? 'show' : 'hide';
}
else {
this.display = action;
}
for (i=0; i<total; i++) {
if (this.display == 'show') {
needed[i].style.display = 'block';
}
else {
needed[i].style.display = 'none';
}
}
return true;
}
return toggle();
}
</script>
</head>
<body>
<table id="bar">
<tr><th>Header</th></tr>
<tr><td class="foo">1 Data foo</td></tr>
<tr><td>2 Data</td></tr>
<tr><td class="foo">3 Data foo</td></tr>
<tr><td>4 Data</td></tr>
</table>
<button type="button" onclick="toggle()">toggle</button>
</body>
</html>