I have a table with this markup:
<table>
<tr class="odd"><td>Product 1</td></tr>
<tr class="even"><td>Product 2</td></tr>
<tr class="odd"><td>Product 3</td></tr>
<tr class="even"><td>Product 4</td></tr>
</table>
Every table row is a product and some products have more information. So in this case a table looks like this:
<table>
<tr class="odd"><td>Product 1</td></tr>
<tr class="even"><td>Product 2</td></tr>
<tr class="even"><td>Information 1</td></tr>
<tr class="even"><td>Information 2</td></tr>
<tr class="odd"><td>Product 3</td></tr>
<tr class="even"><td>Product 4</td></tr>
</table>
I wan't to hide the rows with the product information, and show it after a click on the product row.
I tried this with the following Javascript function and onlick="":
function showHide(id) {
var el = document.getElementById(id);
if( el && el.style.visibility == 'hidden')
el.style.visibility = 'visible';
else
el.style.visibility = 'hidden';
}
But the problem is I don't know how to target only the information rows of the product I've clicked on. It would be easy if I could change the markup, but this markup is generated, so I only can solve it with Javascript.
Is ist possible to solve this problem? I have created a fiddle, so it's easier to deliver a quick solution:
/
I have a table with this markup:
<table>
<tr class="odd"><td>Product 1</td></tr>
<tr class="even"><td>Product 2</td></tr>
<tr class="odd"><td>Product 3</td></tr>
<tr class="even"><td>Product 4</td></tr>
</table>
Every table row is a product and some products have more information. So in this case a table looks like this:
<table>
<tr class="odd"><td>Product 1</td></tr>
<tr class="even"><td>Product 2</td></tr>
<tr class="even"><td>Information 1</td></tr>
<tr class="even"><td>Information 2</td></tr>
<tr class="odd"><td>Product 3</td></tr>
<tr class="even"><td>Product 4</td></tr>
</table>
I wan't to hide the rows with the product information, and show it after a click on the product row.
I tried this with the following Javascript function and onlick="":
function showHide(id) {
var el = document.getElementById(id);
if( el && el.style.visibility == 'hidden')
el.style.visibility = 'visible';
else
el.style.visibility = 'hidden';
}
But the problem is I don't know how to target only the information rows of the product I've clicked on. It would be easy if I could change the markup, but this markup is generated, so I only can solve it with Javascript.
Is ist possible to solve this problem? I have created a fiddle, so it's easier to deliver a quick solution:
http://jsfiddle/emjay__/8B3M4/
Share Improve this question asked Dec 4, 2013 at 14:12 emjayemjay 1,5115 gold badges19 silver badges36 bronze badges 3-
1
you are using class and selecting id,
class="even"
,document.getElementById(id)
– Jonathan de M. Commented Dec 4, 2013 at 14:16 - make it simple (i say not use table for design), make another level to this sub menu (another table/element), so the main menu don't stay a mess with the submenus – korogui Commented Dec 4, 2013 at 14:34
- here is a simple example: jsfiddle/9tQUu/4 – korogui Commented Dec 4, 2013 at 14:58
4 Answers
Reset to default 4Hi for this i propose you a solution with Jquery : http://jsfiddle/8B3M4/9/
First hide all your elements with just CSS : matching all elements preceeded by the same class name.
tr.even + .even { display:none; } tr.odd + .odd { display:none; }
Second this function wich show / hide the elements:
$(document).ready(function () { $('tr.even').click(function (){ $(this).nextUntil('.odd').toggle(); }) })
A pure JS method:
http://jsfiddle/8B3M4/13/
var current_class = 'odd';
var current_index = 0;
var pairs = [];
// Loop through each td
var table = document.getElementsByTagName('table')[0];
for (var i = 0; i < table.rows.length; i++) {
var row = table.rows[i];
// Pair the products with their information based on the class
if (row.getAttribute('class') !== current_class) {
current_index++;
current_class = row.getAttribute('class');
}
// Set up the pairing
if (pairs[current_index] === undefined) {
// A new pair in sights
pairs[current_index] = {
'product': row.cells[0],
'info': []
}
row.cells[0].onclick = function(ci) {
return function() {
for (var j = 0; j < pairs[ci].info.length; j++) {
var cell = pairs[ci].info[j];
if (cell.style.display == 'none') {
cell.style.display = '';
}
else {
cell.style.display = 'none';
}
}
}
}(current_index);
}
else {
// Add more info to the object
pairs[current_index].info.push(row.cells[0]);
console.log(row.cells[0].style.display);
row.cells[0].style.display = 'none';
}
}
At first, you are using class and selecting ID.
On the second hand, I would use display property.
if( el && el.style.visibility == 'hidden')
el.style.display = 'block';
else
el.style.display = 'none';
On the third invisible hand, you still have "a lot" of work to do to get it running.
This is working (s. http://jsfiddle/S7gTA/3/)
var lastClass = 0;
var lastIndex = 0;
$('tr').each(function(index, element){ // get each tr on the page, change the selector to #%TABLEID% > tr if this should work only for a specific table
if($(this).attr("class") != lastClass) // class change from odd to even or even to odd?
{
lastClass = $(this).attr("class"); // set current "mother" class
lastIndex = index; // store the index of the "mother"
$(this).addClass("mother").attr("rel", index) // now the mother is able to hide or show all the element with the class info-for-%index% *1
}
else
{
$(this).addClass("info-for-"+lastIndex).hide();
}
});
$( '.mother' ).bind("click", function(){ $('.info-for-'+$(this).attr("rel")).toggle(); });