Get Parent Row from Child in datatables - javascript

From within a row in a child of a row in datatables, how do I find access the parent row in datatables. Basically, I would like to highlight the parent row when its child row after expansion is clicked.
I gave all parentRows a class name, and when a button in the child row is clicked, I did this:
var tr = $(this).prev('.parentRow');
tr.addClass('rowIsDirty');
<tr class="vcenter parentRow">
<td class="hidden">#element.ElementName</td>
<td class="details-control meter"></td>
<td>#element.ElementTemplateName</td>
<td>#element.ElementName</td>
<td>#element.MeterTemplateName</td>
<td>#element.MeterName</td>
</tr>
<td class="details-control">#element.CaseDataPairs</td>
<td class="text-left"><b>#item.ProductName</b></td>
<td class="text-left">#item.ProductGroupName</td>
<td class="text-center">#item.VersionsCount</td>
<td class="text-center">
<i class="fa fa-pencil-square-o"></i>
</td>
<td class="text-center">
<input checked="#item.IsActive" data-toggle="toggle" class="toggleCheckBox ActivateProductButton" data-style="ios" data-on="Active" data-off="InActive" type="checkbox" id="EditAccountIsActive" data-product-id="#item.ProductId">
</td>
$(document).on('change', '.ActivateProductButton, function() {
UpdateStatus($(this));
});
function UpdateStatus(thisObj) {
var tr = thisObj.closest('.parentRow');
tr.removeClass('highlightExpanded');
tr.addClass('rowIsDirty');
}
It's not giving me the parentRow to highlight. Any ideas?

I tried to create a simplified version of a table and added an event to when a button is clicked...
Hopefully you will be able to modify this code to suit your needs.
The code selects the closest node with class .parentRow and, since the nested row is added as a sibling row, we select the previous row (.prev()) to mark as dirty (or highlight or whatever)
Let me know if you have any questions about the code.
function UpdateStatus(thisObj) {
var tr = thisObj.closest('.parentRow').prev();
$(tr).removeClass('highlightExpanded');
$(tr).addClass('rowIsDirty');
}
$(document).ready(function() {
$('.UnitStatusButton').on('click', function() {
UpdateStatus($(this));
});
});
.highlightExpanded {
background-color: lightblue;
}
.rowIsDirty {
background-color: royalblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border="1">
<tr role="row" class="even shown">
<td class=" details-control">iconhere</td>
<td class="sorting_1">Brielle Williamson</td>
<td>Integration Specialist</td>
<td>New York</td>
<td>$372,000</td>
</tr>
<tr class="parentRow highlightExpanded">
<td colspan="5">
<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">
<tbody>
<tr>
<td>Full name:</td>
<td>Brielle Williamson</td>
</tr>
<tr>
<td>Extension number:</td>
<td>4804</td>
</tr>
<tr>
<td>Extra info:</td>
<td>And any further details here (images etc)...</td>
</tr>
<tr>
<td>Edit</td>
<td>
<button class="UnitStatusButton">Click Me</button>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr role="row" class="even shown">
<td class=" details-control">iconhere2</td>
<td class="sorting_1">Jane Williamson</td>
<td>No Specialist</td>
<td>New York</td>
<td>$2,000</td>
</tr>
</table>

Related

Javascript store table in a variable with conditions

This is how my page looks like:
<div class="bgSmTitle smTitle">Customer Addresses</div>
<table class="bgLtTable">
<tr>
<td class="bgLtRow1 padded">New York</td>
</tr>
<tr>
<td class="bgLtRow1 padded">Osaka</td>
</tr>
<tr>
<td class="bgLtRow1 padded">Los Angeles</td>
</tr>
</table>
<div class="bgSmTitle smTitle">Family Members</div>
<table class="bgLtTable">
<tr>
<td class="bgHeader1 padded" style="width:24%;">Name</td>
<td class="bgHeader2 padded" style="width:10%;">Relationship</td>
<td class="bgHeader1 padded" style="width:30%;">Age</td>
</tr>
<tr>
<td class="bgLtRow1 padded">Jordan</td>
<td class="bgLtRow2 padded">Father</td>
<td class="bgLtRow1 padded">58</td>
</tr>
</table>
I would like to store the tables with class name bgLtTable. These table can appear up to 3-4 times in this page. Is it possible to get the specific table using the div above it? Something like:
var tableAddress = div.innerHtml="Customer Addresses".table.bgLtTable;
var tableMembers = div.innerHtml="Family Members".table.bgLtTable;
Maybe try to use document.getElementsByTagName("TABLE");
This will give you an object that is accessible via index
You can then assign those elements to a variable and loop through it but look where the class attribute is equal to className for example
var element = document.getElementsByTagName("TABLE");
for (var i = 0; element.length > i; i++)
{
var elementClass = element[i].getAttribute('class');
}
I am not 100% sure this answers your question how I understand is you just want to get the class.
I hope this helps I am also pretty new to coding but always willing to help if I can.
var CustomerAddressesTable = $('div.smTitle:contains("Customer Addresses")').next('.bgLtTable');
console.log($("<div />").append($(CustomerAddressesTable).clone()).html());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr class="prnt">
<td>
<div class="bgSmTitle smTitle">Customer Addresses</div>
<table class="bgLtTable">
<tr>
<td class="bgLtRow1 padded">New York</td>
</tr>
<tr>
<td class="bgLtRow1 padded">Osaka</td>
</tr>
<tr>
<td class="bgLtRow1 padded">Los Angeles</td>
</tr>
</table>
</td>
</tr>
<tr class="prnt">
<td colspan="3">
<div class="bgSmTitle smTitle">Family Members</div>
<table class="bgLtTable">
<tr>
<td class="bgHeader1 padded" style="width:24%;">Name</td>
<td class="bgHeader2 padded" style="width:10%;">Relationship</td>
<td class="bgHeader1 padded" style="width:30%;">Age</td>
</tr>
<tr>
<td class="bgLtRow1 padded">Jordan</td>
<td class="bgLtRow2 padded">Father</td>
<td class="bgLtRow1 padded">58</td>
</tr>
</table>
</td>
</tr>
</table>
This method will give you the html of the required table.

Replace duplicate value in each column as as null

I have a html table similar to this
I want to replace all the duplicate values in first TWO columns to be replaced with a null i.e an output similar to this
Added the html code below for reference
table, th, td {
border: 1px solid black;
}
table {
border-collapse: collapse;
}
<table >
<thead>
<tr >
<th>ABBEY </th>
<th>ANX </th>
<th>TPIN</th>
<th>ACP</th>
<th>4</th>
<th>3</th>
</tr>
</thead>
<tbody>
<tr>
<td>ABNAMRO </td>
<td>ANW </td>
<td>TPIN</td>
<td>ACP</td>
<td>32</td>
<td>32</td>
</tr>
<tr>
<td>ABNAMROLLC</td>
<td>MLD </td>
<td>TPIN</td>
<td>ACP</td>
<td>10</td>
<td>10</td>
</tr>
<tr>
<td>AMHERSTP </td>
<td>QPE</td>
<td>GRAM</td>
<td>ACP</td>
<td>341</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>GRAM</td>
<td>RJT</td>
<td>56</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td>QPE </td>
<td>TPIN</td>
<td>ACP</td>
<td>24</td>
<td>19</td>
</tr>
<tr>
<td> </td>
<td>QPP</td>
<td>GRAM</td>
<td>ACP</td>
<td>353</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>GRAM</td>
<td>RJT</td>
<td>2</td>
<td> </td>
</tr>
<tr>
<td>BAKERGRP </td>
<td>JBC</td>
<td>GRAM</td>
<td>ACP</td>
<td>337</td>
<td>142</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>GRAM</td>
<td>RJT</td>
<td>3</td>
<td></td>
</tr>
</tbody>
</table>
Fiddle
Perhaps a little something like the following.
The columnsToProcess object should specify true for the zero-based column indices of the columns to process. For your stated requirement to do the first two columns only I could've just used a selector of "td:lt(2)" instead, but using an object to specify which columns to process is more versatile, in case, e.g., you later wanted to process the first, fourth, and sixth columns:
columnsToProcess = { 0: true, 3: true, 5: true }
The lastVals object keeps track of the last changed value for each column. There's no need to initialise its elements at all because when we test lastVals[i] it will just return undefined if not yet initialised, and undefined is not equal to any string.
var columnsToProcess = {
0: true,
1: true
};
var lastVals = {};
$("table tbody tr").each(function() { // for each row
$(this).find("td").each(function(i) { // for each cell in the current row
if (!columnsToProcess[i]) return; // do we care about this column?
if (this.innerHTML === lastVals[i]) // if value is same as the previous row
this.innerHTML = " "; // blank out the cell
else // otherwise
lastVals[i] = this.innerHTML; // remember the current value
});
});
table, th, td { border: 1px solid black; }
table { border-collapse: collapse; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<thead>
<tr><th>ABBEY</th><th>ANX</th><th>TPIN</th><th>ACP</th><th>4</th><th>3</th></tr>
</thead>
<tbody>
<tr><td>ABNAMRO</td><td>ANW</td><td>TPIN</td><td>ACP</td><td>32</td><td>32</td></tr>
<tr><td>ABNAMROLLC</td><td>MLD</td><td>TPIN</td><td>ACP</td><td>10</td><td>10</td></tr>
<tr><td>AMHERSTP</td><td>QPE</td><td>GRAM</td><td>ACP</td><td>341</td><td> </td></tr>
<tr><td>AMHERSTP</td><td>QPE</td><td>GRAM</td><td>RJT</td><td>56</td><td> </td></tr>
<tr><td>AMHERSTP</td><td>QPE</td><td>TPIN</td><td>ACP</td><td>24</td><td>19</td></tr>
<tr><td>AMHERSTP</td><td>QPP</td><td>GRAM</td><td>ACP</td><td>353</td><td> </td></tr>
<tr><td>AMHERSTP</td><td>QPP</td><td>GRAM</td><td>RJT</td><td>2</td><td> </td></tr>
<tr><td>BAKERGRP</td><td>JBC</td><td>GRAM</td><td>ACP</td><td>337</td><td>142</td></tr>
<tr><td>BAKERGRP</td><td>JBC</td><td>GRAM</td><td>RJT</td><td>3</td><td></td></tr>
</tbody>
</table>
Left as an exercise for the reader: trimming whitespace before comparing the values, if "AMHERSTP" and "AMHERSTP " are supposed to be considered equal.

Convert table to html and group in to divs

update: almost done! problem is that the productrow im trying to grouop gets divided into two groups: https://jsfiddle.net/g3zrh5y5/1/
I have a HTML table that I would like to convert and group to divs. I have dont his succesfully with tableanarchy.js (http://codepen.io/KurtWM/pen/AJpEw) on another table on my site, but on this table the setup is a bit different and I cant make it to work.
I need to remove the divider table row, and group the rest in divs as the example shows. Any idea how I do this?
<tbody>
<tr>
<td class="unfoldedlabel" colspan="6"><a href="javascript://" name=
"_ec_pd6_cc/cL" id="_ec_pd6_cc/cL" onclick=
"if( UI.pb_boolean(this, 'click') ) {} return false;">Backup/datalagring/Raid
Controllers</a></td>
</tr>
//group this ---->
<tr>
<td rowspan="2"><a href=
"">
<img src="/imgs" alt="" /></a></td>
<td colspan="3"><a href=
"">
HP Flash Backed Write Cache - RAID controller cache memory (1GB)</a></td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>534562-B21</td>
<td>HP</td>
<td>0</td>
<td>4 127,97SEK</td>
<td><input type="button" id="rpb13804" class="actionbutton" value="KÖP NU"
onclick="buy(this, 13804, null, null,null, '/ajax/buy')" /></td>
</tr>
//end group ---->
//remove this ---->
<tr>
<td class="divider" colspan="6"></td>
</tr>
//end remove ---->
//group this ---->
<tr>
<td rowspan="2"><a href=
"">
<img src="/imgs/9248a5f8-1a45-40c1-b254-52ab24881150/40/40" alt="" /></a></td>
<td colspan="3"><a href=
"">
HP Flash Backed Write Cache - RAID controller cache memory (512MB) - for ProLiant
BL460c G7, BL620C G7, BL680c G7, DL165 G7, DL360 G7, DL370 G6, DL980 G7, ML110
G7</a></td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>534916-B21</td>
<td>HP</td>
<td>0</td>
<td>3 260,99SEK</td>
<td><input type="button" id="rpb28314" class="actionbutton" value="KÖP NU"
onclick="buy(this, 28314, null, null,null, '/ajax/buy')" /></td>
</tr>
//end group ---->
</tbody>
Just iterate the table rows and exclude the rows you don't need. Here is a working fiddle
$(document).ready(function(){
$('.group-btn').click(function(){
// Lets create the main div
var div = $('<div />', {id: '#myDiv', class: 'new-div'});
// Let's start iterating the body rows
$('.myTable tbody tr').each(function(index, row) {
// Exclude divider rows
if(!$(row).hasClass('divider')) {
// Let's iterate the columns of the row
$(row).find('td').each(function(index, column){
// This is a simple example that extract the column text that's why i create a simple <p> tag
// Let's exclude tds that have "exclude" class
if(!$(column).hasClass('exclude')) {
var paragraph = $(column).html();
$(div).append(paragraph).append('<br/>');
}
});
}
});
// And finally we append the div to the "append-here" div
$('.append-here').append(div)
});
});
table {
border: 1px solid black
}
table tr td{
border: 1px solid black
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button type="button" class="group-btn">Click me!</button>
<table class="myTable">
<thead>
<tr>
<th>col 1-1</th>
<th>col 2-1</th>
<th>col 3-1</th>
</tr>
</thead>
<tbody>
<tr>
<td>Val 1-2</td>
<td class="exclude">Val 2-2</td>
<td>Val 3-2</td>
</tr>
<tr>
<td>Val 1-3</td>
<td>Val 2-3</td>
<td class="exclude">Val 3-3</td>
</tr>
<tr class="divider">
<td colspan="3">DIVIDER</td>
</tr>
<tr>
<td>Val 1-5</td>
<td>Val 2-5</td>
<td>Val 3-5</td>
</tr>
</tbody>
</table>
<div class="append-here">
<p>Here is where you append the divs</p>
</div>
I've made a little change: the "divider" class is in the tr and not in the td
* UPDATE *
I've added this line of code
if(!$(column).hasClass('exclude')) {
var paragraph = $(column).html();
$(div).append(paragraph).append('<br/>');
}
That permits you to check whatever class you need to check in order to include/exclude tds elements

Using JQuery to select all <tr> elements with a specific class

The basic structure is a table with a few rows. I would like the top half of the table showing and the bottom half collapsed until a user clicks on the READ MORE cell. I have that functionality working but I can't get the JQuery right that selects all of the ".collapseThis" rows and hides them on page load.
Here is the table
<div id="tables">
<table class="expandableTable">
<tr>
<td></td>
<td></td>
</tr>
<tr class="accordion">
<td colspan="2">READ MORE</td>
</tr>
<tr class="collapseThis">
<td></td>
<td></td>
</tr>
</table>
<table class="expandableTable">
<tr>
<td></td>
<td></td>
</tr>
<tr class="accordion">
<td colspan="2">READ MORE</td>
</tr>
<tr class="collapseThis">
<td></td>
<td></td>
</tr>
</table>
</div>
Here is the JQuery.
$(document).ready(function () {
function getCollapsable($row) {
var children = [];
while ($row.next().hasClass('collapseThis')) {
children.push($row.next());
$row = $row.next();
}
return children;
}
function hideTableRows($row) {
children = getCollapsable($row);
$.each(children, function () {
$(this).toggle();
});
}
$('#tables').each($('expandableTable'), function () {
hideTableRows($(this).children().hasClass('.accordion'));
});
You can just use css to set the display value, there is no need to use jQuery to set the initial state.
If you want to use jQuery, use a simple selector like $('#tables .expandableTable .collapseThis').hide().
$(document).ready(function() {
//if you don't want to use css
//$('#tables .expandableTable .collapseThis').hide();
});
#tables .expandableTable .collapseThis {
display: none;
}
<div id="tables">
<table class="expandableTable">
<tr>
<td>1.1</td>
<td>1.2</td>
</tr>
<tr class="accordion">
<td colspan="2">READ MORE</td>
</tr>
<tr class="collapseThis">
<td>2.1</td>
<td>2.2</td>
</tr>
</table>
<table class="expandableTable">
<tr>
<td>1.1</td>
<td>1.2</td>
</tr>
<tr class="accordion">
<td colspan="2">READ MORE</td>
</tr>
<tr class="collapseThis">
<td>2.1</td>
<td>2.2</td>
</tr>
</table>
<table class="expandableTable">
<tr>
<td>1.1</td>
<td>1.2</td>
</tr>
<tr class="accordion">
<td colspan="2">READ MORE</td>
</tr>
<tr class="collapseThis">
<td>2.1</td>
<td>2.2</td>
</tr>
</table>
</div>

jquery toggle <td> on click of a button

I have a table that has a few items inside, and a button for each that will display more information on the specific item on the menu.
my HTML table is below
<table id="menu_breads">
<thead>
<tr>
<th colspan="2">BREADS</th>
</tr>
<tr>
<th>ITEM</th>
<th>PRICE</th>
</tr>
</thead>
<tbody>
<tr>
<td>Portugese Rolls
<button class="myButton">&#x2C5</button>
</td>
<td>R1.49</td>
</tr>
<tr>
<td colspan="2" class="more">A hand made selection of Portugese rolls</td>
</tr>
<tr>
<td>Hotdog Buns
<button class="myButton">&#x2C5</button>
</td>
<td>R0.99</td>
<tr>
<td colspan="2" class="more">A hand made selection of Hotdog buns</td>
</tr>
</tr>
<tr>
<td>French Loaf
<button class="myButton">&#x2C5</button>
</td>
<td>R3.49</td>
<tr>
<td colspan="2" class="more">A hand made selection of French loaves</td>
</tr>
</tr>
<tr>
<td>Sead Roll
<button class="myButton">&#x2C5</button>
</td>
<td>R2.49</td>
<tr>
<td colspan="2" class="more">A hand made selection of Seed Rolls</td>
</tr>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">
<h6>Prices may change without prior warning</h6>
</td>
</tr>
</tfoot>
</table>
<!-- TABLE FOR CONFECTIONARIES -->
<table id="menu_confect">
<thead>
<tr>
<th colspan="2">CONFECTIONARIES</th>
</tr>
<tr>
<th>ITEM (per slice)</th>
<th>PRICE</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cream Slice
<button class="myButton">&#x2C5</button>
</td>
<td>R12.49</td>
<tr>
<td colspan="2" class="more">A hand made selection of Cream slices</td>
</tr>
</tr>
<tr>
<td>Chocolate Cake
<button class="myButton">&#x2C5</button>
</td>
<td>R15.99</td>
<tr>
<td colspan="2" class="more">A hand made selection of Chocolate cakes</td>
</tr>
</tr>
<tr>
<td>Coconut Eclaire
<button class="myButton">&#x2C5</button>
</td>
<td>R2.49</td>
<tr>
<td colspan="2" class="more">A hand made selection of Coconut Eclairs</td>
</tr>
</tr>
<tr>
<td>Chocolate Eclaire
<button class="myButton">&#x2C5</button>
</td>
<td>R4.49</td>
<tr>
<td colspan="2" class="more">A hand made selection of chocolate Eclairs</td>
</tr>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">
<h6>Prices may change without prior warning</h6>
</td>
</tr>
</tfoot>
</table>
My CSS is here
.myButton {
background: #183C4C;
border-radius: 31%;
border:2px solid #4e6096;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-family:Arial;
font-size:11px;
text-decoration:none;
width: 15%;
float: right;
}
.more {
display: none;
}
Demo
and the jquery is what I am having a bit of a problem understanding. Would I need to ID every td that I want to display or can I do it with classes and an on click toggle event?
I have managed to get it to display on click, the problem is that all the hidden rows display and not just the individual one.
$(document).ready(function(){
$('.myButton').click(function(){
$(this).closest('tr').next().find('.more').toggle();
if ($(this).closest('tr').is(":visible")) {
$(this).html("&#x2C4")
}
else {
$(this).html("&#x2C5")
}
});
});
You wouldn't have to give IDs to every td, that'd be overkill. You want something dynamic. Assuming that your HTML structure will stay the same, you can do:
EDIT: Added the ability to toggle plus and minus icons from comments
$(".myButton").on("click", function () {
var more = $(this).closest("tr").next("tr").find(".more");
more.toggle();
if (more.is(":visible")) {
//show minus icon, hide plus
}
else {
//show plus icon, hide minus
}
});
DEMO (thanks Rory)
The more should be given to the tr - also your markup is not valid(you have a tr as child of tr - the more tr is child of the button tr)
<tr>
<td>Portugese Rolls
<button class="myButton">&#x2C5</button>
</td>
<td>R1.49</td>
</tr>
<tr class="more">
<td colspan="2">A hand made selection of Portugese rolls</td>
</tr>
then
$('.myButton').click(function(){
$(this).closest('tr').next().toggle();
})
Demo: Fiddle
If you don't want to change anything
$('.myButton').click(function(){
$(this).closest('tr').next().find('.more').toggle();
})
Demo: Fiddle
Have you tried this:
$(".myButton").on("click",function() {
$(this).closest("tr").toggle();
})

Categories