Write values to td with no id? - javascript

I need to edit values in a table where the rows/cells are generated dynamically so I they have no html id. I am currently doing this by going to tr:nth-child, but this only works if the value I set for rowID corresponds to that position in the table. Ex: If I remove the 3rd item from the table, the item with rowID=4 is now the 3rd child of the tr, and the following code will edit the wrong cells.
// I get the rowID like this:
rowID = $(this).data("row-id");
// This is what I'm doing now to edit the table:
$('#or-table tr:nth-child(' + rowID + ') td:nth-child(3)').html($('#aff-selector').val());
$('#or-table tr:nth-child(' + rowID + ') td:nth-child(4)').html($('#editor-code').val());
$('#or-table tr:nth-child(' + rowID + ') td:nth-child(5)').html($('#editor-lat').val());
$('#or-table tr:nth-child(' + rowID + ') td:nth-child(6)').html($('#editor-long').val());
<!-- This is the table: -->
<table id="or-table" class="table table-condensed table-hover table-striped bootgrid-table">
<thead>
<tr>
<th data-column-id="id" data-identifier="true" data-type="numeric">ID</th>
<th data-column-id="aff" align="center">Affiliation</th>
<th data-column-id="code">Symbol Code</th>
<th data-column-id="lat">Latitude</th>
<th data-column-id="long">Longitude</th>
<th data-column-id="commands" data-formatter="commands" data-sortable="false">Commands</th>
</tr>
</thead>
<tbody></tbody>
</table>

You could dynamically assign the row ids using a for loop and then redo that calculation every time you remove a row.
function foo () {
var rowCount = $('#or-table tbody tr').length;
for (i=1;i <= rowCount; i++) {
$('#or-table tbody tr:nth-child("'+i+'")').data('row', i);
}
}
You could run this function on $(document).ready and again after the removal of any row.

Use the HTMLTableElement interface. BTW, why would you need to remove a <td>? Wouldn't be easier just to remove the data inside the <td>?
Get a reference to the <table>
-var or = document.getElementById('or-table');
Then use the .rows property.
-or.rows[0] // first row of table
Next, use the .cells property.
-or.rows[0].cells[2] // first row, 3rd cell
Finally, edit the value of cell with innerHTML or textContent.
-or.rows[0].cells[2].innerHTML='test' // set first row, 3rd cell content to "test"
The following Snippet demonstrates the use of the HTMLTableElement interface:
SNIPPET
var or = document.getElementById('or-table');
function seekCell(row, cell) {
var data = document.getElementById('data').value;
var row = parseInt(row, 10);
var cell = parseInt(cell, 10);
var rows = or.rows.length; // max number of rows
var cells = rows * 6; //max number of cells
(row > rows) ? row = rows: row = row - 1;
(cell > cells) ? cell = cells: cell = cell - 1;
var tgt = or.rows[row].cells[cell];
tgt.innerHTML = data;
}
[type='number'] {
width: 30px;
}
<!-- This is the table: -->
<table id="or-table" class="table table-condensed table-hover table-striped bootgrid-table">
<thead>
<tr>
<th data-column-id="id" data-identifier="true" data-type="numeric">ID</th>
<th data-column-id="aff" align="center">Affiliation</th>
<th data-column-id="code">Symbol Code</th>
<th data-column-id="lat">Latitude</th>
<th data-column-id="long">Longitude</th>
<th data-column-id="commands" data-formatter="commands" data-sortable="false">Commands</th>
</tr>
</thead>
<tbody>
<tr>
<td>01</td>
<td>NONE</td>
<td>🗡</td>
<td>20</td>
<td>30</td>
<td>KILL</td>
</tr>
<tr>
<td>02</td>
<td>NONE</td>
<td>🖉</td>
<td>30</td>
<td>30</td>
<td>EDIT</td>
</tr>
</tbody>
</table>
<form id='f1' name='f1' onsubmit='seekCell(row.value, cell.value)'>
<fieldset>
<legend>Row & Cell</legend>
<label>Row:
<input id='row' name='row' type='number' min='1' max='99'>
</label>
<label> <small>Note: The first row is the <thead></small>
</label>
<br/>
<label>Cell:
<input id='cell' name='cell' type='number' min='1' max='6'>
</label>
<label><small> Note: The number will be adjusted for 0-Index enumeration. (i.e. input -1)</small>
</label>
<br/>
<label>Data:
<input id='data'>
</label>
<input type='submit'>
</fieldset>
</form>

Related

How can I add rows to be filled from javascript

I have my code for a table that I created in html with one row, but I want to add more rows to it, the number of total rows has to be equal to the value that my combox takes (24,36,48 rows in total):
<div id="visible" class="table-responsive">
<table class="table " id="tablacondatos" name="tablacondatos">
<thead>
<tr>
<th scope="col">MES</th>
<th scope="col">CUOTA</th>
<th scope="col">INTERES</th>
<th scope="col">AMORTI.</th>
<th scope="col">CAPITAL</th>
<th scope="col">SEGURO DESGRAV.</th>
<th scope="col">SEGURO INMOBIL.</th>
<th scope="col">GASTOS ADM.</th>
<th scope="col">CUOTA FINAL</th>
</tr>
</thead>
<tbody id="cuerpotabla" name="cuerpotabla">
<tr id="filamaestra">
<td id="mes" name="mes">0</td>
<td id="cuota" name="cuota">0</td>
<td id="interes" name="interes">0</td>
<td id="amorti" name="amorti">0</td>
<td id="capital" name="capital">0</td>
<td id="segurodesgrav" name="segurodesgrav">0</td>
<td id="seguroinmobil" name="seguroinmobil">0</td>
<td id="gastosadm" name="gastosadm">0</td>
<td id="cuotafinal" name="cuotafinal">0</td>
</tr>
</tbody>
</table>
</div>
This is how I get the value of my combo for the rows:
ahorrar = document.getElementById("plazooperacion").value; // 24,36,48 rows
I am using this code to add rows, but the problem is that it generates too many rows, and in the first cells I am putting a counter, which goes from 1 to 24, or 1 to 36 or from 1 to 48; but it generates them backwards (it puts the last one first and the first one last):
ms=ms+1; //accountant
var table = document.getElementById("cuerpotabla");
var row = table.insertRow(0);
//this adds row in 0 index i.e. first place
row.innerHTML = "<td>"+ms+"</td><td id='cuota' name ='cuota'>"+cuota+"</td><td id='interes' name='interes'>"+interes+"</td><td id='amorti' name='amorti'>"+amorti+
"</td><td id='capital' namre='capital'>"+capital+"</td><td id='segurodesgrav' name='segurodesgrav'>"+segurodesgrav+"</td><td id='seguroinmobil' name='seguroinmobil'>"+seguroinmobil+"</td><td id='gastosadm' namre='gastosadm'>"+gastosadm+"</td><td id='cuotafinal' name='cuotafinal'>"+cuotafinal+"</td>";

table row as a counter in HTML

I would like to know how could I assign a table row an id which is systematically as a counter. It can be a string + a counter as follow:
<table>
<tr id="Row1"> # it can be only a number => id="1"
<tr id="Row2"> # it can be only a number => id="2"
<tr id="Row3"> # it can be only a number => id="3"
.....
<tr id="Row5000"> # it can be only a number => id="5000"
</table
Because I have thousands of rows and then could not assign id to them manually. This is why I want to assign them via XSLT. Does anybody know how could I do so? Thanks.
// javascript
var table = document.querySelectorAll('table tr');
{
for(var i=0;i<table.length;i++){
table[i].setAttribute("id",i+1);
}
//jquery
$("table tr").each(function(index,object) {
object.attr("id",(index+1));
})
$("table tr").each(function(i, tr) {tr.id = 'Row' + (i+1);})
explanation: you can find each tr in table and assign id for each one.
First you assign an id attribute to your table like this
<table id="mytable">
<tr></tr>
<tr></tr>
....
</table>
Then add a script at the bottom of your document
<script>
(function() {
var rows = document.getElementById("mytable").rows;
for(var i = 1; i <= rows.length; i++) {
rows[i-1].id = 'Row'+i;
}
})();
Its a pure javascript solution. No jQuery required.
Assign your table an id. here its newTable then iterate and set the attibute
<script>
function getit(){
$('#newTable').find('tr').each(function(index){
var x= this.setAttribute("id","Row"+[index]);
console.log(x);
})
}
</script>
hope that helped.
You Can Use This:
Your CSS
<style>
body {
counter-reset: section;
}
table tbody tr th::before {
counter-increment: section;
content: "Section " counter(section);
}
table tbody tr th::before {
content: counter(section);
}
</style>
Your Html
<table class="table">
<thead>
<tr>
<th colspan="6">
</th>
</tr>
<tr>
<th scope="col">#</th>
<th scope="col">f1</th>
<th scope="col">f2</th>
<th scope="col">f3</th>
<th scope="col">f4</th>
<th scope="col">f5</th>
</tr>
</thead>
<tbody>
<tr>
<th class="align-middle" scope="row"></th>
<td class="align-middle">d1</td>
<td class="align-middle">d2</td>
<td class="align-middle">d3</td>
</tr>
<tr>
<th class="align-middle" scope="row"></th>
<td class="align-middle">d1</td>
<td class="align-middle">d2</td>
<td class="align-middle">d3</td>
</tr>
</tbody>
</table>

Get the hidden column value in a table on row click

I have a table with four columns. The first two columns are hidden. I want to get the values of the second and third columns on row click. I can get the value of the third column using the below code. But how can I get the value of the hidden column?
$('body').on( 'click','#item-grid table tbody tr', function() {
$('#PurchaseOrder_supplier_name').val($(this).children(':nth-child(3)').text());
});
Below is the table html.
<table class="table table-bordered table-condensed table-hover table-striped dataTable">
<thead>
<tr>
<th id="item-grid_c0" style="display:none">Supplier ID</th>
<th id="item-grid_c1" style="display:none">Supplier ID</th>
<th id="item-grid_c2"><a href="/builders_common/index.php?r=purchase/purchase/multipurchaseorderdetailview&PurchaseOrder%5Bvoucher_no%5D=12&PurchaseOrderDetails%5Bpurchase_voucher_no%5D=12&PurchaseOrderDetails%5Bproject_id%5D=45&PurchaseOrderDetails%5Bitem_id%5D=79&ajax=item-grid&sort=supplier"
class="sort-link">Supplier</a>
</th>
<th id="item-grid_c3"><a href="/builders_common/index.php?r=purchase/purchase/multipurchaseorderdetailview&PurchaseOrder%5Bvoucher_no%5D=12&PurchaseOrderDetails%5Bpurchase_voucher_no%5D=12&PurchaseOrderDetails%5Bproject_id%5D=45&PurchaseOrderDetails%5Bitem_id%5D=79&ajax=item-grid&sort=item"
class="sort-link">Item</a>
</th>
<th id="item-grid_c4"><a href="/builders_common/index.php?r=purchase/purchase/multipurchaseorderdetailview&PurchaseOrder%5Bvoucher_no%5D=12&PurchaseOrderDetails%5Bpurchase_voucher_no%5D=12&PurchaseOrderDetails%5Bproject_id%5D=45&PurchaseOrderDetails%5Bitem_id%5D=79&ajax=item-grid&sort=rate"
class="sort-link">Rate</a>
</th>
</tr>
</thead>
<tbody>
<tr class="odd selected">
<td style="display:none">
<input type="hidden" id="ProjectPurchaseOrderSupplierwise_item_id_5" name="ProjectPurchaseOrderSupplierwise[item_id_5]" value="79" class="gridfield">
</td>
<td style="display:none">
<input type="hidden" id="ProjectPurchaseOrderSupplierwise_supplier_id_5" name="ProjectPurchaseOrderSupplierwise[supplier_id_5]" value="14" class="gridfield">
</td>
<td>General</td>
<td>Cement</td>
<td>
<input type="text" id="ProjectPurchaseOrderSupplierwise_rate_5" name="ProjectPurchaseOrderSupplierwise[rate_5]" value="50.00" readonly="readonly" class="gridfield">
</td>
</tr>
</tbody>
</table>
Try like below.
$('body').on( 'click','#item-grid table tbody tr', function() {
$(this).find('td:eq(1) input').val(); // 2nd column
$(this).find('td:eq(2)').text(); // 3rd column
});
You can use either of the two :eq() Selector or :nth-child() Selector.
https://api.jquery.com/nth-child-selector/
https://api.jquery.com/eq-selector/
Click here
Example code with your HTML
To get a specific cell by index, you can use :
$(this).find('td:nth-child(2) input').val(); // 2nd column
$(this).find('td:eq(1) input').val(); // 2nd column
$(this).find('td:nth-child(3)').text(); // 3rd column
$(this).find('td:eq(2)').text(); // 3rd column
$('#PurchaseOrder_supplier_name').val($(this).children(':nth-child(3):visible').text());

How can I populate a table's cell through JavaScript code?

I have a table as below. I have to populate the "Amount" field using the "Buy Quantity" and "Market Price" field. Amount = Buy Quantity*Market Price. I am doing something as -
<script>
function populate() {
var rows = document.getElementById("mytable").getElementsByTagName("tr");
for ( var i = 1; i <= rows.length; i++) {
cells = rows[i].getElementsByTagName("td");
for ( var j = 0; j <= cells.length; j++) {
if (j == 1) {
var num1 =parseFloat(cells[1].childNodes[0].value);
var num2 =parseFloat(cells[2].childNodes[0].data);
var num3=num1 * num2;
cells[3].childNodes[0].value = num3.toString();
}
}
}
}
</script>
I can get the values of column1 and column2, but the value in last column is not getting populated. The last line does not seem to work.
cells[3].childNodes[0].value = num3.toString();
What should I change?
The below html code is part of my .jsp file.
<form action="BuyServlet">
<table border="1" cellpadding="5" id="mytable">
<tr>
<th>Stock Name</th>
<th>Buy Quantity</th>
<th>Market Price</th>
<th>Amount</th>
</tr>
<tr>
<td>Stock Name</td>
<td><input type="text" name="quantity" onblur="populate()"></td>
<td>122</td>
<td><input type="text" name="amount">
</d>
</tr>
<tr>
<td>Stock Name</td>
<td><input type="text" name="quantity" onblur="populate()"></td>
<td>111</td>
<td><input type="text" name="amount"></td>
</tr>
</table>
</form>
Basically you are getting the value from the text box (best quantity) and you are using data to get the value of the Market price(better use innerText)
try this (Replace with your code inside loop)
var num1 =parseFloat(cells[1].childNodes[0].value);
var num2 =parseFloat(cells[2].innerText);
var num3=num1 * num2;
cells[3].innerText = num3.toString();
Your code is in need of improvement. In your table, you should have a thead and a tbody sections. This will make it more accessible and easier to ingore the heading row.
<table border="1" cellpadding="5" id="mytable">
<thead>
<tr>
<th>Stock Name</th>
<th>Buy Quantity</th>
<th>Market Price</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>Stock Name</td>
<td><input type="text" name="quantity"></td>
<td>122</td>
<td><input type="text" name="amount"></td>
</tr>
<tr>
<td>Stock Name</td>
<td><input type="text" name="quantity"></td>
<td>111</td>
<td><input type="text" name="amount"></td>
</tr>
</tbody>
</table>
</form>
Now with the code, you should be adding the onblur with code, not hardcoded. You are looping through the cells, there is no reason for that. Also there is no need to loop every row when the table is changed. Just calculate the one that changed! Using childNodes can be tricky because of whitespace differences in browsers. Run this code after the table has been rendered.
(function () {
var table = document.getElementById("mytable");
var tbody = table.getElementsByTagName("tbody")[0];
var rows = tbody.getElementsByTagName("tr");​​​​​​​​​
function populateRow (index, addBlurEvent) {
var row = rows[index];
var cells = row.getElementsByTagName("td")
var textboxes = row.getElementsByTagName("input");
var amountTextbox = textboxes[0];
var totalTextbox = textboxes[1];
var costCell = cells[2];
var amount = amountTextbox.value.length>0 ? parseFloat(amountTextbox.value) : 0;
var cost = parseFloat(costCell.innerHTML);
var total = amount * cost;
totalTextbox.value = total;
if (addBlurEvent) {
amountTextbox.onblur = function () { populateRow(index, false); };
}
}
for (i=0;i<rows.length;i++) {
populateRow(i, true);
}
}());
The running fiddle of the above code
​
I think the error is due to spelling mistake - you have childnodes instead of childNodes on "cells[3].childnodes[0].value = num3.toString();"
Check this fiddle - http://jsfiddle.net/VwU7C/

How can I get the corresponding table column (td) from a table header (th)?

I want to get the entire column of a table header.
For example, I want to select the table header "Address" to hide the address column, and select the "Phone" header to show the correspondent column.
<table>
<thead>
<tr>
<th id="name">Name</th>
<th id="address">Address</th>
<th id="address" class='hidden'>Address</th>
</tr>
</thead>
<tbody>
<tr>
<td>Freddy</td>
<td>Nightmare Street</td>
<td class='hidden'>123</td>
</tr>
<tr>
<td>Luis</td>
<td>Lost Street</td>
<td class='hidden'>3456</td>
</tr>
</tbody>
I want to do something like http://www.google.com/finance?q=apl (see the related companies table) (click the "add or remove columns" link)
Something like this would work -
$('th').click(function() {
var index = $(this).index()+1;
$('table td:nth-child(' + index + '),table th:nth-child(' + index + ')').hide()
});
The code above will hide the relevant column if you click on the header, the logic could be changed to suit your requirements though.
Demo - http://jsfiddle.net/LUDWQ/
With a couple simple modifications to your HTML, I'd do something like the following (framework-less JS):
HTML:
<input class="chk" type="checkbox" checked="checked" data-index="0">Name</input>
<input class="chk" type="checkbox" checked="checked" data-index="1">Address</input>
<input class="chk" type="checkbox" checked="checked" data-index="2">Phone</input>
<table id="tbl">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Phone</th>
</tr>
</thead>
<tbody>
<tr>
<td>Freddy</td>
<td>Nightmare Street</td>
<td>123</td>
</tr>
<tr>
<td>Luis</td>
<td>Lost Street</td>
<td>3456</td>
</tr>
</tbody>
Javascript:
var cb = document.getElementsByClassName("chk");
var cbsz = cb.length;
for(var n = 0; n < cbsz ; ++n) {
cb[n].onclick = function(e) {
var idx = e.target.getAttribute("data-index");
toggleColumn(idx);
}
}
function toggleColumn(idx) {
var tbl = document.getElementById("tbl");
var rows = tbl.getElementsByTagName("tr");
var sz = rows.length;
for(var n = 0; n < sz; ++n) {
var el = n == 0 ? rows[n].getElementsByTagName("th")[idx] : rows[n].getElementsByTagName("td")[idx];
el.style.display = el.style.display === "none" ? "table-cell" : "none";
}
}
http://jsfiddle.net/dbrecht/YqUNz/1/
I added the checkboxes as it doesn't make sense to bind the click to the column headers as you won't be able to toggle the visibility, only hide them.
You can do something with CSS, like:
<html>
<head>
<style>
.c1 .c1, .c2 .c2, .c3 .c3{
display:none;
}
</style>
</head>
<body>
<table class="c2 c3">
<thead>
<tr>
<th id="name" class="c1">Name</th>
<th id="address" class="c2">Address</th>
<th id="phone" class="c3">Phone</th>
</tr>
</thead>
<tbody>
<tr>
<td class="c1">Freddy</td>
<td class="c2">Nightmare Street</td>
<td class="c3">123</td>
</tr>
<tr>
<td class="c1">Luis</td>
<td class="c2">Lost Street</td>
<td class="c3">3456</td>
</tr>
</tbody>
</table>
</body>
</html>
To hide a column, you add with Javascript the corresponding class to the table. Here c2 and c3 are hidden.
You could add dynamically the .c1, .c2,... in a style tag, or define a maximum number.
The easiest way to do this would be to add a class to each td that matches the class of the header. When you click the , it checks the class, then hides every td with that class. Since only the s in that column would hide that class, it would effectively hide the column.
<table>
<thead>
<th>Name</th>
<th>Address</th>
</thead>
<tbody>
<tr>
<td class="Name">Joe</td>
<td class="Address">123 Main St.
</tbody>
</table>
And the script something like:
$('th').click( function() {
var col = $(this).html(); // Get the content of the <th>
$('.'+col).hide(); // Hide everything with a class that matches the col value.
});
Something like that, anyway. That's probably more verbose than it needs to be, but it should demonstrate the principle.
Another way would be to simply count how many columns over the in question is, and then loop through each row and hide the td that is also that many columns over. For instance, if you want to hide the Address column and it is column #3 (index 2), then you would loop through each row and hide the third (index 2).
Good luck..
Simulating the Google Finance show/hide columns functionality:
http://jsfiddle.net/b9chris/HvA4s/
$('#edit').click(function() {
var headers = $('#table th').map(function() {
var th = $(this);
return {
text: th.text(),
shown: th.css('display') != 'none'
};
});
var h = ['<div id=tableEditor><button id=done>Done</button><table><thead><tr>'];
$.each(headers, function() {
h.push('<th><input type=checkbox',
(this.shown ? ' checked ' : ' '),
'/> ',
this.text,
'</th>');
});
h.push('</tr></thead></table></div>');
$('body').append(h.join(''));
$('#done').click(function() {
var showHeaders = $('#tableEditor input').map(function() { return this.checked; });
$.each(showHeaders, function(i, show) {
var cssIndex = i + 1;
var tags = $('#table th:nth-child(' + cssIndex + '), #table td:nth-child(' + cssIndex + ')');
if (show)
tags.show();
else
tags.hide();
});
$('#tableEditor').remove();
return false;
});
return false;
});
jQuery('thead td').click( function () {
var th_index = jQuery(this).index();
jQuery('#my_table tbody tr').each(
function(index) {
jQuery(this).children('td:eq(' + th_index + ');').each(
function(index) {
// do stuff here
}
);
}
);
});
here's a working fiddle of this behaviour:
http://jsfiddle.net/tycRW/
of course, hiding the column with out hiding the header for it will have some strange results.

Categories