Select specific table cell in JavaScript - javascript

I have a HTML like this:
<table id="laboral">
<tr>
<td><input type="text" name="start"/></td>
<td><input type="text" name="end"/></td>
<td><textarea name="desc"></textarea></td>
<td><button type="button" onclick="saveValues(this);createRow('laboral')"> + </button></td>
</tr>
</table>
What I want is to save the values in the three cells (2 inputs and 1 textarea).
The button creates another row just like the first, with the same inputs and names. The problem is that I don't know how to access THIS row, I mean, the row who owns the button.
I tried with this.parentNode.parentNode but didn't work.

Try this
<table id="laboral">
<tr>
<td><input type="text" name="start"/></td>
<td><input type="text" name="end"/></td>
<td><textarea name="desc"></textarea></td>
<td><button type="button" onclick="saveValues(this)"> + </button></td>
</tr>
</table>
var inputVals = [];
function saveValues(elm) {
// button td tr tbody table
var table = elm.parentNode.parentNode.parentNode.parentNode;
// iterating through the first row cells
for (var i = 0; i<table.rows[0].cells.length-1; i++) {
// the current cell
var cell = table.rows[0].cells[i];
// pushing the input elm's value into the array
inputVals.push(cell.childNodes[0].value);
// retrieving the pushed value
alert(inputVals[i]);
}
}
Fiddle example
You can modify the code.

You're passing a reference to the button into saveValues, so within saveValues the first argument will refer to the button. Let's call that argument btn. btn.parentNode will be the td containing the button, and `btn.parentNode.parentNode will be the tr containing that td. So:
function saveValues(btn) {
var tr = btn.parentNode.parentNode;
// Work with `childNodes` and the `childNodes` of those children to get the values
}

Related

Accessing an individual column in a row which is selected by default with a radio button on page load

With the code below, I am trying to access a particular column "quantity" from a row in a table. What is happening is one of the rows is selected by default when page loads while the rest of the rows can be selected when user chooses. I created a click event handler to handle manual selection.
When accessing the column with a class name, it returns nothing. I need to assign this value to an input box in the same form. I would attach the image of the row
Table Markup:
<tr valign="top" class="row6">
<td>
{if $tpl_order_details[lineitems].quantity > 1}
{if $radio_flag == "false"}
<input type="radio" name="line_item" class="radio_class" id="line_item" value="{$tpl_order_details[lineitems].mSku}" checked onclick="handleClick(this);"/>
{assign var=radio_flag value='true'}
{else}
<input type="radio" name="line_item" class="radio_class" id="line_item" value="{$tpl_order_details[lineitems].mSku}" onclick="handleClick(this);" />
{/if}
{/if}
</td>
<td>
{$tpl_order_details[lineitems].sku}
</td>
<td>
</td>
<td>{$tpl_order_details[lineitems].item_description}</td>
<td class="quantity_class" >{$tpl_order_details[lineitems].quantity}</td>
<td>{$tpl_order_details[lineitems].item_status}</td>
Markup with the Input field outside the loop:
<table>
<tr>
<td><label for="new_quantity">Enter New Quantity</label></td>
<td><input type="number" id="split_quantity" name="split_quantity"
min="1" max="6"></td>
<td><button type="submit" value="Save"
name="submit_action">Submit</button></td>
<td><button type="submit" value="Cancel"
name="submit_action">Cancel</button></td>
</tr>
</table>
JavaScript:
// This is to handle the radio button selected by default on page load.
$( document ).ready(function() {
var firstRadioValue = 0;
firstRadioValue = $("input[name='line_item']:checked").val();
$('input[name="split_quantity"]').attr('max', firstRadioValue);
var quantity = $(".radio_class").parent().find(".quantity_class").val();
alert(quantity);
});
// This is to handle the radio button that user actually chooses.
var currentRadioValue = 0;
function handleClick(line_item) {
alert('New value: ' + line_item.value);
currentRadioValue = line_item.value;
$('input[name="split_quantity"]').attr('max', currentRadioValue);
}
You're not going far enough up the tree to find the class. You have:
var quantity = $(".radio_class").parent().find(".quantity_class").val();
which gets you to the parent <td> The element you're looking for is a sibling of this:
<td class="quantity_class" >...
What you want to do is go one element higher (the table row), then find the class you're looking for from there, so use closest(). Note that .quantity_class doesn't have a value so you have to get the text in the table cell:
var quantity = $(".radio_class").closest('tr').find(".quantity_class").text();
In addition, I do not see any markup with the max attribute or any markup with the name of split_quantity.
EDIT - based on a conversation with the user it was found that there needed to be a number of changes. First, the table holding split_quantity needed to be identified so it could be targeted in the grander markup:
<table id="split_quantity_id">
<tr>
<td><label for="new_quantity">Enter New Quantity</label></td>
<td><input type="number" id="split_quantity" name="split_quantity" min="1" max="6"></td>
<td><button type="submit" value="Save" name="submit_action">Submit</button></td>
<td><button type="submit" value="Cancel" name="submit_action">Cancel</button></td>
</tr>
</table>
Then we got rid of the onclick="handleClick(this) inline JavaScript in favor of letting jQuery handle the click event. Finally we refactored the functions:
$(function() {
var firstRadioValue = 0;
firstRadioValue = $("input[name='line_item']:checked").closest('tr').find('.quantity_class').text();
$('input[name="split_quantity"]').attr('max', firstRadioValue);
var quantity = $(".radio_class").closest('tr').find(".quantity_class").text();
console.log(quantity);
$('table').delegate('.line_item', 'click', function(){
currentRadioValue = $(this).closest('tr').find('.quantity_class').text();
console.log(currentRadioValue);
$('#split_quantity_id').find('[name="split_quantity"]').attr('max', currentRadioValue);
});
});
NOTE: It was also discovered that the OP is using Smarty 2 which is an older version of Smarty using an older version of jQuery, so .delegate() is used instead of on().

can't print a variable in a table from json recordset

I have a Json recordset, that is working perfectly, however so far I can't sort out how to place a value of the json array into an specific cell of a table.
this is my function that looks for the form and start printing the values but only if there is an input component inside the table
function process_response(response) {
var frm = document.getElementById("form-ajax");
var i;
console.dir(response); // for debug
for (i in response) {
if (i in frm.elements) {
frm.elements[i].value = response[i];
}
}
}
and this is table
form id="form-ajax" action="form-ajax.php">
<table class="table">
<thead>
<tr>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" id="name" name="ID" maxlength="12" size="12"></td>
<th scope="row"><input type="submit" value="1" /></th>
<td></td>
this is the place where I want to the resultset without the need of place a input
if I place something like this.
<td><input type="text" name="1" /></td>
then the javascript works and it reads whatever is in the json name with 1.
but if I do something like this.
<td name="1"></td>
then nothing prints out.
Whatever I do different than place an input type="text" then the Function doesn't work.
I need to populate the table with an specific order from the json .
TDs are not part of a form and do not have value or name attributes
You could do
var tds = document.querySelectorAll("td[name]");
for (var i=0;i<tds.length;i++) {
tds[i].innerText=response[tds[i].getAttribute("name")];
}
assuming the name attribute matches the response key
You also likely do not want to have a submit button but a type="button"
I figure out a way to print an specific value inside the table ...
var s = document.getElementById("so");
s.innerHTML =response['sort'];
this way I force td component with ID="SO" to print the value I passed over the json file.
<td id="so"></td>

How to fix given row to avoid delete using .remove function

I created a table where in can add and remove dynamically. I just have a little problem where it comes to deleting a row. I want my first row to be fixed because when I used remove() it deletes the row that I given.
Table:
<div class = "col-md-12">
<table class = "table" id = "customFields">
<thead>
<tr>
<th>Stock No.</th>
<th>Unit</th>
<th>Description</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" class="form-control"></td>
<td><input type="text" class="form-control"></td>
<td><input type="text" class="form-control"></td>
<td><input type="text" class="form-control"></td>
</tr>
</tbody>
</table>
<button type = "submit" class = "btn btn-primary" id = "addMore">+ Add</button>
<button type = "submit" class = "btn btn-danger" id = "removeRow">- Remove</button>
</div>
Script:
<script>
$(document).ready(function ()
{
$("#addMore").click(function ()
{
$("#customFields").append('<tr><td><input type="text" class="form-control"></td><td><input type="text" class="form-control"></td><td><input type="text" class="form-control"></td><td><input type="text" class="form-control"></td></tr>');
});
$("#removeRow").click(function()
{
$('#customFields td:last').remove();
});
});
</script>
I used last function to delete the row but this only delete one textfield. How can I delete this by 4? Any help would appreciated!!
tr represents the row and td represent the row's single cell.
You should read and explore about HTML tables
$('#customFields tr:last').remove();
Working Demo
and to keep first row always , Count the tr length , and do the delete operation
$("#removeRow").click(function()
{ if($('#customFields tbody tr').length== 1){
// only one row left
alert("Cant delete first row")
}else
{
$('#customFields tr:last').remove();
}
});
And Since your thead has a tr too . So delete using this selection
$('#customFields tbody tr:last').remove();
it will delete tr from tbody only
you should select last row, instead of last table data(td). I mean in $('#customFields td:last').remove(); statement, instead of using td:last , please use tr:last.
i fixed it in this fiddle

Having incremental order ids for tr in tables after deleting rows too

I have table with following format
<table>
<tr>
<td>
<input type="hidden" name="help[0].id" />
</td>
<td> <span class="tr-close">X</span>
</tr>
<tr>
<td>
<input type="hidden" name="help[1].id" />
</td>
<td> <span class="tr-close">X</span>
</tr>
<tr>
<td>
<input type="hidden" name="help[2].id" />
</td>
<td> <span class="tr-close">X</span>
</tr>
</table>
Now I have Add button which will add row to the end of table. On clicking X icon I am deleting the entire row. Suppose if I delete row with name help[1].id, Now if I again add the new row, it should have help[1].id..So, on each addition/deletion the name should have differenct incrementatal non repeating numbers like id's 0,1,2,3....
After deleting the row, you can loop through each hidden field to update the name attribute. You can use .each() for looping. use .attr() method to update the name attribute
$(".tr-close").click(function(){
$(this).parents("tr").remove();
$("input[type=hidden]").each(function(i){
$(this).attr("name","help["+i+"]");
});
});
Demo
I think you can use a "Heap" data structure to maintain the smallest number of your deleted index. Pick from the Heap when you add a new row.
RemoveRow ->
Insert index to Heap
AddRow ->
if Heap is empty:
Index = Rows.length
else:
Index = top of heap
remove top of heap
You can do it like this
//In order to have the dynamically created rows to have the
//delete function also you can use you on() like this
$('table').on('click', '.tr-close', function(){
$(this).parents('tr').remove();
});
// the #add refers to the add button you use
$('#add').click(function(){
var counter = 0;
$('table')
.append('<tr><td><input type="hidden" name=""/></td><td> <span class="tr-close">X</span></td></tr>');
$('tr').each(function(){
$(this).find('input').prop('name', 'help[' + counter + '].id');
counter++;
});
});

How to add row in html table on top of specific row?

I have a table, and each row has a button to add a new row on top of it. Each row has new inputs.
I know how to add a row on top of the table, but not on top of each row that I'm clicking on the button. Would anyone have a tip on how to solve it? I might be able to do it, but the solution I see is very complicated, and I'm sure there must be a smarter solution.
Oh, also I don't know how to update the parameter sent in the insertNewRow(id) function.
So far this is what I have:
<script type="text/javascript">
function insertNewRow(id){
var row = document.getElementById("bottomRow");
var newrow = row.cloneNode(true);
console.log(newrow);
var newInputs = newrow.getElementsByTagName('input');
var allRows = row.parentNode.getElementsByTagName('tr');
row.parentNode.insertBefore(newrow, row);
var i=row.rowIndex;
console.log(i);
}
</script>
<table id="myTable">
<tr>
<td>Title1:</td>
<td></td>
<td>Title2:</td>
<td></td>
<td>Title3:</td>
<td></td>
<td></td>
</tr>
<tr>
<td><input class="c1" readonly maxlength="9" size="7" id="gTop" type="text" value ="11"></td>
<td> <-></td>
<td id="l1"><input class="c2" style="width:35px;" maxlength="9" size="7" type="text" id="lTop" value="33"></td>
<td>=</td>
<td id="rv1"><input id="rvTop" input class="c2" style="width:105px;" maxlength="100" size="37" type="text" value="blahblahblah"></td>
<td></td>
<td>x</td>
</tr>
<tr id="bottomRow">
<td><input class="c1" readonly maxlength="9" size="7" id="gBottom" type="text" value =""></td>
<td> </td>
<td id="l1"><input class="c2" style="width:35px;" maxlength="9" size="7" type="text" id="lBottom" value="11"></td>
<td>=</td>
<td id="rv1"><input id="rvBottom" input class="c2" style="width:105px;" maxlength="100" size="37" type="text" value="blahblahblah"></td>
<td><button type="button" onclick="insertNewRow(1)">+</button></td>
<td>x</td>
</tr>
</table>
In the onclick attribute, instead of just calling insertNewRow(), do something like
insertNewRow.apply(this);
The this keyword inside the onclick attribute is a reference of the clicked element. With insertNewRow.apply(this), we'll be calling insertNewRow() and at the same time, assign the this keyword inside that function call to the clicked element or in this case, the button (if we don't do that, this inside insertNewRow() will be a reference to the Window object instead). Then in, your insertNewRow() function, check if the current element being clicked on is a tr element. If not, go up by one level and see if that element is a tr element. Keep doing that until you get to the first tr element. So, basically you'll be searching for the closest tr element.
<button type="button" onclick="insertNewRow.apply(this);">+</button>
function insertNewRow(){
var row = null,
el = this;
// Get the closest tr element
while (row === null)
{
if (el.tagName.toLowerCase() === 'tr')
{
row = el; // row is now the closest tr element
break;
}
el = el.parentNode;
}
// Rest of the code here
}​
JsFiddle
If you're still not sure what Function.apply() is, take a look at the documentation here.

Categories