I am searching my Table Column for the string "None". It does this but I am unable to get the row number after. I am attempting to use the "rowIndex" attribute. Not sure why it is pulling "Not a Number" (NaN). Table is 50 rows 10 cols. I am assuming it may have to do with that I am pulling from a column instead of Row.
function F0416()
{
var tab = document.getElementById('part1Table');
var l = tab.rows.length;
var s = '';
for ( var i = 0; i < l; i++ )
{var tr = tab.rows[i];
var cll = tr.cells[2];
s += ' ' + cll.innerText;
}
var y = (s.indexOf('None') != -1)
document.write(this.rowIndex + 1)
Instead of concatenating all the values of the column into a string and searching the string, you could instead test the value of each cell in the column for the value 'None'. Then you would know the row number from the loop counter, and you could halt the loop if you find it instead of iterating over every row.
It would look more like this:
for ( var i = 0; i < l; i++ ) {
var tr = tab.rows[i];
var cll = tr.cells[2];
if(cll.innerText.indexOf('None') != -1) {
document.write(i + 1);
break;
}
}
You could also return the value of the row instead of outputting it.
I would recommend using a rich javascript library like JQuery.
Then given the following HTML:
<table>
<tr><td>Row 1- Column 1</td><td>Row 1 - Column 2</td>
<tr><td>none</td><td>Row 2 - Column 2</td>
<tr><td>Row 3- Column 1</td><td>Row 3 - Column 2</td>
</table>
You can use the following to get all the rows containing none:
var rows = $('table tr').filter(":contains('none')");
Have a look at this Fiddle example.
Related
I want to move columns of a table around in several hundred webpages that are outside of my control so that they print nicely. I can get to the tables in question easily enough with XPATH, but rearranging them has me stumped. Essentially, I want to rearrange this:
Table:
Header1 Header2
data1 data2
To this:
Table 1:
Header1
data1
Table 2:
Header2
data2
Is this possible?
Or, a simplified view of the existing HTML:
<table><tbody>
<tr>
<th>Header1</th>
<th>Header2</th>
</tr>
<tr>
<td>data1</td>
<td>data2</td>
</tr>
</tbody></table>
It isn't strictly necessary that these become separate tables, but the data portions are just wide enough to fit on a page, so they can't be in the same row.
Thanks in advance!
Update:
I have been learning jQuery, and it looks like I could use something like this:
function jqsplit($table, chunkSize) {
var cols = $("th", $table).length;
var n = cols / chunkSize;
for (var i = 0; i <= n; i++) {
$("<br/>").appendTo("body");
var $newTable = $table.clone().appendTo("body");
for (var j = cols; j > 0; j--) {
if (j + chunkSize - 1 <= chunkSize * i || j > chunkSize * i + 1) {
$('td:nth-child(' + j + '),th:nth-child(' + j + ')', $newTable).remove();
}
}
}
}
(Stolen from here, but modified for my particular use case.)
The problem I now have is that I can't figure out how to select my initial table with jquery, and if I can process them all together. The original tables always have 2 rows and 3 columns, and no other tables match that criteria, can anyone help?
OK, Solved it. My solution is inelegant as all hell, but works perfectly. Awful code, away!
function jqsplit($table, chunkSize) {
//Splits these specific tables into 3 by creating 3 copies and deleting the unneeded rows.
var $randomP = $("<p></p>").insertAfter($table);
var $newTable1 = $table.clone().appendTo($randomP);
var $newTable2 = $table.clone().appendTo($randomP);
var $newTable3 = $table.clone().appendTo($randomP);
$newTable1.children("tbody").children("tr").children("th").get(2).remove();
$newTable1.children("tbody").children("tr").children("td").get(2).remove();
$newTable1.children("tbody").children("tr").children("th").get(1).remove();
$newTable1.children("tbody").children("tr").children("td").get(1).remove();
$newTable2.children("tbody").children("tr").children("th").get(2).remove();
$newTable2.children("tbody").children("tr").children("td").get(2).remove();
$newTable2.children("tbody").children("tr").children("th").get(0).remove();
$newTable2.children("tbody").children("tr").children("td").get(0).remove();
$newTable3.children("tbody").children("tr").children("th").get(1).remove();
$newTable3.children("tbody").children("tr").children("td").get(1).remove();
$newTable3.children("tbody").children("tr").children("th").get(0).remove();
$newTable3.children("tbody").children("tr").children("td").get(0).remove();
$table.remove();
}
//Split table
var tablelist = $("table");
$.each(tablelist, function(index,value){
if ( $(this).children("tbody").children("tr").children("th").length == 3 && $(this).children("tbody").children("tr").length == 2 && $(this).children("tbody").children("tr").children("td").length == 3) {
jqsplit($(this), 1);
//Don't want to do the below because some pages have several matching tables
//return false;
}
});
I am kind of new to javascript and trying to accomplish a simple (yet complicated for me) task. I am trying to exclude first row and first column from a table and got stuck in excluding first cell in every row from this table (HTMLTableRowElement). Following is my sample code.
function clickSchedule(){
var table
var grow // group row
table= document.getElementById("myTable");
grow = table.rows;
for(var i= 1; i<= grow.length ; i++ ){
var cellIndex = this.cells;
for( var j =1 ; j<= cellIndex.length ; j++ ){
this.onclick = function () {
alert("test");
}
}
}
The first "for loop" will grab all rows from the table excluding row[0] that is why you can see var i = 1. Next, I am storing cells from all rows to a variable and trying to exclude cell[0] using second "for loop" in order to perform an onclick event to the selected table area.
Also, is it possible to get the index value of the selected cell from this table?
I would really appreciated your help
Faraz Amjad
Your logical part is right and wrong.
Start iteration from index 1 is right.
i <= grow.length means when it's true, go on iteration. But when i == grow.length, grow[i] should be undefined, because grow.length-1 is the last index. So the right condition expression should be i < grow.length.
You didn't do event binding right in iterations.
Try this one:
(function(){
var table = document.querySelector('table')
var rows = table.rows
var cells
for(var i = 1; i < rows.length; i++ ) {
cells = rows[i].cells
for(var j = 1; j < cells.length; j++ ) {
cells[j].onclick = function() {
alert(this.innerHTML);
}
}
}
})()
<table>
<tr>
<td>a1</td><td>a2</td><td>a3</td><td>a4</td>
</tr>
<tr>
<td>b1</td><td>b2</td><td>b3</td><td>b4</td>
</tr>
<tr>
<td>c1</td><td>c2</td><td>c3</td><td>c4</td>
</tr>
<tr>
<td>d1</td><td>d2</td><td>d3</td><td>d4</td>
</tr>
</table>
I'm trying to use JS to sum up a column of already Javascript-generated values. I'm new to JS, so this may be way wrong. At any rate, I tried this:
NOTE -- FINAL CODE AT BOTTOM
$(".js-package").change(function(){
var parentTable = $(this).parents("table");
var table_rows = parentTable.rows;
var height = table_rows.length;
var total = 0;
for (var i = 0; i < height; i++) {
var current_row = table_rows[i];
total += current_row[5];
}
$(parentTable).find(".js-lb-total").html((total).toFixed(2));
});
This applies to a bunch of html, but the relevant stuff is that I've got this line where things are supposed to total up:
<td class="js-lb-total">?</td>
And this further up:
<td>
<%= l.select :units, dropdown, {}, :class => "unit_select js-package" %>
</td>
Importantly, the seemingly arbitrary number 5 refers to the column (assuming JS starts arrays at 0) that I'm trying to sum up.
Any idea what I'm doing wrong/how to fix it? I'll go ahead and look into opening a fiddle that I can link to with the more complete code. I'll add that link below.
Thanks!
EDIT -- Row totaling script below
$(".js-package").change(function(){
var numOfPackages = parseFloat($(this).val());
var parentTr = $(this).parents("tr");
var parentTable = $(this).parents("table");
var weight = parseFloat($(parentTr).find(".js-weight").attr('data-weight'));
var price = parseFloat($(parentTr).find(".js-lb-price").attr('data-lb-price'));
$(parentTr).find(".js-price").html(((numOfPackages * weight * price).toFixed(2)));
$(parentTr).find(".js-lbs").html((numOfPackages * weight).toFixed(2));
});
EDIT 2 -- Basic fiddle link here Fiddle. None of the JS is working there, though, for some reason. (The first bunch works on my server). So it may not be particularly helpful.
EDIT 3 -- To be clear, I'm trying to sum a column whose values are all dynamically generated by another javascript action. They're not in the html. Could that be part of the problem?
FINAL EDIT -- After much tweaking and following of advice, I got this, which works great (and totals both price and poundage, after totaling each line).
$(".js-package").change(function(){
var numOfPackages = parseFloat($(this).val());
var parentTr = $(this).parents("tr");
var parentTable = $(this).parents("table");
var weight = parseFloat($(parentTr).find(".js-weight").attr('data-weight'));
var price = parseFloat($(parentTr).find(".js-lb-price").attr('data-lb-price'));
$(parentTr).find(".js-price").html(((numOfPackages * weight * price).toFixed(2)));
$(parentTr).find(".js-lbs").html((numOfPackages * weight).toFixed(2));
var table = document.getElementById('sumtable');
var table_rows = table.rows;
var height = parseInt(table_rows.length);
var lb_total = 0;
var money_total = 0;
var cell;
for (var i = 1, iLen = height - 1; i < iLen; i++) {
cell = table_rows[i].cells[5];
lb_total += Number(cell.textContent);
}
for (var j = 1, jLen = height - 1; j < jLen; j++) {
cell = table_rows[j].cells[6];
money_total += Number(cell.textContent);
}
$(parentTable).find(".js-lb-total").html(lb_total.toFixed(2));
$(parentTable).find(".js-price-total").html(money_total.toFixed(2));
});
The example below might get you started. If the headers and footers are in a different table section, it will make life easier, I've put them all in the one tbody.
Things to note:
Values read from cells will be strings, so you need to convert them to numbers
Javascript is notoriously bad at decimal arithmetic, much better to do integer arithmetic and convert to decimal only at the very end for presentation
Be careful of Math.toFixed, it has quirks, search the questions
Good luck. :-)
<script>
// column is the column with values in it to total (first column is zero)
// Assume values are floats.
function addRows(tableId, column, resultId) {
var table = document.getElementById(tableId);
var rows = table.rows;
var total = 0;
var cell;
// Assume first row is headers, adjust as required
// Assume last row is footer, addjust as required
for (var i=1, iLen=rows.length - 1; i<iLen; i++) {
cell = rows[i].cells[column];
total += Number(cell.textContent || cell.innerText);
}
document.getElementById(resultId).innerHTML = total.toFixed(2);
}
</script>
<table id="productTable">
<tr>
<th>Item
<th>value ($)
<tr>
<td>foo
<td>23.33
<tr>
<td>bar
<td>03.04
<tr>
<td>Total
<td id="totalValue">
</table>
<button onclick="addRows('productTable', 1, 'totalValue')">Update total</button>
try this:
total = parseInt(total)+ parseInt(current_row[5].childNodes[1].value);
if that doesn't work try getting the cell of the column you want:
total =parseInt(total)+ parseInt(current_row[5].cells[try numbers here].childNodes[1].value);
hope i helped.
I have a jquery code that displays results in one row and multiple columns as follows
function () {
var i = noDays;
var days = 30;
while (i < days) {
$('tr').append('<td> ' + i + ' </td>');
i++;
},
}
When I have more than 10 results (10 columns), the row stretch outside the page
How can I divide the row into multiple rows for instance?
if I have 30 columns in 1 row
I would like to instead have 6 columns and 5 rows
Not sure exactly where you're appending the data, but look at the code here: http://jsfiddle.net/kdst5/1/ - using the modulus operator on "i" can tell you when you to move to a new line; Additionally, instead of using $("tr"), you should use a specific selector, not necessarily the variable that I used, but something more specific than a general "every TR" selector.
It is better to create an element and use a reference to it, as opposed to having jquery fire off a selector in every pass.
Here is a working solution and its jsfiddle:
var $table = $("#myTable");
var i = 1;
var days = 30;
var $tr = $("<tr>");
while (i <= days) {
$tr.append('<td>' + i++ + '</td>');
if (i %6 == 1) {
$table.append($tr);
$tr = $("<tr>");
}
};
$("#myTable").append($tr);
I'm trying to make a table that has 3 cells to a row, and into those three cells, I have a string that I get from a textbox from a HTML form that I created an array from. I'm using JavaScript to do this, and I have it to where I have each word in their own cell, but if there is an empty cell, it won't create a cell. How can I fill that empty cell with another word like "empty".
This is what I have so far.
arrays=tx_val.split(' ');
table="< table border='1' bgcolor=gray>"
for(x=0;x< arrays.length-2;x=x+3)
{
if(x<arrays.length-2)
{
table=table+"< tr>< td>"+arrays[x]+"< /td> <td>"+arrays[x+1]+
"< /td>< td>"+arrays[x+2]+"</td><td>";
}
else
{
table=table+"< /tr>< /table>"
}
}
|| 'empty'
as in
(arrays[x] || 'empty')
or
var empty = '--empty--';
if(x) table += "<tr><td>" + (arrays[x] || empty) + "</td> " + (arrays[x+1] || empty) + "</td><td>" + (arrays[x+2] || empty) + ""
There are errors in your logic that might be causing you problems:
for(x=0;x< arrays.length-2;x=x+3)
{
if(x<arrays.length-2)
Based on the for loop, the if statement will always evaluate to true. As such, for every iteration, you are adding a table row without an ending tr element and you are adding a table cell without an ending td element. The result will be ill-formed HTML that might not be rendering as you desire, even if you get some 'empty' value put in a cell.
Try this:
arrays = tx_val.split( ' ' );
table = "< table border='1' bgcolor=gray>";
currItem = 0;
for( x = 0; x < Math.ceil( arrays.length / 3 ); x = x + 1 )
{
table = table + "<tr>";
for( y = 0; y < 3; y = y + 1 )
{
if( arrays[currItem] == "" )
{
displayItem = "";
}
else
{
displayItem = arrays[currItem];
}
table = table + "<td>" + displayItem + "</td>";
currItem = currItem + 1;
}
table = table + "</tr>";
}
Basically, I changed the loops to form the table code per row first, then per column.
The outer for loop is the one responsible for adding code for each row. The Math.ceil( arrays.length / 3 ) formula determines the number of rows the table should have depending on the number of values in the array. The inner for loop creates 3 cells for each row.
If you want to change the dimensions of the table want to create you can just change the divisor in the Math.ceil function in the outer loop as well as the number used in the condition in the inner loop ( y < 3 ).