How to append new rows to a table more than once? - javascript

I have a table within a form that I want to append new rows as the user enters input in the last row of the table.
$('table.form-table').on('input', function() {
var tableID = '#' + $(this).closest('table').attr('id');
if(jQuery(this).closest('tr').is(':last-child')) {
var currTR = $(this).closest('tr');
var currTRhtml = '<tr>' + currTR.html() + '</tr>';
var nextRow = jQuery(currTRhtml);
var checkBox = jQuery('<td class="border-right checks"><input type="checkbox" name="del_000" value="000"></td>');
jQuery(tableID).append(nextRow);
checkBox.appendTo(currTR);
}
});
And the html code if needed (simplified/trimmed):
<table class="form-table" id="XXX" border="1" cellspacing="0" cellpadding="3">
<thead>
<tr class="main"><th nowrap colspan="3" align="left"
class="border-left border-top border-right">
<h3>XXX</h3></th>
</tr>
<tr>
<th>header</th>
</tr>
</thead>
<tbody>
<tr>
<input type="hidden" name="isnew" value="">
<td >
<input type="text"
name="new_text"
value="">
</td>
</tr>
</tbody>
</table>
The problem is that this works only once and does not continue appending new rows. It's as if the last-child filtering does not get reset...
Any thoughts?

The problem is that you need to use the event's target, rather than "this". Right now "this" refers to the current table, but you need to refer to the current input box and then use closest() to find its parent tr (and :first-child to make sure it's the last one). So your code needs to look more like this:
$('table.form-table').on('input', function(e) {
var tableID = '#' + $(this).closest('table').attr('id');
if ($(e.target).closest('tr').is(':last-child')) {
var currTR = $(e.target).closest('tr');
var currTRhtml = '<tr>' + currTR.html() + '</tr>';
var nextRow = $(currTRhtml);
var checkBox = $('<td class="border-right checks"><input type="checkbox" name="del_000" value="000"></td>');
$(tableID).append(nextRow);
checkBox.appendTo(currTR);
}
});
Notice I'm passing the event as "e" and then referencing the current input box with $(e.target).
Here's a working JS fiddle.

I suspect the problem is that you need to delegate the input event as the appended rows do not exist on $(document).ready(). Try doing something like this to delegate the handler:
$(document).ready(function () {
$('table.form-table tbody').on('input', 'tr', function () {
var self = $(this),
tableID = '#' + self.closest('table').attr('id'),
currTR = self.closest('tr'),
currTRhtml = '<tr>' + currTR.html() + '</tr>',
nextRow = $(currTRhtml),
checkBox = $('<td class="border-right checks"><input type="checkbox" name="del_000" value="000"></td>');
if (currTR.is(':last-child')) {
$(tableID).append(nextRow);
checkBox.appendTo(currTR);
}
});
});
Fiddle: http://jsfiddle.net/KW7ET/

Related

jQuery Datatable, editing selected rows data with html text boxes

I'm fairly new to coding. I have a jQuery datatable, and when I select a row, the tds of that row fill out html textboxes above the table. I'm trying to make it so whatever is entered into those textboxes (and upon pressing the save button), is then saved into the row.
Currently I have it so it saves 1 field/td. If I press on column 0, fill out the Name textbox and press save, it saves. But it works on any column. It should only be editing the correct td. Plus I want to edit the entire row, not just one td. I'm not sure how to accomplish this. Thanks for any help!
JSFiddle
Javascript:
var table = $('#example').DataTable();
(function () {
var table = document.querySelector('#example');
var name = document.querySelector('#nameinput');
var format = document.querySelector('#formatinput');
var address = document.querySelector('#addressinput');
var report = document.querySelector('#reportinput');
var alarm = document.querySelector('#alarminput');
table.addEventListener('click', onTableClick);
function onTableClick (e) {
var tr = e.target.parentElement;
var data = [];
for (var td of tr.children) {
data.push(td.innerHTML);
}
name.value = data[0];
address.value = data[1];
format.value = data[2];
report.value = data[3];
alarm.value = data[4];
console.log(alarm.value);
}
$("#saverow").click(function() {
var table1 = $('#data-table').DataTable();
var data = [];
data[0] = name.value;
data[4] = alarm.value;
console.log(name.value);
console.log(alarm.value);
table1.draw(true);
});
})();`
I've updated my code with what I've tried so far. Currently, what I type in the textboxes, correctly is displayed in the console (upon hitting the saverow button), now I cant figure out how to save that into the table.
i think it is mor responsive to edit data right in the table.
HTML:
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Format</th>
<th>Report Time</th>
<th>Alarms</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>Tiger#gmail.com</td>
<td>email</td>
<td>1PM</td>
<td>Master</td>
<td class="td-button"></td>
</tr>
<tr>
<td>Bill Gates</td>
<td>111-111-1111</td>
<td>sms</td>
<td></td>
<td>Master</td>
<td class="td-button"></td>
</tr>
</tbody>
</table>
JS:
var table = $('#example').DataTable();
$("#example tbody tr").click(function(){
if (! $(this).find("button").length)
{
$(this).find("td").each(function(){
if (!$(this).hasClass("td-button"))
{
var text = $(this).text();
$(this).html ('<input type="text" value="' + text + '">')
} else
$(this).html ('<button class="button-save">Save</button>')
})
}
})
$(document).on("click", ".button-save",function(){
var tr = $(this).parent().parent();
tr.find("td").each(function(){
if (!$(this).hasClass("td-button"))
{
var text = $(this).find("input").val();
$(this).text(text)
} else
$(this).html('');
})
})
https://jsfiddle.net/91wvw619/

jqueryUI datepicker without document.ready function

To create jquery datepicker, we use the following function
$( function() {
$( "#datepicker" ).datepicker();
} );
<input type="text" id="datepicker">
I am trying to achieve a in-line editing functionality with a new record function as below
function createRowForAdd(){
var tRow = "<tr>"
for(var i = 0; i < array.length; i++){
var jsonObj = array[i];
tRow +="<td><input type='text' id='"+jsonObj.id+"' /></td>"
}
tRow += "</tr>";
return tRow;
}
function Add(){
var tRow = createRowForAdd();
$("#tblId tbody").append(tRow);
}
<button id="btnAdd" onclick="javascript:Add()">New</button>
<table id="tblId" border="1">
<thead>
<tr>
<th>Name</th>
<th>Birth Date</th>
<th>Joining Date</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
One or more columns may contain a date field. For those column(s), I would like to show a date picker. As I understand, document.ready function gets triggered once the DOM is ready. Is it possible to initiate a date picker on row add?
.datepicker() function just needs that the element is in the DOM, so you can execute it after you add the row without problems, applying your desired selector for that input fields.
About the selector, considering that you're going to have multiple datapicker inputs, avoid using the same id (id's are designed to be unique in the DOM). You better use a class instead.
function Add() {
var tRow = createRowForAdd();
$("#tblId tbody").append(tRow);
// When creating the row, set class="datepicker" the inputs of the row that
// has to be converted to a datetime picker. Then you just have to do this...
$("input.datepicker").datepicker();
}
Or even better, apply it only to the inputs from the new added row (the last one)...
function Add() {
$("#tblId tbody").append(createRowForAdd()).find('tr:last input.datepicker').datepicker();
}
EDITED: I can't see the value of your array variable, but looking at your code it looks like all the inputs of the same column will have the same id. As I mention earlier, avoid that because id's are designed to be unique in the DOM. If you need an id, you can use the row number to change the input for every id. Here you have an example with that idea...
HTML:
<button id="btnAdd">New</button>
<table id="tblId" border="1">
<thead>
<tr>
<th>Name</th>
<th>Birth Date</th>
<th>Joining Date</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
JQUERY:
// I'm making up the content of this array. The question doesn't show it.
var array = [
{ 'id': 'name', 'class': '' },
{ 'id': 'birthdate', 'class': 'datepicker' },
{ 'id': 'joiningdate', 'class': 'datepicker' },
{ 'id': 'something', 'class': '' }
];
function createRowForAdd(rowPos) {
var tRow = [];
for (var i=0, l=array.length; i<l; i++)
tRow.push('<td><input type="text" id="'+array[i].id+rowPos+'" class="'+array[i].class+'" /></td>');
return '<tr>' + tRow.join('') + '</tr>';
}
$('button#btnAdd').click(function() {
var rowPos = $("table#tblId tbody tr").length;
$("table#tblId tbody").append(createRowForAdd(rowPos)).find('tr:last input.datepicker').datepicker();
});
And the fiddle... https://fiddle.jshell.net/rigobauer/tpxnvpy4/
I hope it helps

jquery efficient way to select tablerow data

I have a table with multiple rows of the same pattern:
<tr role="row" class="even">
<td><input type="checkbox" id="valj4"></td>
<td>Generell grupp</td>
<td>IKT Ipad11- Mirko</td>
<td>Grundinställningar</td>
</tr>
Each row has a checkbox with unique ID, what would be the most efficient way to get a list of UUIDs for the rows with a checked checkbox. I would like to use jQuery.
$(function() {
var texts = [];
$('tr td:has(input:checkbox:checked) ~ td > a').each(function(i, e) {
texts.push($(e).attr('href'));
});
$('#result').html(texts.join('<br/>'));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr role="row" class="even">
<td>
<input type="checkbox" id="valj4" checked>
</td>
<td>Generell grupp</td>
<td>IKT Ipad11- Mirko (...5)
</td>
<td>Grundinställningar</td>
</tr>
<tr role="row" class="even">
<td>
<input type="checkbox" id="valj4">
</td>
<td>Generell grupp</td>
<td>IKT Ipad11- Mirko (...6)
</td>
<td>Grundinställningar</td>
</tr>
<tr role="row" class="even">
<td>
<input type="checkbox" id="valj4" checked>
</td>
<td>Generell grupp</td>
<td>IKT Ipad11- Mirko (...7)
</td>
<td>Grundinställningar</td>
</tr>
</table>
<div id="result"/>
Getting the UUID is then an easy exercise in string chopping.
I assume your table has an id and it's "#table-id":
$("#table-id").find(":checked")
would get you all the checked checkboxes and radio boxes.
$("#table-id").find("input[type='checkbox']:checked")
would get you all the checked checkboxes.
var ids = "";
$("#table-id").find("input[type='checkbox']:checked").each(function(){
ids += $(this).attr("id") + ",";
});
would give you a comma seperated list containing the ids of checked checkboxes in the table.
and the UUIDS list:
var UUIDs = "";
$("#table-id").find("input[type='checkbox']:checked").each(function(){
var href = $(this).closest("tr").find("td > a").first().attr("href");
var UUID = href.split('?')[1];
UUIDS += UUID + ",";
});
I would try the following
var ids = [];
$("#table input:checkbox:checked").each(function () {
var uuid = getParameter($(this).closest('tr').find('a').eq(0).attr('href'))
ids.push(uuid);
});
function getParameter(url) {
var regex = new RegExp("[\\?&]uuid=([^&#]*)"),
results = regex.exec(url);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
where #table is the id of your table
Example
jQuery('#formId').find('tr[class=even]').each(function () {
var rowId = "";
this.find('input[type=checkbox]').each(function() {
if(this.checked) {
rowId = "row" + $(this).val();
}
});
$(this).attr('id', rowId);
});
Create a new list of UUIDs.
var listOfUUIDs = [];
Get the checked input, go up to grandparent (the tr), then find the a inside it.
Go through the list of a's, adding UUIDs to the list.
$("tr input[checked=checked]").parent().parent().find("td a").each(function(){
listOfUUIDs.push(
$(this).prop('href').substr(indexOf("uuid=") + 5)
)
});
This should give you what you need.
$('tr').each(function(index) {
var $this = $(this),
input = $this.find('input'),
result = '';
if ( input.is(':checked') ) {
var uuid = $this.find('a').attr('href').replace(/^\/Home\/DeviceDetails\?uuid=/g, ""),
result = result + index + '. ' + input.attr('id') + ' has the uuid: ' + uuid + '<br />';
}
$('#result').html(result);
});
try this
$( "input[type=checkbox]" ).change(function() {
if($(this).is(":checked")) {
alert($(this).attr("id"));
}
});

JavaScript remove dynamically created tr

I have a js function that adds a tr to a table:
function AddData() {
var rows = "";
var product_id = $('input[name="product_name"]').val();
var product_price = $('input[name="product_price"]').val();
rows += "<td><input type='hidden' name='item_id[]' value='" + product_id + "'><p>" + name + "</p></td><td><input type='hidden' name='price[]' value='" + product_price + "' class='price'></td><td>£<span id='amount' class='amount'>0</span></td><td><div class='btn btn-circle' onclick='RemoveData()' value='" + curtainid + "'>Delete</div></td>";
var tbody = document.querySelector("#myTable tbody");
var tr = document.createElement("tr");
tr.innerHTML = rows;
tbody.appendChild(tr)
update_amounts();
}
Within the <td> is a RemoveData() call. I want this to remove the selected tr from the table. I have tried to use:
function RemoveData() {
var elements = document.getElementById('tr');
last = elements[elements.length-1];
last.parentNode.removeChild(last);
}
but with no success.
getElementById gets a single element, by its id. You're passing in a tag name and expecting it to return a list.
If your goal is to remove the last tr element anywhere on the page, you can use querySelectorAll instead:
function RemoveData() {
var elements = document.querySelectorAll('tr'); // <== Main change
var last = elements[elements.length-1]; // <== Note I added `var`
last.parentNode.removeChild(last);
}
querySelectorAll works on all modern browsers, and IE8.
I added var to the last line because your code was falling prey to The Horror of Implicit Globals without it.
Re your comment below:
How would I remove a selected element...
I'd probably have a single event handler on the table and then trigger removal based on the event's target (e.g., delegated handling). That looks something like this:
"use strict";
var tbody = document.getElementById("the-tbody");
// Add rows when the button is clicked
document.getElementById("btn-add").addEventListener("click", addRow, false);
function addRow(e) {
var row = document.createElement('tr');
row.innerHTML = '<td>Hi there ' +
Math.floor(Math.random() * 1000) +
' <span class="remove">[x]</span></td>';
tbody.appendChild(row);
}
// Remove rows when their ".remove" span is clicked
tbody.addEventListener("click", removeRow, false);
function removeRow(e) {
var elm;
for (elm = e.target; elm !== this; elm = elm.parentNode) {
if (/\bremove\b/.test(elm.className)) { // On modern browsers you could use `classList`
// It's a remove link, remove its parent tr and we're done
removeElement(elm.parentNode);
e.stopPropagation();
return;
}
}
}
function removeElement(elm) {
elm.parentNode.removeChild(elm);
}
.remove {
cursor: pointer;
}
<table>
<tbody id="the-tbody"></tbody>
</table>
<input type="button" id="btn-add" value="Add Row">
There I'm using addEventListener. If you need to support older browsers, you can use the hookEvent function in this other answer instead.
I prefer the jQuery function .closest() to delete the selected row so you don't need to work with an Row-ID...because the threadstarter has already jQuery...try this:
$(document).ready(function(){
$('button[name=deleteTR]').click(function(){
$(this).closest('tr').remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr><td><button type="button" name="deleteTR">Delete</button></td><td>Row 1</td></tr>
<tr><td><button type="button" name="deleteTR">Delete</button></td><td>Row 2</td></tr>
<tr><td><button type="button" name="deleteTR">Delete</button></td><td>Row 3</td></tr>
<tr><td><button type="button" name="deleteTR">Delete</button></td><td>Row 4</td></tr>
</table>
Greetings from Vienna

i need to get the second td span value based on tr id how can i get that?

i need to get the second td span value based on tr id
`
<table><tr id="1">
<td style="width:150px;"><span id="1">C </span></td>
<td><span style="width:800px;">hello world</span></td>
<td><input type="checkbox" name="1" onclick="KeywordText(1);" value="1"></td>
</tr>
<tr id="2">
<td style="width:150px;"><span id="2">Dot Net </span></td>
<td><span style="width:800px;">Dot Net,java,cobol,hai,Dot Net,java,cobol,hai,Dot Net,java,cobol,hai,Dot Net,java,cobol,hai</span></td>
<td><input type="checkbox" name="2" onclick="KeywordText(2);" value="2"></td>
</tr></table>
This assumes you want the second span
JavaScript:
var row = document.getElementById("rowId");
var spans = row.getElementsByTagName("span");
var secondSpan = spans[1];
jQuery:
var secondSpan = $("#rowId span:eq(1)");
It you want the span inside the second table cell
JavaScript:
var row = document.getElementById("rowId");
var cells = row.getElementsByTagName("td");
var spans = cells.getElementsByTagName("span");
var secondSpan = spans[0];
or with querySelector
var span = document.getElementById("rowId").querySelector("td + td > span");
jQuery:
var secondSpan = $("#rowId td:eq(1) span");
And spans do not have a value, you either what its html or its text.
JavaScript:
var text = secondSpan.innerHTML;
jQuery:
var text = secondSpan.html(); // or secondSpan.text();
function KeywordText(id) {
var td = document.getElementById(id).cells[1];
console.log(td.firstChild.innerHTML); // "hello word" if id == 1
}
example: http://jsfiddle.net/n2t4Z/
Strictly speaking, you can do it like this:
getSpanValueByRowId(1);
function getSpanValueByRowId(rowID) {
var row = document.getElementById(rowID);
var cells = row.getElementsByTagName("td");
var span = cells[1].getElementsByTagName("span")[0];
return span.innerText;
}
Although you could use jQuery to get it, it would look like this:
function getSpanValueByjQuery(rowID){
return $("#"+rowID + " td:nth-child(2) span").text();
}
Using jQuery:
var getvalue=$(this).closest('tr').find('td:eq(1) span').val();
alert(getvalue);

Categories