jQuery - Remove and group from HTML table - javascript

i have a dynamic table like this:
<table cellspacing="0" cellpadding="0">
<col width="80" span="3">
<tr id="id-1">
<th colspan="3" width="240">TITLE-1</th>
</tr>
<tr>
<td>val-1</td>
<td>val-2</td>
<td>val-3</td>
</tr>
<tr id="id-1">
<th colspan="3">TITLE-1</th>
</tr>
<tr>
<td>val-2</td>
<td>val-2</td>
<td>val-3</td>
</tr>
<tr id="id-2">
<th colspan="3">TITLE-2</th>
</tr>
<tr>
<td>val-1</td>
<td>val-2</td>
<td>val-2</td>
</tr>
</table>
In this table is 3 TR element with same ID. i want to remove all TR except first TR.
If not is duplicate IDs nothing change with this TR.
And i need also: in TR's is 3 td's. result must be next. if value is same group this td's:
<tr>
<td>val-2</td>
<td>val-2</td>
<td>val-3</td>
</tr>
result
<tr>
<td colspan="2">val-2</td>
<td>val-3</td>
</tr>
tnx

i changed id > class
$(".idxx:gt(0)").remove();

I did a function to parse tr's and td's. See here http://jsfiddle.net/mig1098/qo4xvqjm/ :
var mapTable={
_tr:function(){
var tabletr = $('table tr');
var compareid = '';
tabletr.each(function(){
var id = $(this).attr('id');
if(typeof id != 'undefined'){
if(compareid == ''){
compareid = id;
}else if(compareid == id){
$('#'+id).next().remove();
$('#'+id).remove();
}
}
});
},
_td:function(){
tabletr = $('table tr');
tabletr.each(function(){
var tdtext = {"obj":"","txt":"","count":1};
console.log($(this).find('th').text());
$(this).find('td').each(function(){
var td = $(this);
if(tdtext.txt == ''){
tdtext.txt = td.text();
tdtext.obj = td;
}else if(tdtext.txt == td.text()){
tdtext.count +=1;
td.hide();
td.addClass('todelete');
}else{
//before to change
tdtext.obj.attr('colspan',tdtext.count);
//
tdtext = {"obj":td,"txt":td.text(),"count":1};
}
});
if(tdtext.count > 1){
tdtext.obj.attr('colspan',tdtext.count);
}
$('.todelete').remove();
});
},
init(){
mapTable._tr();
mapTable._td();
}
}

Related

Hide table if its <td> is empty (Using only JS)

I want to hide a table if its "td" empty.
I'm trying to use this function, but it's not working:
function isEmptyTable(){
var tdTable = document.getElementsByName('tdTable').textContent;
var table = document.getElementsByName('tableToday');
if(tdTable == "")
table.style.display = 'none';
}
Any tips?
HTML:
<body onload="isEmptyTable()">
<table name="tableToday">
<thead>
<tr>
<th>Prêmio</th>
<th>Resultado</th>
<th>Grupo</th>
</tr>
</thead>
<tbody>
<tr>
<th>1º</th>
<td name="tdTable">oi</td>
<td name="tdTable"></td>
</tr>
</tbody>
</table>
I'd use the getElementById and the getElementsByClassName selectors to achieve this:
function isEmptyTable(myId){
let tds = document.getElementsByClassName(myId);
let hide = false
for (let element of tds) {
if (element.innerHTML.length == 0) hide = true
}
let myTable = document.getElementById(myId);
if (hide) myTable.style.display = 'none';
}
isEmptyTable("myTable")
isEmptyTable("myTable2")
td {
border: 1px solid red;
}
<table id="myTable">
<tr>
<td class="myTable"></td>
<td class="myTable">
lololo
</td>
</tr>
</table>
<table id="myTable2">
<tr>
<td class="myTable2">asdasd</td>
<td class="myTable2">
lololo
</td>
</tr>
</table>
in your code just change these two lines. because the td will return in collection so use array index [0]
function isEmptyTable(){
var tdTable = document.getElementsByName('tdTable')[0].textContent;
var table = document.getElementsByName('tableToday')[0];
if(tdTable == "")
table.style.display = 'none';
}
it will work fine.
The problem is in the part:
var tdTable = document.getElementsByName('tdTable').textContent;
and
table.style.display = 'none';
Because the function document.getElementsByName() doesn't return a simple variable , it's return an array , so to solve the problem you have to change the part:
var tdTable = document.getElementsByName('tdTable').textContent;
to
var tdTable = document.getElementsByName('tdTable')[0].textContent;
and change table.style.display = 'none'; to table[0].style.display = 'none';
For more information about document.getElementsByName() Click here

Get clicked column index from row click

I have a row click event. Recently had to add a checkbox to each row. How can I identify the clicked cell on row click event?
Or prevent row click when clicked on the checkbox.
Attempts: this.parentNode.cellIndex is undefined on the row click event.
function pop(row){
alert(row.cells[1].innerText);
}
<table style="width:100%">
<tr>
<th>Select</th>
<th>Site</th>
</tr>
<tr onclick="pop(this);">
<td><input type="checkbox" id="123456" /></td>
<td>Lonodn</td>
</tr>
</table>
Do you want something like this? You can just check the type attribute of the source element of the event and validate whether to allow it or not, you can stop the event using e.stopPropagation();return;.
function pop(e, row) {
console.log(e.srcElement.type);
if(e.srcElement.type === 'checkbox'){
e.stopPropagation();
return;
}else{
console.log(row);
alert(row.cells[1].innerText);
}
}
<table style="width:100%">
<tr>
<th>Select</th>
<th>Site</th>
</tr>
<tr onclick="pop(event, this);">
<td><input type="checkbox" id="123456" /></td>
<td>Lonodn</td>
</tr>
</table>
You should pass in the event details to your function and check the target property:
function pop(e){
// If the target is not a checkbox...
if(!e.target.matches("input[type='checkbox']")) {
alert(e.target.cellIndex);
}
}
<table style="width:100%">
<tr>
<th>Select</th>
<th>Site</th>
</tr>
<tr onclick="pop(event)">
<td><input type="checkbox" id="123456" /></td>
<td>Lonodn</td>
</tr>
</table>
Note: If you have nested elements inside the <td>, you might want to check e.target.closest("td") instead.
Note 2: You might need a polyfill for the matches method depending on which browsers you're supporting.
Here is an example if you don't want to attach a listener on every row :
document.getElementById("majorCities").addEventListener("click", function(e){
if(e.target.type === 'checkbox'){
var checked = e.target.checked;
var tr = e.target.parentElement.parentElement;
var city = tr.cells[1].innerHTML;
console.log(city+":checked="+checked);
}
});
<table id="majorCities" style="width:100%">
<tr>
<th>Select</th>
<th>Site</th>
</tr>
<tr>
<td><input type="checkbox"/></td>
<td>London</td>
</tr>
<tr>
<td><input type="checkbox"/></td>
<td>Paris</td>
</tr>
<tr>
<td><input type="checkbox"/></td>
<td>New-York</td>
</tr>
</table>
window.pop = function(row){
console.log('here');
var parent = row.parentNode;
Array.from(row.parentNode.querySelectorAll('tr')).forEach(function(tr, index){
if (tr === row) {
alert(index)
}
})
}
https://jsfiddle.net/sz42oyvm/
Here is for the pleasure, another example with an object containing the cities' names and a method to draw the table with ids corresponding to the name of the clicked city, so getting the clicked name is easier.
(function () {
var mySpace = window || {};
mySpace.cities = {};
mySpace.cities.pointer = document.getElementById("majorCities");
mySpace.cities.names = ["Select","City"];
mySpace.cities.data = [{"name":"Paris"},{"name":"New Delhi"},{"name":"Washington"},{"name":"Bangkok"},{"name":"Sydney"}];
mySpace.cities.draw = function(){
this.pointer.innerHTML="";
var html = "";
html+="<tr>"
for(var i=0;i < this.names.length;i++){
html+="<th>"+this.names[i];
html+="</th>"
}
html+="</tr>"
for(var i=0;i < this.data.length;i++){
html+="<tr>"
html+="<td><input id='"+this.data[i].name+"' type='checkbox'/></td>"
html+="<td>"+this.data[i].name+"</td>"
html+="</tr>"
}
this.pointer.innerHTML=html;
}
mySpace.cities.draw();
mySpace.cities.pointer.addEventListener("click", function(e){
if(e.target.type === 'checkbox'){
var checked = e.target.checked;
var city = e.target.id;
console.log(city+":checked="+checked);
}
});
})();
table {width:25%;background:#ccc;border:1px solid black;text-align:left;}
td,tr {background:white;}
th:first-of-type{width:20%;}
<table id="majorCities">
</table>

How can I uncheck the checked row of a table only if the column value matches

Actually I am looking to uncheck the checked row of a table only if the column value of the row matches to my value(value that i am passing). When I check the row from table 1 it binds into table 2.
So with the below script, when I delete a row from the "table 2", I am fetching the column (item code) value of row to be deleted from "table 2" and pass it to another table "table1". Now I want to compare the selected rows column value of "table1". If the column (Item code) value of table 1 matches to "item code" that I am passing, I want to uncheck the row.
But with the below code when I try to delete a row from table 2. it unchecked all the selected rows from table 1. So how can I modify my script to uncheck only only row (matched value row)?
Any help appreciated.
HTML Table
Table 1
<table id="order-table" name="order-table">
<tr>
<th>Select</th>
<th>Medication</th>
<th>Max Issue Limit</th>
<th>Quantity</th>
<th>X</th>
<th>Unit Price</th>
<th>=</th>
<th>Totals</th>
<th>Item Code</th>
</tr>
<tbody id="contacts">
<tr class='odd'>
<td><input type='checkbox' class='single-checkbox' checked></td>
<td class='product-title'>itemName</td>
<td>5</td>
<td class='qty'>2 </td>
<td class='times'>X</td>
<td class='rate'>10.00</td>
<td class='equals'>=</td>
<td class='date-total'>20</td>
<td class='med'>1</td>
</tr>
<tr class='odd'>
<td><input type='checkbox' class='single-checkbox'></td>
<td class='product-title'>itemName</td>
<td>5</td>
<td class='qty'>2 </td>
<td class='times'>X</td>
<td class='rate'>10.00</td>
<td class='equals'>=</td>
<td class='date-total'>20</td>
<td class='med'>2</td>
</tr>
</tbody>
</table>
Table 2
<table id='peopleTable' class='table table-bordered table-condensed table-striped'>
<thead>
<tr><th style='width:475px;'>Item Name</th>
<th>Actual Amount</th>
<th>Bill Amount</th>
<th>Item Code</th>
<th></th>
</tr></thead>
<tbody style='height:135px;overflow:auto'>
<tr>
<td class='name'>Item Name</td>
<td class='price'>25.00</td>
<td>24.00</td>
<td class='midlist'>1</td>
<td>
<button type='button' onclick='deletePerson(this);' class='btn btn-default'> <span class='glyphicon glyphicon-remove' /></button>
</td>
</tr>
</tbody>
</table>
Here is my script
function deletePerson(ctl) {
$(ctl).parents("tr").remove();
var sum = 0.00;
$('.price').each(function () {
sum += parseFloat($(this).text());
});
if (sum > 0.00) {
var elem = document.getElementById("grandtotal"); // Get text field
elem.value = sum;
var eleminfo = document.getElementById("ActualAmount"); // Get text field
eleminfo.value = sum;
var elemen = document.getElementById("grandtotalclaim"); // Get text field
elemen.value = sum;
var elemenfees = document.getElementById("ClaimAmount"); // Get text field
elemenfees.value = sum;
}
else {
sum = 0.00
var elem = document.getElementById("grandtotal"); // Get text field
elem.value = sum;
var eleminfo = document.getElementById("ActualAmount"); // Get text field
eleminfo.value = sum;
var elemen = document.getElementById("grandtotalclaim"); // Get text field
elemen.value = sum;
var elemenfees = document.getElementById("ClaimAmount"); // Get text field
elemenfees.value = sum;
}
var value1= $(ctl).parents("tr").find('.midlist').text();
var tableControl = document.getElementById('order-table');
var count = document.querySelectorAll('input[type="checkbox"]:checked', tableControl).length;
$('input:checkbox:checked', tableControl).each(function () {
$(this).closest('tr').find('.med').each(function () {
var te = $(this).text();
if (te == value1) {
alert("matched");
$(this).find('input[type=checkbox]').attr('checked', true);
}
else
{
alert("Not Matched");
}
})
});
}

Jquery parse HTML Table

I have the following table:
<table id="tableData" name="tableData">
<tr>
<td class="tdvalue"><a class="XXX">10</a></td>
<td class="tdvalue"><a class="YYY">4</a></td>
<td class="tdvalue"><a class="XXX">7</a></td>
</tr>
</table>
I need to get the td value which has hyperlink with class name in an array
The following code is not working
var rows = [];
$("#tableData tr").each(function() {
$tr = $(this);
var row = [];
$tr.find(".tdvalue").each(function(){
row.push($(this).text());
});
});
This gives the value of the text with in the td.
but I need to class name of XXX <a class="XXX">10</a>
result would be:
Array[3] 0:"XXX" 1:"YYY" 2:"XXX"
Please help anyone
target the a's directly:
var row = [];
$(".tdvalue a").each(function() {
row.push($(this).attr('class'));
});
//gives row= ["XXX","YYY","XXX"]
var row = [];
$(".tdvalue a").each(function() {
row.push($(this).attr('class'));
});
console.log(row)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tableData" name="tableData">
<tr>
<td class="tdvalue"><a class="XXX">10</a></td>
<td class="tdvalue"><a class="YYY">4</a></td>
<td class="tdvalue"><a class="XXX">7</a></td>
</tr>
</table>

Th doesn't sort Tbody on some modified column

I have multiple tbody in a table which some of span columns and rows. And then I got a jQuery code to sort this tbody based on the th.data- click.
In the first th column when it is clicked it will sort correctly. However, in the second th column when it is clicked it does not sort the tbody.
Here is the snippet :
var table = $('table'),
th = table.find('thead th'),
tbody = table.find('tbody');
$(th).on('click', function() {
$(th).removeClass();
var index = this.cellIndex,
sortType = $(this).data('sort'),
sortDir = $(this).data('dir') || 'asc';
var that = $(this);
$('table').find('tbody').slice().sort(function(a, b) {
var dataTH = that.data('class');
//alert(dataTH);
if(dataTH == 'number')
{
//alert("hi this is a number");
var aText = $(a).find('td.sortNum:eq(' + index + ')').text(),
bText = $(b).find('td.sortNum:eq(' + index + ')').text();
}
else if(dataTH == 'department')
{
//alert("hi this is a department");
var aText = $(a).find('td.depart:eq(' + index + ')').text(),
bText = $(b).find('td.depart:eq(' + index + ')').text();
}
if (sortDir == 'desc') {
temp = aText;
aText = bText;
bText = temp;
}
if (sortType == 'string') {
return aText.localeCompare(bText);
}
else {
return +aText - +bText;
}
})
.appendTo('table');
$(this).data('dir', sortDir == 'asc' ? 'desc' : 'asc');
$(this).removeClass().addClass('sort-' + sortDir);
});
table {
border-collapse: collapse;
width: 400px;
}
th, td {
padding: 5px;
border: 1px #DDD solid;
}
.sort-asc:after,
.sort-desc:after {
content: '▲';
font-size: 12px;
}
.sort-desc:after {
content: '▼';
}
<table>
<thead>
<tr>
<th data-sort="number" data-class="number" >No</th>
<th data-sort="number" data-class="department" >Department</th>
<th data-sort="number">Quantity</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2" class="sortNum">1</td>
<td class="depart">20</td>
<td>20</td>
</tr>
<tr>
<td colspan="2" style="text-align:center">VTP</td>
</tr>
</tbody>
<tbody>
<tr>
<td rowspan="2" class="sortNum">2</td>
<td class="depart">30</td>
<td>25</td>
</tr>
<tr>
<td colspan="2" style="text-align:center">VTP</td>
</tr>
</tbody>
<tbody>
<tr>
<td rowspan="2" class="sortNum">3</td>
<td class="depart">40</td>
<td>50</td>
</tr>
<tr>
<td colspan="2" style="text-align:center">VTP</td>
</tr>
</tbody>
<tbody>
<tr>
<td rowspan="2" class="sortNum">4</td>
<td class="depart">50</td>
<td>15</td>
</tr>
<tr>
<td colspan="2" style="text-align:center">VTP</td>
</tr>
</tbody>
<tbody>
<tr>
<td rowspan="2" class="sortNum">5</td>
<td class="depart">60</td>
<td>32</td>
</tr>
<tr>
<td colspan="2" style="text-align:center">VTP</td>
</tr>
</tbody>
</table>
You do not need the :eq Selector since you are referencing the Cells by css class. It does work in the first Column because the cell index is zero. What you are essentially saying in the selector $(a).find('td.sortNum:eq(' + index + ')') is "give me the list of td's with the class 'sortNum' and of that list the element at position index. But the first condition of the Selector - td.sortNum - will only return one element.
To make your sorting work again for the second column you could get rid of the :eq part
if(dataTH == 'number')
{
//alert("hi this is a number");
var aText = $(a).find('td.sortNum').text(),
bText = $(b).find('td.sortNum').text();
}
else if(dataTH == 'department')
{
//alert("hi this is a department");
var aText = $(a).find('td.depart').text(),
bText = $(b).find('td.depart').text();
}
see also http://jsfiddle.net/doc_snyder/Lvvmow8g/1/

Categories

Resources