Toggle opening all table rows with one click - javascript

I have created a basic table using HTML. This table has nested elements which are supposed to open individually when you click on each assigned toggle. So when you click on a '+' icon it opens the a sub menu which also has an icon 'pitch' that opens up what will be an information page when clicked on.
This works, however when i click on one of the '+' icons it opens both of the sub menus, likewise with the 'pitch' buttons, which obviously I dont want to happen, I want to be able to open and close these independently.
Can anyone please tell me how to amend the Javascript/HTML to make this happen?
I have attached the code below...
<table>
<tr>
<td></td>
<td>Column 1</td>
<td>Column 2</td>
<td>Column 3</td>
<td>Column 4</td>
<td>Column 4</td>
<td>Column 5</td>
<td>Column 6</td>
<td>Column 7</td>
</tr>
<tr>
<td>+ </td>
<td>Company</td>
<td>47</td>
<td>123</td>
<td>22/10</td>
<td>***</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="cat1" style="display:none">
<td>pitch </td>
<td>List</td>
<td>120</td>
<td>105</td>
<td>22/10</td>
<td>***</td>
<td>23/6/2015</td>
<td>14.95%</td>
<td>30%</td>
</tr>
<tr class="cat1" style="display:none">
<td>
<p>HELLO</p>
</td>
</tr>
<tr class="cat1" style="display:none">
<td>pitch </td>
<td>List</td>
<td>120</td>
<td>105</td>
<td>22/10</td>
<td>***</td>
<td>23/6/2015</td>
<td>14.95%</td>
<td>30%</td>
</tr>
<tr class="cat1" style="display:none">
<td>
<p>HELLO</p>
</td>
</tr>
<tr>
<td>+ </td>
<td>Company</td>
<td>48</td>
<td>156</td>
<td>22/10</td>
<td>***</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="cat1" style="display:none">
<td>pitch </td>
<td>List</td>
<td>156</td>
<td>256</td>
<td>22/10</td>
<td>***</td>
<td>23/6/2015</td>
<td>16.95%</td>
<td>30%</td>
</tr>
<tr class="cat1" style="display:none">
<td>
<p>HELLO</p>
</td>
</tr>
</table>
Also I have attached a JSFiddle so you can see what I mean
Any help would be greatly appreciated, I have been struggling with this issue for some time.

use can use .closest() and .next()
$(document).ready(function(){
$(".toggler").click(function(e){
e.preventDefault();
$(this).closest('tr').next('.cat'+$(this).attr('data-prod-cat')).toggle();
});
});
DEMO HERE

UPDATE:- I have discovered that this only works when each main table entry (+) only has one sub menu item (pitch). If it has more than 1, it will only display the first sub-menu item.
I should re-phrase my question.
I now want to reveal all sub-menus related to a particular group and then be able to open their details individually.
I have updated the main question so you can see what I mean

Related

Why doesn't my table row appear when the button is clicked? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last year.
Improve this question
Just trying to have a new drop down row to enter some data on a form. Should be simple, but the drop down shows in the first cell only, even when using colspan=5.
Or is there a better way? Thx for any help.
<table cellspacing=0 cellpadding=7 border=1>
<tr bgcolor=#efefef>
<td></td>
<td>Date</td>
<td>DATA</td>
<td>MORE DATA</td>
<td>Method</td>
</tr>
<tr>
<td>
<button onclick="javascript:showElement('abcdata')" style="padding:4px" class=verd8> SHOW NEW ROW </button>
</td>
<td>Jan 22, 2022</td>
<td>SOME DATA</td>
<td>SOME MORE</td>
<td>BUTTONDROP</td>
</tr>
<tr id="abcdata" style="display:none;">
<td colspan=5>
SHOW NEW ROW ACROSS ALL CELLS : sfdgsdfgs hlahhfa la dfl dfljhsd flhsd flhsdf lhdsfh asf alhd a</td>
</tr>
<tr>
<td colspan=5>
ADDED THIS tr/td IN EDIT : NOTHING HIDDEN.... DOES IT SHOW ALL ACROSS?? YES IT DOES
</td>
</tr>
</table>
Okay, I don't know where you got showElement from, but the simplest way to unhide your row is going to be abcdata.style.display=''
<button onclick="abcdata.style.display=''"
<table cellspacing=0 cellpadding=7 border=1>
<tr bgcolor=#efefef>
<td></td>
<td>Date</td>
<td>DATA</td>
<td>MORE DATA</td>
<td>Method</td>
</tr>
<tr>
<td>
<button onclick="abcdata.style.display=''" style="padding:4px" class=verd8> SHOW NEW ROW </button>
</td>
<td>Jan 22, 2022</td>
<td>SOME DATA</td>
<td>SOME MORE</td>
<td>BUTTONDROP</td>
</tr>
<tr id="abcdata" style="display:none;">
<td colspan=5>
SHOW NEW ROW ACROSS ALL CELLS : sfdgsdfgs hlahhfa la dfl dfljhsd flhsd flhsdf lhdsfh asf alhd a</td>
</tr>
</table>
function showElement(id) {
document.getElementById(id).classList.remove('hidden');
}
.hidden {
display: none;
}
<table cellspacing=0 cellpadding=7 border=1>
<tr bgcolor=#efefef>
<td></td>
<td>Date</td>
<td>DATA</td>
<td>MORE DATA</td>
<td>Method</td>
</tr>
<tr>
<td>
<button onclick="javascript:showElement('abcdata')" style="padding:4px" class=verd8> SHOW NEW ROW </button>
</td>
<td>Jan 22, 2022</td>
<td>SOME DATA</td>
<td>SOME MORE</td>
<td>BUTTONDROP</td>
</tr>
<tr id="abcdata" class="hidden" >
<td colspan=5>
SHOW NEW ROW ACROSS ALL CELLS : sfdgsdfgs hlahhfa la dfl dfljhsd flhsd flhsdf lhdsfh asf alhd a</td>
</tr>
</table>
I don't see your code but I guess you use display: block in order to display the td.
I suggest you to add css class that is called hidden.
Add it to the element you want to hide.
When you want to display the element, remove it.
P.S.
I don't suggest to change specific properties via JS (if it's not necessary).
You seem to be implying that showElement() is a native JavaScript function. It isn't. If we add the function your code works.
My guess is that you're accustomed to working on projects where some utility functions are provided by another script or library.
<script>
function showElement(id) {
document.getElementById(id).style.display = 'table-row';
// or just '' to make it more generic
}
</script>
<table cellspacing=0 cellpadding=7 border=1>
<tr bgcolor=#efefef>
<td></td>
<td>Date</td>
<td>DATA</td>
<td>MORE DATA</td>
<td>Method</td>
</tr>
<tr>
<td>
<button onclick="javascript:showElement('abcdata')" style="padding:4px" class=verd8> SHOW NEW ROW </button>
</td>
<td>Jan 22, 2022</td>
<td>SOME DATA</td>
<td>SOME MORE</td>
<td>BUTTONDROP</td>
</tr>
<tr id="abcdata" style="display:none;">
<td colspan=5>
SHOW NEW ROW ACROSS ALL CELLS : sfdgsdfgs hlahhfa la dfl dfljhsd flhsd flhsdf lhdsfh asf alhd a</td>
</tr>
</table>

How to set the index for a dynamically changing table?

I have created a form where you can add or delete table rows using javascript and jQuery. I would like to know how I can obtain and set the index for each table row such that sequence is maintained even if I were to delete and element from the middle of the table. The table is of the form:
<thead>
<tr>
<th>Index</th>
<th>Name</th>
<th>Property</th>
<th>Edit/Delete</th>
</tr>
</thead>
<tbody>
<tr>
<td class="index">Index goes here (1)</td>
<td>NameOne</td>
<td>PropOne</td>
<td><span class="edit">Edit Icon</span> <span class="delete">Delete Icon</span></td>
</tr>
<tr>
<td class="index">2</td>
<td>NameTwo</td>
<td>PropTwo</td>
<td><span class="edit">Edit Icon</span> <span class="delete">Delete Icon</span></td>
</tr>
<tr>
<td class="index">3</td>
<td>NameThree</td>
<td>PropThree</td>
<td><span class="edit">Edit Icon</span> <span class="delete">Delete Icon</span></td>
</tr>
</tbody>
Now what I want to achieve is if I were to delete the second row, the index of the previous third row should automatically change to 2 and if I were to add new element it should automatically take the index value of 3 and so on.
I tried to achieve this with:
function setIndex(){
$("td.index").each(function(index) {
$(this).text(++index);
});
}
But when I used the above function although the initial index when the elements were added printed properly the index wouldn't update properly when I called the function again after deleting or editing a row( I deleted the row using jQuery remove).
Also I am creating the new table rows with jQuery append().
I think that although I used remove() they don't get deleted completely as when I used a console.log("test") statement inside the setIndex() although "test" was only supposed to be printed twice(I had initially created 3 rows and deleted one of them) it go printed thrice signifying that there were 3 tr.index's.
Please help me solve the same.
You can use the CSS counter-reset and content properties.
The counter-reset property allows for automatic numbering of elements.
It works on any element.
The counter-reset property is used to reset a CSS counter to a given value.
It sets a named counter to a specific value.
body{
counter-reset: Serial; /* Set the Serial counter to 0 */
}
table{
border-collapse: collapse;
}
tr td:first-child:before{
counter-increment: Serial; /* Increment the Serial counter */
content:counter(Serial); /* Display the counter */
}
<table border="1">
<thead>
<tr>
<th>Automatic Serial number</th>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tr>
<td></td>
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tr>
<td></td>
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tr>
<td></td>
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tr>
<td></td>
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tr>
<td></td>
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tr>
<td></td>
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tr>
<td></td>
<td>Column 1</td>
<td>Column 2</td>
</tr>
</tbody>
</table>
I'd suggest using the the CSS/Counter answer by #pravin-prajapati because it requires no JS overhead and will scale easily.
Was interested in what the problem was with your code because it looked fine to me so rebuilt it. Seemed to be working fine.
I'm guessing the problem is actually in the way you're attaching code to the .delete click, especially if you're adding new rows or recreating rows after an edit.
If you add new rows after the initial document.ready (or window.onload...) has attached the callback to the existing .delete elements, it will not automatically attach the callback to the new .delete elements.
In other words, don't do this in your init:
$('.delete').on('click', function(){
// do stuff
});
because that will only work for .delete elements that exist during the init. There are a few ways around this but an easy way is to listen for click events on a parent of the rows and then filter them to your actual target before running the callback. jQuery's on method makes this easy.
Below is an example with the table as the event listener.
EDIT:
If, for some reason, this isn't possible, you might look into using jQuery.clone() and setting withDataAndEvents and/or deepWithDataAndEvents to true like $('tr.template').clone(true, true);. This will copy the <tr> and any event handlers attached to it (first 'true') and any event handlers attached to any of its child elements (second 'true'). jQuery Clone Docs
$(document).ready(function(){
// your function, copied 100%
function setIndex(){
$("td.index").each(function(index) {
$(this).text(++index);
});
}
// set the index to begin with. Note the last three
// row indexes are actually empty in the sample HTML
setIndex();
// Move the click listener to the table.
$('table').on('click', '.delete', function(){
// remove the tr...
$(this).parents('tr').remove();
//... and reset the index
setIndex();
})
});
table {
font-family: sans-serif;
margin: 10px;
}
table td {
border: 1px solid #ccc;
padding: 10px;
}
.delete {
color: red;
cursor: pointer;
font-size: 80%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Index</th>
<th>Name</th>
<th>Property</th>
<th>Edit/Delete</th>
</tr>
</thead>
<tbody>
<tr>
<td class="index">Index here</td>
<td>NameOne</td>
<td>PropOne</td>
<td><span class="edit">Edit</span> <span class="delete">Delete</span></td>
</tr>
<tr>
<td class="index">2</td>
<td>NameTwo</td>
<td>PropTwo</td>
<td><span class="edit">Edit</span> <span class="delete">Delete</span></td>
</tr>
<tr>
<td class="index">3</td>
<td>NameThree</td>
<td>PropThree</td>
<td><span class="edit">Edit</span> <span class="delete">Delete</span></td>
</tr>
<tr>
<td class="index"></td>
<td>Name 4</td>
<td>Prop 4</td>
<td><span class="edit">Edit</span> <span class="delete">Delete</span></td>
</tr>
<tr>
<td class="index"></td>
<td>Name 5</td>
<td>Prop 5</td>
<td><span class="edit">Edit</span> <span class="delete">Delete</span></td>
</tr>
<tr>
<td class="index"></td>
<td>Name 6</td>
<td>Prop 6</td>
<td><span class="edit">Edit</span> <span class="delete">Delete</span></td>
</tr>
</tbody>
</table>
EDIT
Praven Prajapati's answer surprised me.
I didn't know that very cool CSS feature.
Praven's answer really is better.
And if you need to refer to that number in a JS/jQuery code... And can't get it because it's a not in DOM pseudo-element... Then use .index() for that particular part of your code! Let CSS work on the rest.
jQuery way:
You need to refer to a row index... Use the .index() method.
Then on .delete click (I'm sure you can delete the row), just call a function to update the row index cell using that method.
Same after appending a new row...
Important
Use delegation with .on() on the classes present in your table rows, since you add new rows that are not present on page load code parsing. ;)
That is a Will's catch. (See his answer)
function updateRowCount(){
$("table tbody tr").each(function(){
$(this).find(".index").html($(this).index());
});
}
// Run on load
updateRowCount();
$(document).on("click",".delete",function(){ // Use delegation here!
$(this).parents("tr").remove();
updateRowCount();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Index</th>
<th>Name</th>
<th>Property</th>
<th>Edit/Delete</th>
</tr>
</thead>
<tbody>
<tr>
<td class="index"></td>
<td>NameOne</td>
<td>PropOne</td>
<td><span class="edit">Edit Icon</span> <span class="delete">Delete Icon</span></td>
</tr>
<tr>
<td class="index"></td>
<td>NameTwo</td>
<td>PropTwo</td>
<td><span class="edit">Edit Icon</span> <span class="delete">Delete Icon</span></td>
</tr>
<tr>
<td class="index"></td>
<td>NameThree</td>
<td>PropThree</td>
<td><span class="edit">Edit Icon</span> <span class="delete">Delete Icon</span></td>
</tr>
</tbody>
</table>

How to split one row into multiple row in html

I need to split one table row into multiple row when calling a js function
This is the table:
<table id="tab_calc">
<tr class="tr_calc">
<td>Sub Total</td>
<td>Tax</td>
<td>Freight</td>
<td>Insurance</td>
<td>Discount</td>
<td>Total</td>
<td>Amt Paid</td>
<td>Bal Due</td>
</tr>
I want to make it look like this after I call a function:
<table id="tab_calc">
<tr>
<td>Sub Total</td>
</tr>
<tr>
<td>Tax</td>
</tr>
<tr>
<td>Freight</td>
<td>Insurance</td>
<td>Discount</td>
</tr>
<tr>
<td>Total</td>
</tr>
<tr>
<td>Amt Paid</td>
</tr>
<tr>
<td>Bal Due</td>
</tr>
</table>
Try below code:
fiddler
$(document).ready(function(){
$('.tr_calc').replaceWith( $('.tr_calc').html()
.replace(/<td>/gi, "<tr> <td>")
.replace(/<\/td>/gi, "</td></tr>")
);
});

How to copy specific content from one table to another using Javascript

I am currently developing a tool to display large amount of data in different tables. Different amount of data from one table has to be assigned into another table more than once. This view takes almost 20 seconds to load and i want to lower the time by manipulating the DOM instead of assigning every match within PHP. I want to place a few identifiers hidden in the first table and on click of one row, show the additional data within the next element.
Here is an example how the Tables look before:
<table>
<tr>
<th>Name</th>
</tr>
<tr class="iWantToClickThis">
<td>Bla Bla</td>
<td style="visibility:hidden;">3,5</td>
</tr>
</table>
<table style="visibility:hidden">
<tr>
<th>Additional Header</th>
</tr>
<tr id="1">
<td>Additional Info 1</td>
</tr>
<tr id="2">
<td>Additional Info 2</td>
</tr>
<tr id="3=>
<td>Additional Info 3</td>
</tr>
<tr id="4">
<td>Additional Info 4</td>
</tr>
<tr id="5">
<td>Additional Info 5</td>
</tr>
<tr id="6">
<td>Additional Info 6</td>
</tr>
</table>
And after the click:
<table>
<tr>
<th>Name</th>
</tr>
<tr class="iWantToClickThis">
<td>Bla Bla</td>
<td style="visibility:hidden;">3,4,5</td>
</tr>
<tr>
<td colspan="2>
<table>
<tr>
<th>Additional Header</th>
</tr>
<tr id="3">
<td>Additional Info 3</td>
</tr>
<tr id="5">
<td>Additional Info 5</td>
</tr>
</table>
</td>
</table>
I've found out how to achieve this with a single row but how do i do that with different, identitying them by their ids?

jQuery next in <TR> tag not working when TR collapse

I have a table with many rows, but each row need a help row, so they come in pairs.
For example
<tbody>
<tr>
<td>Info 1</td>
<td>Info 2</td>
<td>Info 3</td>
<td>Info 4</td>
<td> <a>button more</a> </td>
</tr>
<!-- AND -->
<tr class="bottom-row">
<td colspan="2">Info 5</td>
<td colspan="2">Info 6</td>
<td>Info 7</td>
</tr>
<tr>
<td>OtherInfo 1</td>
<td>OtherInfo 2</td>
<td>OtherInfo 3</td>
<td>OtherInfo 4</td>
<td> <a>button more</a> </td>
</tr>
<!-- AND -->
<tr class="bottom-row">
<td colspan="2">OtherInfo 5</td>
<td colspan="2">OtherInfo 6</td>
<td>OtherInfo 7</td>
</tr>
I want to click the bottom row is displayed, and click again to hide
I try use toggle of jQuery UI
$(".btnMore").click(function(){
$(this).parent("td").parent("tr").next().toggle();
});
This working perfect when the bottom rows are visible, when i add style="display:none" stops working. Try also remove style="display:none" and add in load page $(".bottom-row").hide(); but does not work either
that I can do?
Try this:
$('table').on("click", ".btnMore", function() {
$(this).closest('tr').next().toggle();
});
http://jsfiddle.net/PnUns/
It seems to work fine when I try it, http://jsfiddle.net/LF7Ar/1/
// I added the hide from the beginning
$(".btnMore").click(function(){
$(this).parent("td").parent("tr").next().toggle();
});
$('.bottom-row').hide();

Categories