I have a table like this
<table>
<tr>
<td>Item1<td>
<td><p>Description<p><br><td>
</tr>
<tr>
<td>Item2<td>
<td><p>Description1</p><p>Description2</p><br><td>
</tr>
<tr>
<td>Item3<td>
<td><p>Description3<p><br><td>
</tr>
</table>
Here is my javascript to get an array of items
var iList = document.querySelectorAll('td:first');
and here is to get all mapped td p content
var iDesc = document.querySelectorAll('td:second p');
I would like to create a mapped then sort its content in the onload event by the way. Is what I am doing correct ? I mean the selector td:first and second with my example table
In the example above there is one td element containing 2 p's
The pseudo-selectors :first and :second don't exist, (:first exist in jQuery but it's not a CSS selector).
Here is the official list of CSS selectors.
What you need here is the :nth-child pseudo selector :
var iList = document.querySelectorAll('td:nth-child(1)');
var iDesc = document.querySelectorAll('td:nth-child(2) p');
PS : Pay attention to your code, you don't close <td>s but re-open new ones, <td> don't have to be closed, which means that in this <tr> you have 4 <td>s :
<tr>
<td>Item1
<td>
<td><p>Description<p><br>
<td>
</tr>
You should run a loop for each tr element and get the keys and values from td elements. Next, push them into an array.
var arr = new Array();
$('table tr').each(function() {
var $row = $(this);
var key = $row.find('td:first').html();
var value = $row.find('td:last').html();
arr.push([key, value]);
});
Finally, sort the array by it's first index.
arr.sort(function(a, b) {
var valueA, valueB;
valueA = a[0]; // Where 1 is your index, from your example
valueB = b[0];
if (valueA < valueB) {
return -1;
}
else if (valueA > valueB) {
return 1;
}
return 0;
});
Live Demo
Related
I want to get value like in subject, from cell but that cell have element <a>1</a> and in this element is the value.
I tried something like this:
function filter(gvId) {
var table = document.getElementById(gvId);
for (var c = 1; c < table.rows[2].cells.length; c++) {
for (var r = headerNumber; r < table.rows.length; r++) {
var value = table.rows[r].cells[c].getElementsByClassName("a").innerHTML;
console.log(value); //and it should show me :
//1
//2
//3
//4
}
}
}
<table>
<tbody>
<tr>
<td><a>1</a>
</td>
<td><a>2</a>
</td>
</tr>
<tr>
<td><a>3</a>
</td>
<td><a>4</a>
</td>
</tr>
</tbody>
</table>
Everything works greate without <a> tag inside cell. But now I don't know how to get this value.
In your case, the problem is in a row:
var value = table.rows[r].cells[c].getElementsByClassName("a").innerHTML;
Because you're trying to match an element by class, but not by element tag. Link tag <a> has no className a. Your current code will work fine for: <a class="a">1</a> or <div class="a"></div>.
May be you should try something like querySelector instead? Like:
var value = table.rows[r].cells[c].querySelector('a').innerHTML;
Please, also check the MDN docs about getElementsByClassName and querySelector
UPD: All the code could be simplified:
var contentLinks = table.querySelectorAll('td a');
contentLinks.forEach(function(item) {
var value = item.innerHTML;
console.log(value);
});
Get the text content of an element with .textContent instead of .innerHTML
var value = table.rows[r].cells[c].textContent;
Documentation here and here
I have the following HTML table:
<table id="review-total">
<tbody><tr class="wlp">
<td class="left-cell">WLP Total</td>
<td>199.00</td>
</tr>
<tr class="tax">
<td class="left-cell">GST</td>
<td>19.90</td>
</tr>
<tr class="net">
<td class="left-cell">Order Total</td>
<td class="net-price">$218.90</td>
</tr>
</tbody>
</table>
I'm trying to loop through this table and retrieve the values i.e
199.00, 19.90 and $218.90 I have the following code:
var reviewTotal = document.getElementById('review-total');
for (var i = 1; i < reviewTotal.rows.length; i++) {
if (reviewTotal.rows[i].cells.length) {
wlpTotal = (reviewTotal.rows[i].cells[1].textContent.trim());
gstAmount = (reviewTotal.rows[i].cells[3].textContent.trim());
totalOrderAmount = (reviewTotal.rows[i].cells[5].textContent.trim());
}
}
I'm having a small issue trying to retrieve those values specified above, at present the error I get is textContent is undefined.
Can someone show me how I should go about retrieving those values, unfortunately I'm not strong in Javascript.
You have 3 rows and each row has only 2 cells. The 3 and 5 indices are undefined and undefined doesn't have .textContent property.
If you want to store the values by using specific variable names, you remove the loop and select the target elements manually:
var wlpTotal = reviewTotal.rows[0].cells[1].textContent.trim();
var gstAmount = reviewTotal.rows[1].cells[1].textContent.trim();
var totalOrderAmount = reviewTotal.rows[2].cells[1].textContent.trim();
If you want to store the values in an array, you can code:
var values = [].map.call(reviewTotal.rows, function(row) {
return row.cells[1].textContent.trim();
});
By using ES2015's Destructuring Assignment you can also extract the array's elements:
var [wlpTotal, gstAmount, totalOrderAmount] = values;
First:the index start the 0 either row or cell.
Secend:get value in the tag to use innerText or innerHTML ,The code following:
var reviewTotal = document.getElementById('review-total');
for (var i = 0; i < reviewTotal.rows.length; i++)
{
if (reviewTotal.rows[i].cells.length>1)
{
wlpTotal = (reviewTotal.rows[i].cells[1].innerText);
}
}
I have this code to try and sort the table by lowest price to highest price (the table is populated by ajax).
Heres the sorting code i have
$("#tableid tbody tr")
.detach()
.sort(function(a, b) {
var dataA1 = $(a)
.find("td:eq(5)")
.text()
.trim();
var dataB1 = $(b)
.find("td:eq(5)")
.text()
.trim();
return parseFloat(dataA1.substring(1)) - parseFloat(dataB1.substring(
1));
})
.appendTo('#tableid');
However i do have an issue with this that keeps happening
As you can see this is broken. the blank rows do have some text in and is in a colspan 6. What i'm wanting is these to be at the bottom of the table and the results at the top.
Any ideas how to do this?
Edit
<tr style="font-weight:bold">
<td>
<%= image_tag("provider-logo.png", style: "width: 140px") %>
</td>
<td colspan="6">
No Tickets Are available from provider
</td>
</tr>
This is one of the table rows that has a colspan (i had put the colspan 6 in the filter)
Thanks
Sam
Working with what you already have, add a filter, and use prependTo instead of appendTo:
$("#tableid tbody tr")
.filter(function() { return $(this).find('td[colspan="6"]').length == 0; })
.detach()
.sort(function(a, b) {
var dataA1 = $(a)
.find("td:eq(5)")
.text()
.trim();
var dataB1 = $(b)
.find("td:eq(5)")
.text()
.trim();
return parseFloat(dataA1.substring(1)) - parseFloat(dataB1.substring(
1));
})
.prependTo('#tableid');
I have the following type of table in html, which is generated dynamically by php :
<tr><td>Kiss the Girls</td><td>2016-01-01</td></tr>
<tr><td>Kiss the Girls</td><td>2016-02-05</td></tr>
<tr><td>Along Came a Spider</td><td>2016-01-07</td></tr>
<tr><td>Along Came a Spider</td><td>2016-01-22</td></tr>
<tr><td>Along Came a Spider</td><td>2016-03-31</td></tr>
I would like to be able to have a dynamic display filter that would allow the user to click a box and hide all but the latest version of the manuscript. So it might look like :
<tr><td>Kiss the Girls</td><td>2016-02-05</td></tr>
<tr><td>Along Came a Spider</td><td>2016-03-31</td></tr>
At this point none of the <tr> or <td> tags have an id or a class, but I could easily add a class to the first column (e.g., <td class='bookTitle'>). There is only one table on the page and php sorts it by date already. I'm open to jQuery or native JavaScript, though I would think this would be easier with jQuery. Seems like it could be done by just grabbing the last row before it changes names, but I'm not sure how to do that. Any thoughts?
According to 'Seems like it could be done by just grabbing the last row before it changes names', this is what I've come out with:
var rows = $("table tr");
if(rows.length > 0){
var last = $(rows[0]).find('td')[0].innerText;
for(var i=1; i<rows.length; i++){
var row = $(rows[i]);
var text = row.find('td')[0].innerText;
if(text === last){
$(rows[i-1]).hide();
}
last = text;
}
}
See the Pen Finding last occurrence of text by Tan Li Hau (#tanhauhau) on CodePen.
Iterate over the tr and store in key value pair where key as td content and value as object, after get the objects from it.
var a = {}; // object for storing dom element object
$('table tr').each(function() {
a[$('td:first', this).text().trim()] = this; // update the dom element object based on the column
});
var $res = $($.map(a, function(v) {
return v; // get objects and convert to jQuery object
}));
console.log($res);
$res.css('color', 'red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tr>
<td>Kiss the Girls</td>
<td>2016-01-01</td>
</tr>
<tr>
<td>Kiss the Girls</td>
<td>2016-02-05</td>
</tr>
<tr>
<td>Along Came a Spider</td>
<td>2016-01-07</td>
</tr>
<tr>
<td>Along Came a Spider</td>
<td>2016-01-22</td>
</tr>
<tr>
<td>Along Came a Spider</td>
<td>2016-03-31</td>
</tr>
</table>
FYI : If you want to maintain the order then the value with index and object array and set order based on that
You could iterate in reverse and remove everything you've seen before as you go:
function filterPreviousVersions ( ) {
var seen = {};
$( $('tr').get( ).reverse( ) ).each( function ( ) {
var text = $( 'td', this ).first( ).text();
if ( seen[ text ] )
$( this ).remove();
seen[ text ] = true;
} );
}
filterPreviousVersions();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tr>
<td>Kiss the Girls</td>
<td>2016-01-01</td>
</tr>
<tr>
<td>Kiss the Girls</td>
<td>2016-02-05</td>
</tr>
<tr>
<td>Along Came a Spider</td>
<td>2016-01-07</td>
</tr>
<tr>
<td>Along Came a Spider</td>
<td>2016-01-22</td>
</tr>
<tr>
<td>Along Came a Spider</td>
<td>2016-03-31</td>
</tr>
</table>
If you add ids in increasing order as you add the rows,
You may use this :
var valArray = [];
$('.maindiv').each(function() {
valArray.push(parseInt($(this).attr('id'), 10));
})
valArray.sort(function(a, b) {
return a - b
})
alert("Last row : " + document.getElementById(valArray[valArray.length - 1]).innerHTML); // highest`
alert("Second last : " + document.getElementById(valArray[valArray.length - 2]).innerHTML);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="2" class="maindiv">Contents in row 2</div>
<div id="5" class="maindiv">Contents in row 5</div>
<div id="3" class="maindiv">Contents in row 3</div>
<div id="1" class="maindiv">Contents in row 1</div>
<div class="main">Contents in test row</div>
<div id="4" class="maindiv">Contents in row 4</div>
To put it all together:
Succint: (May have some performance impact for large tables with many duplicate values)
$('tr').each(function(){
$("tr :contains('" + $('td', this).first().html() + "')").last()
.parent().css('color', 'red');
});
Explanation for the succint version:-
$('tr').each(function(){ // for each row of the table
$("tr // find a child inside a tr
:contains('" // that contains the text
+ $('td', this) // present within a td of the row (in line 1)
.first().html() // at the beginning
+ "')") // Using string concat to pass variable to `contains` selector)
.last() // at the end (last occurence of text)
.parent() // invoke `parent()` to select whole row
.css('color', 'red'); // apply css to identify the desired row.
});
Verbose: (Using Set of ECMAScript6 or $.unique() to remove duplicates from the full list of names. This way, when the forEach loop at the end of the code runs, it'll iterate only one per name.)
var uniqueNames = [];
$('tr').each(function(){
uniqueNames.push($('td', this).first().html());
}); // this will return the list of names from the table
// Remove duplicates from the list of names
uniqueNames = new Set(uniqueNames); // OR: uniqueNames = $.unique(uniqueNames);
uniqueNames.forEach(function(el){
$("tr :contains('" + el + "')").last().parent().css('color', 'red');
});
I got a table:
<table id="ItemsTable" >
<tbody>
<tr>
<th>
Number
</th>
<th>
Number2
</th>
</tr>
<tr>
<td>32174711</td> <td>32174714</td>
</tr>
<tr>
<td>32174712</td> <td>32174713</td>
</tr>
</tbody>
</table>
I need the values 32174711 and 32174712 and every other value of the column number into an array or list, i'm using jquery 1.8.2.
var arr = [];
$("#ItemsTable tr").each(function(){
arr.push($(this).find("td:first").text()); //put elements into array
});
See this link for demo:
http://jsfiddle.net/CbCNQ/
You can use map method:
var arr = $('#ItemsTable tr').find('td:first').map(function(){
return $(this).text()
}).get()
http://jsfiddle.net/QsaU2/
From jQuery map() documentation:
Description: Pass each element in the current matched set through a function, producing a new jQuery object containing the return values.
.
As the return value is a jQuery-wrapped array, it's very common to get() the returned object to work with a basic array.
// iterate over each row
$("#ItemsTable tbody tr").each(function(i) {
// find the first td in the row
var value = $(this).find("td:first").text();
// display the value in console
console.log(value);
});
http://jsfiddle.net/8aKuc/
well from what you have, you can use first-child
var td_content = $('#ItemsTable tr td:first-child').text()
// loop the value into an array or list
http://jsfiddle.net/Shmiddty/zAChf/
var items = $.map($("#ItemsTable td:first-child"), function(ele){
return $(ele).text();
});
console.log(items);