The issue I'm having is when I try to update the remaining rows in a table .outerHTML so that the name attributes are sequential. It's necessary as the .net backend expects the array to start at zero and be sequential.
If you have more than one row with entries, then delete a row, when updating the outerHTML the DOM values are removed and everything resets to blank. Is there a way to retain the values entered? It works fine not updating the outerHTML but that won't work for the backend.
https://jsfiddle.net/y2dxus1m/
function addBenefit() {
//gets the table and adds a new row based on length
var tableRef = document.getElementById('benefitsField').getElementsByTagName('tbody')[0];
var myHtmlContent = '<td><input name="Octopus.Newborns.ReceivingBenefits[' + tableRef.rows.length + '].FirstName"></td><td><input name="Octopus.Newborns.ReceivingBenefits[' + tableRef.rows.length + '].LastName"></td><td><input name="Octopus.Newborns.ReceivingBenefits[' + tableRef.rows.length + '].Amount"></td><td><input name="Octopus.Newborns.ReceivingBenefits[' + tableRef.rows.length + '].Source"></td><td><button class="btn btn-primary btn-sm" onclick="removeRow(this)">Remove</button></td>';
var newRow = tableRef.insertRow(tableRef.rows.length);
newRow.innerHTML = myHtmlContent;
}
function removeRow(a) {
var row = a.parentNode.parentNode;
row.parentNode.removeChild(row);
var tableRef = document.getElementById('benefitsField').getElementsByTagName('tbody')[0];
for (var i = 0; i < tableRef.rows.length; i++) {
console.log(tableRef.rows[i].outerHTML)
//Issue is here ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tableRef.rows[i].outerHTML = tableRef.rows[i].outerHTML.replace(/(\[).+?(\])/g, "[" + i + "]");
console.log(tableRef.rows[i].outerHTML)
}
}
<table class="deptTable" id="benefitsField">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Weekly Benefit Amount</th>
<th>Source</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td><input name="Octopus.Newborns.ReceivingBenefits[0].FirstName" /></td>
<td><input name="Octopus.Newborns.ReceivingBenefits[0].LastName" /></td>
<td><input name="Octopus.Newborns.ReceivingBenefits[0].Amount" /></td>
<td><input name="Octopus.Newborns.ReceivingBenefits[0].Source" /></td>
<td><button class="btn btn-primary btn-sm" onclick="removeRow(this)">Remove</button></td>
</tr>
</tbody>
</table>
<button onclick="addBenefit()">Add</button>
Adding the following function to reset the table rows after a row was removed resolved the issue. Fiddle updated
function setIndex() { $("td.index").each(function (index) { $(this).text(++index); }); }
Related
i'm trying to do calculation with my table using java-script, but i don't know how to loop it with the rest of the id. right now i can only calculate single item how to make this multiple here is the result
as you can see only id 1 get the result while id 2 is null how can i make this work here is my java script
function calc(){
var n1 = parseFloat(document.getElementById('n1').value);
var n2 = parseFloat(document.getElementById('n2').value);
var oper = document.getElementById('result').value = n1*4+n2;
}
<table id="my-table" class="table table-hover table-bordered">
<thead>
<tr >
<th class="text">NAME</th>
<th class="text">A/P</th>
<th class="text">H/W</th>
<th class="text">Result</th>
</tr>
</thead>
<tbody>
#foreach($scores as $index => $score)
<tr>
<td>{{$score->lead->student_name}} <input type="hidden" name="scores[{{$loop->index}}][id]" value="{{$score->id}}"></td>
<td style="text-align:center"><input id="n1" type="text" name="scores[{{$loop->index}}][jan_ap]" value="{{$score->jan_ap}}" class="input" autocomplete="off"></td>
<td style="text-align:center"><input id="n2" type="text" name="scores[{{$loop->index}}][jan_hm]" value="{{$score->jan_hm}}" class="input" autocomplete="off"></td>
<td style="text-align:center"><input id="result" type="text" name="scores[{{$loop->index}}][result]" value="{{$score->result}}" class="input" autocomplete="off"></td>
</tr>
#endforeach
</tbody>
</table><div class="form-group ">
<button onclick="calc(); " type="submit">Submit</button>
</div>
From chat discussion and your controller code it found that, you want to add row with some formula and save the result in results field in database. So here we come up with code
Controller save method
$scores = $request->input('scores');
foreach($scores as $row){
$score = Score::find($row['id']);
$score->jan_ap = $row['jan_ap'];
$score->jan_hm = $row['jan_hm'];
$score->result = round($row['jan_ap'] * 0.5) + ($row['result'] * 0.5);
$score->save();
}
Note: Remove your result text input fro blade template because it is not used anymore.
I am answering this with some assumptions that I will make, since its not really clear from the question.
Assumption 1:
You have this table rendered using blade that gets Data from somewhere:
<div id="myTabDiv">
<table name="mytab" id="mytab1">
<tr>
<td>col1 Val1 (has ID)</td>
<td>col2 Val2 (has jan_ap)</td>
<td>col3 Val3 (has jan_hm)</td>
<td>col4 Val4 (has result)</td>
</tr>
<tr>
<td>col1 Val1 (has ID)</td>
<td>col2 Val2 (has jan_ap)</td>
<td>col3 Val3 (has jan_hm)</td>
<td>col4 Val4 (has result)</td>
</tr>
Assumption 2: Yo have populated col 1-3 with values but you have a magical button, that when clicked calculates col4. Said button uses a JS function.
function calc(){
var table = document.getElementById("mytab1");
for (var i = 0, row; row = table.rows[i]; i++) {
//iterate through rows
//rows would be accessed using the "row" variable assigned in the for loop
for (var j = 0, col; col = row.cells[j]; j++) {
//iterate through columns
//columns would be accessed using the "col" variable assigned in the for loop
//here you can do things like saying sum col[1] + col[2] and then input result in col[3]
}
}
}
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>
I have a form in php with dynamically added rows (after clicking button the row is added). I want to fill the field with value "xx" and i want to do it in jquery.
This loop create the dynamically added rows in jquery. I want to fill added fields with value "xx":
while($personsArrayLength>2){
echo '
<script>
$(document).ready(function(){
var i = 2;
var rowTemplate2 = jQuery.format($("#template2").html());
rowTemplate2.value = "xx";
addRow2();
function addRow2(){
var ii = i++;
$("#app_here2").append(rowTemplate2(ii));
$("#delete_" + ii).click(function(){
$("#row_" + ii).remove();
});
}
});
</script>
';
Here is html for that:
function addRows2(){
global $personsError_css;
$personsArray = $_POST['persons'];
JB_var_dump($_POST['whichRow']);
$html = '<table id="template2" align="right" style="display:none; ">
<tr id="row_{0}">
<td><input type="text" size="52" id="persons" name="persons[]" maxlength="100"></td>
<td><img src="/../_img/row_del.png" id="delete_{0}" alt="usun"></td>
</tr>
</table>
<table id="list2" style="margin-left:200px;">
<thead >
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" size="52" name="persons[]" maxlength="100" style="'.$personsError_css.';" value="'.$personsArray[1].'"></td>
<td></td>
</tr>
<tr>
<td colspan="2" id="app_here2"></td>
</tr>
</tbody>
</table>';
return $html;
}
This is properly filled form
In this epty fields I want to add values "xx"
Sorry for my english.
How can i set values in added rows? What i should change in my code?
Thanks for help.
Change your 'addRow2' to this:
function addRow2(){
var ii = i++;
$("#app_here2").append(rowTemplate2(ii));
//UPDATE: var rowTemplate2 is not a jQuery Object, as i thought
$("#template2").find("input:empty").val("xx");; // added this row
$("#delete_" + ii).click(function(){
$("#row_" + ii).remove();
});
}
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/
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.