Need to sort a table based on attribute value - javascript

I have a table with multiple values and table values are moved from one table to another. When it returns to initial table then I need to sort this table based on the alphabetical order.
I am using this code but it doesn't work for me:
var aa = $("#unSelectedTab").find('td');
var abc = '';
for (var i = 0; i < aa.length; i++) {
abc += aa[i].attr("id");
}

It's a lot of code but this should do it:
<!DOCTYPE html>
<html>
<head>
<script src="jquery-1.9.0.js"></script>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<title>Example</title>
</head>
<body>
<table>
<tbody>
<tr><th>number</th><th>letter</th></tr>
<tr>
<td>3</td>
<td>a</td>
</tr>
<tr>
<td>2</td>
<td>c</td>
</tr>
<tr>
<td>2</td>
<td>c</td>
</tr>
<tr>
<td>2</td>
<td>b</td>
</tr>
<tr>
<td>3</td>
<td>b</td>
</tr>
<tr>
<td>1</td>
<td>c</td>
</tr>
</tbody>
</table>
<script type="text/javascript">
function helper_getText(el){
return (el.innerText)?el.innerText:el.textContent;
}
function sortTable(table,byCols){
var rows=table.getElementsByTagName("tr"),
rowArr=[],
i,rowValues=[],j,cells,
tbody=table.getElementsByTagName("tbody")[0];
for(i=0;i<rows.length;i++){
cells=rows[i].getElementsByTagName("td");
if(cells.length===0){
continue;
}else{
rowArr.push($.clone(rows[i]));
rows[i].parentElement.removeChild(rows[i]);
i--;
}
rowValues.push({vals:[],index:rowValues.length});
for(j=0;j<byCols.length;j++){
rowValues[rowValues.length-1].vals.push(
// here you can get the attribute instead
// if there are multiple attributes per column
// to sort on then this gets more difficult
// $.trim(cells[byCols[j]].document.body.getAttribute("data-something"))
$.trim(helper_getText(cells[byCols[j]]))
);
}
}
//sort by multiple columns should be seporate function
rowValues.sort(function(a,b){
var i = 0;
while(a.vals[i]==b.vals[i]&&i<a.vals.length){
i++;
}
if(i===a.vals.length){return 0};
return (a.vals[i]>b.vals[i])?1:-1;
});
//add the rows in the right order
for(i=0;i<rowValues.length;i++){
tbody.appendChild(rowArr[rowValues[i].index]);
}
}
//[1,0] means sort by colum 2 first than by colum 1
sortTable(document.getElementsByTagName("table")[0],[1,0]);
</script>
</body>
</html>

Related

change attribute of appended element

for (var i = 0; i < 10; i++) {
var tr = $("<tr></tr>")
tr.append("<td>1</td>");
tr.append("<td>2</td>");
$("table tbody").append(tr)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody></tbody>
</table>
How Can I append rows and then dynamically change the rowspan of every second row. What I want to happend is it will look like below:
<table border='1'>
<tbody>
<tr>
<td rowspan="2">1</td>
<td>2</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td rowspan="2">1</td>
<td>2</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td rowspan="2">1</td>
<td>2</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td rowspan="2">1</td>
<td>2</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td rowspan="2">1</td>
<td>2</td>
</tr>
<tr>
<td>2</td>
</tr>
</tbody>
</table>
I tried using index but it is not adding the rowspan
Any help is appreciated.
FYI : What I want to happened is append first then change the row span after the row is appended
Just added mod (%)
for (var i = 0; i < 10; i++) {
var tr = $("<tr></tr>");
if(i%2===0){
tr.append("<td rowspan='2'>1</td>");
}
tr.append("<td>2</td>");
$("table tbody").append(tr)
}
td, th {
border: 1px solid #ddd;
padding: 8px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<table>
<tbody></tbody>
</table>
</body>
</html>
I hope I achieve what you need.
I base the result from your second snippet.
for (var i = 0; i < 10; i++) {
var tr = $("<tr></tr>")
tr.append("<td>1</td>");
tr.append("<td>2</td>");
$("table tbody").append(tr)
}
$('button').click(function(){
$('table tr:odd td:first-child').remove();
$('table tr:even td:first-child').attr('rowspan', 2);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1">
<tbody></tbody>
</table>
<button>append</button>
try to use html string and then attach it to your element and make the rowspan dynamic for example :
var html_string = '<tr>'
for (var i = 0; i < 10; i++) {
html_string+= '<td rowspan="'+i+'">1</td>'
html_string += '<td>2</td>'
}
html_string +='</tr>'
$("table tbody").append(html_string)
Below code may help,
for (var i = 0; i < 10; i++) {
var tr = $("<tr></tr>");
tr.append("<td>1</td>");
tr.append("<td>2</td>");
$("table tbody").append(tr)
}
$('table tr:odd td:first-child').remove();
$('table tr:even td:first-child').attr('rowspan', 2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border='1'>
<tbody></tbody>
</table>

Nth child in table not working Javascript

The td:nth-child('n') is not working over in my table it gives null in the log Where as it is working when i use children[n] it is a simple function for searching
I couldn't find the reason why it is giving out a null.. Here is the code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Table Searching</title>
<style>
th{
font-weight: bolder;
}
table, th, td{
font-size: 20px;
border: 2px solid black;
border-collapse: collapse;
}
</style>
</head>
<body>
<input type="text" name="search">
<button class="s" onclick="Search()">Search by Name</button>
<button class="s" onclick="Search()">Search by Country</button>
<button class="s" onclick="Search()">Search by Pet</button>
<table>
<tr>
<th>Name</th>
<th>Country</th>
<th>Pet</th>
</tr>
<tr>
<td>Abhi</td>
<td>Canada</td>
<td>koala</td>
</tr>
<tr>
<td>Riya</td>
<td>France</td>
<td>Parrot</td>
</tr>
<tr>
<td>Sid</td>
<td>UK</td>
<td>Pig</td>
</tr>
<tr>
<td>Kritika</td>
<td>Germany</td>
<td>Cat</td>
</tr>
<tr>
<td>Kartik</td>
<td>China</td>
<td>Frog</td>
</tr>
<tr>
<td>Radhika</td>
<td>India</td>
<td>Dog</td>
</tr>
</table>
<script>
var input=document.getElementsByName("search")[0];
var s=document.getElementsByClassName("s");
var n=0;
function Search(){
for (var j=0; j<s.length; j++)
{
console.log("element");
console.log(s[j]);
console.log("target");
console.log(event.target);
if(s[j]==event.target){
n=j;
console.log(n);
}
}
var val= input.value;
var a=document.querySelectorAll("table > tbody > tr");
console.log(a);
for(var i =0; i<a.length; i++)
{
var d = a[i].querySelector('td:nth-child("+n+")');
console.log(d);
if(d.innerHTML.toLowerCase()==val.toLowerCase()){
a[i].style.display="";
}
else
{
a[i].style.display="none";
}
}
}
</script>
</body>
</html>
Here are the three reasons why you are giving out null in your code:
First, as stated by Satpal, this code 'td:nth-child("+n+")' will not replace n by its value. It's like writing td:nth-child("+n+") in css.
The solution for this is to write: 'td:nth-child(' + n + ')'. You then concatenate the value of n with the rest of the string
The value of n is an index in a array, so it starts at 0 and ends at array.length - 1. The problem is that the nth-child selector actually selects the nth-child (brilliant naming), so if n is 0 (in the case of searching by name), you'll try to select the 0th-child, wihich doesn't exist... You then have to write: 'td:nth-child(' + (n + 1) + ')' or change the definition of n
You have no <tbody> tag in your HTML. Which means that all the content of the table will be wrapped in a tbody and your selector document.querySelectorAll("table > tbody > tr")will also selects the header of your table. To avoid that, change your HTML accordingly.
Something like that:
<table>
<thead>
<tr>
<th>Name</th>
<th>Country</th>
<th>Pet</th>
</tr>
</thead>
<tbody>
<tr>
<td>Abhi</td>
<td>Canada</td>
<td>koala</td>
</tr>
<tr>
<td>Riya</td>
<td>France</td>
<td>Parrot</td>
</tr>
<tr>
<td>Sid</td>
<td>UK</td>
<td>Pig</td>
</tr>
<tr>
<td>Kritika</td>
<td>Germany</td>
<td>Cat</td>
</tr>
<tr>
<td>Kartik</td>
<td>China</td>
<td>Frog</td>
</tr>
<tr>
<td>Radhika</td>
<td>India</td>
<td>Dog</td>
</tr>
</tbody>
</table>
Here is a jsfiddle where the search works fine: https://jsfiddle.net/n23685b6/1/
Hope this helps!
scrollToNthChild = (): * => {
var tableBody = document.getElementById('event-table-body');
var tableRows = tableBody.getElementsByTagName('tr');
let targetElement = tableRows[7];
targetElement.scrollIntoView();
}

Sort a table on clicking the header of each column using jQuery without duplicating the entire table

Trying to sort the table by just duplicating the row and not the entire table. On click of the column header that column's data must be compared and sorted and the rows rearranged , but I don't know where i am going wrong.Here is my code.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Table Sort</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"> </script>
<script type="text/javascript">
$(document).ready(function() {
$('th').click(function() {
var ColNo = parseInt($(this).index());
var rows= $('tbody').children('tr');
var TotRows = parseInt(rows.length);
for (var i = TotRows-1; i >= 0; i--) {
for (var j = TotRows-1; j > 0; j--) {
var jint = parseInt(j);
var frstval = parseInt(rows[jint].getElementsByTagName("td")[ColNo].innerHTML);
var scndval = parseInt(rows[jint - 1].getElementsByTagName("td")[ColNo].innerHTML);
if (frstval < scndval) {
var a = frstval < scndval;
alert(a);
var sourceRow = $('tr').eq(jint);
alert(sourceRow);
var targetRow = $('tr').eq(jint-1);
targetRow.after(sourceRow.clone());
sourceRow.replaceWith(targetRow);
}
}
}
});
});
</script>
</head>
<body>
<table>
<thead>
<tr>
<th>Employee Id</th>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr>
<td>11</td>
<td>AAA</td>
<td>28</td>
</tr>
<tr>
<td>22</td>
<td>BBB</td>
<td>29</td>
</tr>
<tr>
<td>33</td>
<td>CCC</td>
<td>21</td>
</tr>
<tr>
<td>44</td>
<td>DDD</td>
<td>24</td>
</tr>
</tbody>
</table>
</body>
</html>
Better if you use a dhtmlXgrid... It's easier to implement, and you can create a JSON object of the entire dataset that you want to fill in the table. Then, just parse the JSON object into the dhtmlXgrid. With dhtmlXgrid, sorting, column size, column drag and drop, row drag and drop, etc., all such activities can be made automatically.

Table sort columns horizontal

I have a problem sorting a table.
My table HTML is this:
<table>
<tr>
<td>3</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
</tr>
</table>
And I want it to look like this:
<table>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
</tr>
</table>
Here is my current sorting code:
var rows = $('tr');
rows.eq(0).find('td').sort(function(a, b) {
return $.text([a]) > $.text([b]) ? 1 : -1;
}).each(function(newIndex) {
var originalIndex = $(this).index();
rows.each(function() {
var td = $(this).find('td');
if (originalIndex !== newIndex)
td.eq(originalIndex).insertAfter(td.eq(newIndex));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table>
<tr>
<td>3</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
</tr>
</table>
The code only sorts by separate rows. I can't use any plugins and I need to do this with jquery or javascript. Can anyone suggestion how to make it work?
It's simple.
Store all the numbers from td in an array.
Sort the array.
Modify the tds according to array.
Here's how you'd do it in JS:
var tds= [].slice.call(document.getElementsByTagName("td")); //Find <td> and store in array
var tdsa=tds.map(function (a) {return Number(a.innerHTML);}); //Take the innerHTMLs
tdsa.sort(); //Sort it
tds.forEach(function(a,i) {a.innerHTML=tdsa[i]}); //Modify <td>'s innerHTML
Try this - method:
get the items of the table into an array
sort the array
rebuild the rows
var columnCount = 2;
var items = [];
$('td').each(function (idx, obj) {
items.push(obj.innerHTML);
});
items.sort();
$('table tr').remove();
for(var i=0; i<items.length; i+=2) {
var row = '<tr>';
for(var j=0; j<columnCount; j++) {
row += '<td>' + items[i+j] + '</td>';
};
row += '</tr>';
$('table').append(row);
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table>
<tr>
<td>3</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
</tr>
</table>

Hide rows in table B which already appear in table A

Using this code :
var table1 = $('#TableA').find('td:eq(1)').text();
var table2 = $("#TableB tr:gt(0)");
table2.each(function (i) {
var tds = $(this).children('td');
var type= +tds.eq(0).text();
var price = +tds.eq(1).text();
if (price == table1) {
var myTable = table2.filter(function () {
var tds = $(this).children('td');
})
myTable.add(this).hide()
}
})
My Html Page Structure
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<table id="TableA">
<tr>
<th>Type</th>
<th>Price</th>
<th>Quantity</th>
<th>Ref No</th>
</tr>
<tr>
<td>Mouse</td>
<td>50</td>
<td>6</td>
<td>#101255</td>
</tr>
<tr>
<td>Speaker</td>
<td>300</td>
<td>6</td>
<td>#21165</td>
</tr>
</table>
<table id="TableB">
<tr>
<th>Type</th>
<th>Price</th>
<th>Quantity</th>
<th>Ref No</th>
</tr>
<tr>
<td>Mouse</td>
<td>50</td>
<td>6</td>
<td>#101255</td>
</tr>
<tr>
<td>Speaker</td>
<td>300</td>
<td>6</td>
<td>#21165</td>
</tr>
<tr>
<td>Keyboard</td>
<td>150</td>
<td>7</td>
<td>#31234</td>
</tr>
</table>
</body>
</html>
"The second table in the images is the Table B"
My Table B changes from this :
Before
To this : After
Now my problem is, only one row is hidden. The row, where "speaker" is, is still displayed. I know that I must use a loop for this, but I don't where to implement the loop and how. I'm a newbie programmer and I know that I need more practice. Please Help Thank you in advance
<script type="text/javascript">
$('body').click(function(e){
var table1_tr = $('#TableA').find('tr'); <!--get the rows of first table-->
var table2 = $("#TableB tr:gt(0)");
table1_tr.each(function(i,e){ <!-- loop through rows of first table -->
var table1 = $(e).find('td:eq(1)').text();
table2.each(function (i) {
var tds = $(this).children('td');
var type= +tds.eq(0).text();
var price = +tds.eq(1).text();
if (price == table1) {
var myTable = table2.filter(function () {
var tds = $(this).children('td');
})
myTable.add(this).hide()
}
});
})
});
</script>
you are checking the text of price in the first row of first table with td text of all the rows of second table
I modified script to loop through rows of first table and check them with all rows of second table
Hope this helps

Categories