I have a dynamically created table with 4 text inputs and 1 drop down selection.
When the user clicks the Add button, a clone of the previous row is added to the table. That works as it should. what I'm trying to do is increase the Unit ID input by 1. For example first row is 1111T-01 when the add button is clicked I want the next row Unit ID to be 1111T-02. Thank you.
HTML CODE
<h2>Please fill in the information below</h2>
<form action="pmUnitCreate.php" method="post">
<p>Click the Add button to add a new row. Click the Delete button to Delete ALL rows.</p>
<input type="button" id="btnAdd" class="button-add" onClick="addRow('myTable')" value="Add"/>
<input type="button" id="btnDelete" class="button-delete" onClick="deleteRow('myTable')" value="Delete"/>
<br>
<table id="myTable" class="form">
<tr id="heading">
<th><b><font size="4">Job Number</font></b></th>
<th><b><font size="4">Job Code</font></b></th>
<th><b><font size="4">Unit ID</font></b></th>
<th><b><font size="4">Model Number</font></b></th>
<th><b><font size="4">Scope</font></b></th>
</tr>
<tr id="tableRow">
<td>
<input type="text" name="JobNumber[]" required>
</td>
<td>
<input type="text" name="JobCode[]" required>
</td>
<td>
<input type="text" name="UnitID[]" required>
</td>
<td>
<input type="text" name="ModelNumber[]" required>
</td>
<td>
<select id="Scope" name="Scope[]" required>
<option>100OA</option>
<option>BTank</option>
<option>WSEcon</option>
<option>NetPkg</option>
<option>CstmCtrl</option>
<option>CstmRef</option>
<option>CstmSM</option>
<option>CstmHV</option>
<option>CPCtrl</option>
<option>DesiHW</option>
<option>DigScroll</option>
<option>DFGas</option>
<option>DWall</option>
<option>MZ-DD</option>
<option>DPP</option>
<option>Encl</option>
<option>PlateHX</option>
<option>ERW</option>
<option>ERWModule</option>
<option>ERVMod</option>
<option>EvapBP</option>
<option>PreEvap</option>
<option>XP</option>
<option>Extend</option>
<option>FanWall</option>
<option>FillStat</option>
<option>FFilt</option>
<option>PFilt</option>
<option>CarbFilt</option>
<option>CustFilt</option>
<option>MGH(H)</option>
<option>GHeat</option>
<option>HighStatic</option>
<option>HGBP</option>
<option>HGRH</option>
<option>HPConv</option>
<option>GFHumid</option>
<option>TOHumid</option>
</select>
</td>
</tr>
</table>
JS CODE
<script>
function addRow() {
var row = document.getElementById("tableRow"); // find row to copy
var table = document.getElementById("myTable"); // find table to append to
var clone = row.cloneNode(true); // copy children too
//clone.id = "newID"; // change id or other attributes/contents
table.appendChild(clone); // add new row to end of table
}
function deleteRow() {
document.getElementById("myTable").deleteRow(-1);
}
</script>
jsfiddle
If the unit id is always xxxx-1 and the x is never a - this should do the work.
If the x can be a - let me know and I'll update the answer accordingly.
function incrementUnitId(unitId) {
var arr = unitId.split('-');
if (arr.length === 1) {return;} // The unit id is not valid;
var number = parseInt(arr[1]) + 1;
return arr[0] + '-' + (number < 10 ? 0 : '') + number;
}
function addRow() {
var row = document.getElementById("tableRow"); // find row to copy
var table = document.getElementById("myTable"); // find table to append to
var clone = row.cloneNode(true); // copy children too
row.id = "oldRow"; // We want to take the last value inserted
clone.cells[2].childNodes[1].value = incrementUnitId(clone.cells[2].childNodes[1].value)
table.appendChild(clone); // add new row to end of table
}
function deleteRow() {
document.getElementById("myTable").deleteRow(-1);
}
<h2>Please fill in the information below</h2>
<form action="pmUnitCreate.php" method="post">
<p>Click the Add button to add a new row. Click the Delete button to Delete ALL rows.</p>
<input type="button" id="btnAdd" class="button-add" onClick="addRow('myTable')" value="Add"/>
<input type="button" id="btnDelete" class="button-delete" onClick="deleteRow('myTable')" value="Delete"/>
<br>
<table id="myTable" class="form">
<tr id="heading">
<th><b><font size="4">Job Number</font></b></th>
<th><b><font size="4">Job Code</font></b></th>
<th><b><font size="4">Unit ID</font></b></th>
<th><b><font size="4">Model Number</font></b></th>
<th><b><font size="4">Scope</font></b></th>
</tr>
<tr id="tableRow">
<td>
<input type="text" name="JobNumber[]" required>
</td>
<td>
<input type="text" name="JobCode[]" required>
</td>
<td>
<input type="text" name="UnitID[]" required>
</td>
<td>
<input type="text" name="ModelNumber[]" required>
</td>
<td>
<select id="Scope" name="Scope[]" required>
<option>100OA</option>
<option>BTank</option>
<option>WSEcon</option>
<option>NetPkg</option>
<option>CstmCtrl</option>
<option>CstmRef</option>
<option>CstmSM</option>
<option>CstmHV</option>
<option>CPCtrl</option>
<option>DesiHW</option>
<option>DigScroll</option>
<option>DFGas</option>
<option>DWall</option>
<option>MZ-DD</option>
<option>DPP</option>
<option>Encl</option>
<option>PlateHX</option>
<option>ERW</option>
<option>ERWModule</option>
<option>ERVMod</option>
<option>EvapBP</option>
<option>PreEvap</option>
<option>XP</option>
<option>Extend</option>
<option>FanWall</option>
<option>FillStat</option>
<option>FFilt</option>
<option>PFilt</option>
<option>CarbFilt</option>
<option>CustFilt</option>
<option>MGH(H)</option>
<option>GHeat</option>
<option>HighStatic</option>
<option>HGBP</option>
<option>HGRH</option>
<option>HPConv</option>
<option>GFHumid</option>
<option>TOHumid</option>
</select>
</td>
</tr>
</table>
Related
The Select Items in my code below works if I havent added a new row yet.
The items are fetched from a db using php mysql.
How Can I still make the select options in the children elements work like the parent element cloned. The select button works like its disabled in the children element
I want the children element to also have the room to select items
<script type="text/javascript">
function create_tr(table_id) {
let table_body = document.getElementById(table_id),
first_tr = table_body.firstElementChild
tr_clone = first_tr.cloneNode(true);
table_body.append(tr_clone);
clean_first_tr(table_body.firstElementChild);
}
function clean_first_tr(firstTr) {
let children = firstTr.children;
children = Array.isArray(children) ? children : Object.values(children);
children.forEach(x => {
if (x !== firstTr.lastElementChild) {
x.firstElementChild.value = '';
}
});
}
function remove_tr(This) {
if (This.closest('tbody').childElementCount == 1) {
alert("First Row Can't Be Deleted");
} else {
This.closest('tr').remove();
}
}
</script>
<div class="col-xl-8 col-md-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Add Device Information</h3>
</div>
<div class="card-body">
<form id="" method="POST" autocomplete="off" novalidate="novalidate">
<table class="table border text-nowrap text-md-nowrap table-striped mb-0">
<thead>
<tr>
<th>Device Model</th>
<th>Serial No</th>
<th>
<button type="button" id="add" class=" btn text-success" onclick="create_tr('table_body')">
<i class="fe fe-plus-circle" id="add" style="font-size:1.6em;"></i>
</button>
</th>
</tr>
</thead>
<tbody class="field_wrapper" id="table_body">
<tr>
<td>
<select class="form-control form-select select2" data-bs-placeholder="Select" name="model[]" required="" id="model"> <?php
$readALL1 = "SELECT * FROM productmodels WHERE deleted = 0";
$displayAll1 = mysqli_query($conn,$readALL1);
while($rowFetchAll1 = mysqli_fetch_array($displayAll1)){
$modelName = $rowFetchAll1['modelName'];
$modelid = $rowFetchAll1['modelID'];
?> <option value="
<?=$modelid?>"> <?=$modelName?> </option> <?php } ?> </select>
</td>
<td>
<input type="" name="" class="form-control" placeholder="Serial No...">
<input type="text" name="addedBy[]" class="form-control" id="addedBy" value="
<?=$_SESSION['user_uniq_id']?>" hidden="">
<input type="text" name="client[]" class="form-control" value="
<?=$clientID?>" id="client" hidden="">
<input type="text" name="deviceID[]" class="form-control" value="
<?=time()?>" id="deviceID" hidden="">
</td>
<td>
<button type="button" id="add" class=" btn text-danger" onclick="remove_tr(this)">
<i class="fe fe-minus-circle" id="add" style="font-size:1.6em;"></i>
</button>
</td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
</div>
As per the comment I made above, you have duplicate IDs so whenever you use document.getElementByID you are going to have issues if attempting to call an element that has it's ID duplicated.
Fo the delete buttons to work you can either assign the event handler explicitly when you make the clone of the entire table row or the preferred method is to use a delegated event handler that intercepts click events to the common parent ( the table is easy ) and then reacts accordingly. The following HTML is a modified version of the above - all IDs have been removed, some replaced with dataset attributes. The select menu simply has a basic statically written few options to illustrate the case.
// No element in the HTML now has an ID so there will be no duplicate IDs. To identify
// DOM elements a more useful set of selectors (querySelector & querySelectorAll) are
// very useful. The `event` can be used to begin DOM traversal to find elements of
// interest rather than rely upon a static ID or crudely constructed dynamic IDs, usually
// involving numbers.
document.querySelector('button[data-name="add"]').addEventListener('click', e => {
// from the event.target, find the parent table row and from that the table-body
let tbody = e.target.closest('table').querySelector('tbody');
// clone the first row from table-body and do some manipulations
let clone=tbody.firstElementChild.cloneNode(true);
clone.querySelector('button[data-name="del"]').hidden=false;
clone.querySelectorAll('input, select').forEach(n=>{
n.value='';
});
// add the new row - no IDS anywhere.
tbody.appendChild(clone);
});
// Delegated Event Listener. This is bound to the table and monitors `click` events
// but processes only those events originating from the specified elements (button & i)
// - newly added elements are not registered in the DOM when the page loads initially
// which is why a delegated listener is used.
document.querySelector('form table#dyntbl').addEventListener('click', e => {
e.stopPropagation();
// only process clicks from either a button with dataset.name='del' or it's child i
if (e.target != e.currentTarget && (e.target.dataset.name == 'del' || e.target.parentNode.dataset.name == 'del')) {
// identify the table-body as before
let tbody = e.target.closest('table').querySelector('tbody');
// remove table row unless it is the 1st one otherwise things break.
if( tbody.childNodes.length > 3 ) tbody.removeChild(e.target.closest('tr') )
}
});
<div class='col-xl-8 col-md-12'>
<div class='card'>
<div class='card-header'>
<h3 class='card-title'>Add Device Information</h3>
</div>
<div class='card-body'>
<form method='POST' autocomplete='off' novalidate='novalidate'>
<table id='dyntbl' class='table border text-nowrap text-md-nowrap table-striped mb-0'>
<thead>
<tr>
<th>Device Model</th>
<th>Serial No</th>
<th>
<button type='button' data-name='add' class=' btn text-success'>
<i class='fe fe-plus-circle' data-id='add' style='font-size:1.6em;'>#Add#</i>
</button>
</th>
</tr>
</thead>
<tbody class='field_wrapper'>
<tr>
<td>
<select class='form-control form-select select2' data-bs-placeholder='Select' name='model[]' required>
<option>A
<option>B
<option>C
</select>
</td>
<td>
<input type='text' name='serial[]' class='form-control' placeholder='Serial No...' />
<input type='text' name='addedBy[]' class='form-control' hidden />
<input type='text' name='client[]' class='form-control' hidden />
<input type='text' name='deviceID[]' class='form-control' hidden />
</td>
<td>
<button type='button' data-name='del' class='btn text-danger' hidden>
<i class='fe fe-minus-circle' style='font-size:1.6em;'>#Delete#</i>
</button>
</td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
</div>
The script below creates a new line of text boxes and a button. However, when the button is clicked, the new field would like to have new button text and a new design.
$(function () {
var newRow = $(".addRows").clone();
$("#addButton").on("click", function () {
let row = newRow.clone().appendTo("#TextBoxesGroup tbody");
$("tr").find("#addButton").css( "border-color", "red" );
});
});
<table id="TextBoxesGroup">
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate[]" class="picker" value="" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate[]" class="picker" value="" size="6">
</td>
<td>
<input type="button" id="addButton" value="add row" />
</td>
</tr>
</table>
<script type = "text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
For example, the created new button should be with text delete and color red.
Thanks for the help or recommendation
I think using templates might make it easier and cleaner to modify the elements. Here is a quick guide for basic templating with vanillajs https://gomakethings.com/html-templates-with-vanilla-javascript/
This allows you to easily pass in IDs for your inputs.
I am not sure if you are just trying to toggle a second row or add multiple rows. If you simply want to toggle the second row and not add more than that then only use the second part of the js, and remove the first template. Likewise if you want to add multiple you can remove the second part (currently commented out) of the js and the second template.
(function (){
// Interpolate function from https://gomakethings.com/html-templates-with-vanilla-javascript/
//Lets us pass a unique id to the template
function interpolate (str, params) {
let names = Object.keys(params);
let vals = Object.values(params);
return new Function(...names, `return \`${str}\`;`)(...vals);
}
//Using document on click as we are adding new buttons to the DOM and want the event to trigger on them as well
$(document).on('click', '.add-button', function () {
let id = $('.addRows').length + 1; //Use this for our row ID
let newRow = interpolate(row_template.innerHTML, {id}); //Generate our row html from the template
$(this).closest('.addRows').after(newRow); //Add the html to the table
});
//Remove button
$(document).on('click', '.remove-button', function () {
$(this).closest('.addRows').remove();
});
})();
//Use the below INSTEAD of the above for just the single extra toggling row.
/*(function (){
//Add new row from simple template
$(document).on('click', '.add-button', function () {
$("#TextBoxesGroup tbody").append(row_template_single.innerHTML);
});
//Remove the row
$(document).on('click', '.remove-button', function () {
$(this).closest('.addRows').remove();
});
})();*/
/*Style for red remove button*/
.remove-button {
background-color: #f77;
color: white;
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<table id="TextBoxesGroup">
<tbody>
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate_1" class="picker" value="" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate_2" class="picker" value="" size="6">
</td>
<td>
<input type="button" id="addButton_1" class="add-button" value="Add row" />
</td>
</tr>
</tbody>
</table>
<!-- Template allowing to add multiple new rows with unique input names via id passed -->
<template id="row_template">
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate_${id}" class="picker" value="" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate_${id}" class="picker" value="" size="6">
</td>
<td>
<input type="button" id="addButton_${id}" class="add-button" value="Add row" />
<input type="button" class="remove-button" value="Remove row" />
</td>
</tr>
</template>
<!-- Template for just 'toggling' a second row -->
<!-- <template id="row_template_single">
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate_2" class="picker" value="" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate_2" class="picker" value="" size="6">
</td>
<td>
<input type="button" class="remove-button" value="Remove row" />
</td>
</tr>
</template> -->
I noticed my previous answer did not properly handle adding items in-between other items, i.e. not at the end of the list.
The following will better handle adding and removing items, while keeping the ids in order. This instead renders the fields based on the data we keep and manage in JavaScript.
(function () {
$(document).ready(function () {
field_data.init()
})
let field_data = {
data: [],
init: function () {
this.cacheDom();
this.bindEvents();
this.data.push(this.getItem());
this.renderData();
},
cacheDom: function () {
this.$render_container = $('#render_container');
this.row_template_html = $('#row_template').html();
},
bindEvents: function () {
$(document).on('click', '.remove-button', this.removeItem);
$(document).on('click', '.add-button', this.addItem);
this.$render_container.on('change', 'input', this.inputChange);
},
//When an item gets added, add new empty item to the data and re-render.
addItem: function () {
let target = parseInt($(this).attr('data-target'));
field_data.data.splice(target+1, 0, field_data.getItem());
field_data.renderData();
},
//When an item gets removed, remove it from the data and re-render.
removeItem: function () {
let target = parseInt($(this).attr('data-target'));
if (field_data.data.length > 1) { //Prevent from removing last item.
field_data.data.splice(target, 1);
field_data.renderData();
}
},
//Get a new/empty item.
getItem: function () {
return {
start_date: '',
end_date: '',
}
},
//Update the data when a value of an input changes
inputChange: function () {
let $this = $(this);
let id = parseInt($this.attr('data-id'));
let target = $this.attr('data-target');
field_data.data[id][target] = $this.val();
},
//Render the data according to the template.
renderData: function () {
let html = '';
for (let i = 0; i < field_data.data.length; i++) {
//Generate our row html from the template
html += field_data.getRowTemplate(
{
id: i,
start_date: field_data.data[i].start_date,
end_date: field_data.data[i].end_date,
}
);
}
field_data.$render_container.html(html);
},
//Gets the html for a single row based on our template
getRowTemplate: function (params) {
let names = Object.keys(params);
let values = Object.values(params);
return new Function(...names, `return \`${field_data.row_template_html}\`;`)(...values);
},
}
})();
.remove-button {
background-color: #f77;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="TextBoxesGroup">
<tbody id="render_container">
</tbody>
</table>
<template id="row_template">
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate_${id}" data-id="${id}" data-target="start_date" class="picker" value="${start_date}" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate_${id}" data-id="${id}" data-target="end_date" class="picker" value="${end_date}" size="6">
</td>
<td>
<input type="button" class="add-button" data-target="${id}" id="addButton_${id}" value="Add row"/>
<input type="button" class="remove-button" data-target="${id}" value="Remove row"/>
</td>
</tr>
</template>
I made a listener to attatch an id "selectedRow" to the row a user has clicked on. The intent from there is be able to manipulate the data in that row; Previously i was using content editable however I'm trying to make it more obvious to the user that they are editing a row (this is for a project) so i've created an editing panel to do so. I've however ran in to some problems with a lot of data being returned as undefined when using .innerHTML when sending the TD to the input boxes.
I've tried using .HTML instead
$('tr').click(function() {
if(document.getElementById("SELECTEDROW")) {
var oldRow = document.getElementById("SELECTEDROW");
oldRow.classList.remove("selected");
$("#SELECTEDROW").removeAttr('id');
}
$(this).attr('id', 'SELECTEDROW');
selectedRow = document.getElementById("SELECTEDROW");
table = selectedRow.parentNode;
console.log("Row " + selectedRow.childNodes[1].innerHTML + " Selected");
selectedRow.classList.add("selected");
editRow();
});
function editRow() {
var currentTD = selectedRow.childNodes;
var inputs = document.getElementById("inputs").childNodes;
var i = 0;
for (i = 0; i < currentTD.length; i++) {
inputs[i].innerHTML = currentTD.html;
}
console.log('Now Editing:' + currentTD[1].innerHTML);
document.getElementById("editingPanel").style.display = "block";
document.getElementById("content").style.height = "49%";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content">
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Role</th>
<th>Address</th>
<th>Phone</th>
<th>Email</th>
<th>Password</th>
</tr>
<tr>
<td>1</td>
<td>Bill Robbins</td>
<td>Conductor</td>
<td>12, Caldrow Ave, Plymouth, Pl21XE</td>
<td>01921202384</td>
<td>XxbillyboyxX#bossman.com</td>
<td>CaTsRbAe1967</td>
</tr>
<tr>
<td>2</td>
<td>Kat Robbins</td>
<td>Admin</td>
<td>12, Caldrow Ave, Plymouth, Pl21XE</td>
<td>019232042454</td>
<td>katrobs#gmail.com</td>
<td>thR33mel0ns</td>
</tr>
</table>
</div>
<div id="editingPanel">
<div id="inputFields">
<form id="inputs">
<input id="input1" type="text" name=""/>
<input id="input2" type="text" name="">
<input id="input3" type="text" name="">
<input id="input4" type="text" name="">
<input id="input5" type="text" name="">
<input id="input6" type="text" name="">
<input id="input7" type="text" name="">
<input id="input8" type="text" name="">
</form>
</div>
<div id="editButtons">
<button onclick="addRow()">New Row</button>
<button onclick="editRow()">Save Row</button>
<button onclick="removeRow()">Delete Row</button>
</div>
</div>
The expected output would be for each td's text to be copied into the input boxes.
You need to get the children properly. You also need to assign the text to the value property of the input, not its innerHTML
function editRow() {
// You need to get elements by tag name, not childNodes
var currentTD = selectedRow.getElementsByTagName("td");
// You need to get elements by tag name, not childNodes
var inputs = document.getElementById("inputs").getElementsByTagName("input");
var i = 0;
for (i = 0; i < currentTD.length; i++) {
console.log(inputs[i]);
console.log(currentTD[i]);
// set the "Value" of an input box, not its "innerHTML"
// also you need to apply the [i] to the currentTD because it is a list
inputs[i].value = currentTD[i].innerHTML;
}
You can try this:
$("body").on("click","tr",function(){ //Just in case you are going to use dynamic content, because the click method doesn't work on dynamically created/added elements
for(let i=0;i<7;i++){
$("#input"+(i+1)).val($(this).children()[i].innerHTML); //You are using jQuery for a reason, to simplify code, so avoid using unnecessary JS where you can by using simplified jQuery
}
});
Below in the example, I want that each time when the add button is clicked to take the element inside the template div and append it to the landingzone class element. But at the same time I need the NEWID to change for the new element. Of course this is just an example, the table stuff can be a div or anything else.
the form:
<form method="post">
<input type="text" name="title">
<input type="text" name="number">
<table>
<thead>
<tr> <th>Parts</th> </tr>
</thead>
<tbody class="landingzone">
</tbody>
</table>
<input type="submit" value="Save">
<input type="button" name"add" class="add" value="Save">
</form>
the template:
<div class="template" style="display: hidden">
<tr id="NEWID">
<td>
<input type="text" name="part_NEWID">
</td>
</tr>
</div>
What would be the best way to accomplish this?
Here's an example for your need. The javascript will work without changing any html except in place of name"add" should be name="add"
What i have done here is i'm getting the id of the template tr and setting it with increment and also the input field name.
var $landingzone = $('.landingzone');
var $add = $('.add');
var desiredId = 'id';
$add.on('click', function() {
var $template = $('.template').find('tr');
var id = $template.attr('id');
var idArr = id.split('-');
if (!idArr[1]) {
id = desiredId + '-1';
} else {
id = desiredId + '-' + (parseInt(idArr[1]) + 1);
}
$template.attr('id', id);
$template.find('input').attr('name', 'part_'+id);
console.log('input id--->'+id, 'input name--->'+'part_'+id);
$landingzone.append($template.clone());
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post">
<input type="text" name="title">
<input type="text" name="number">
<table>
<thead>
<tr>
<th>Parts</th>
</tr>
</thead>
<tbody class="landingzone">
</tbody>
</table>
<input type="submit" value="Save">
<input type="button" name="add" class="add" value="Add">
</form>
<table class="template" style="display: none">
<tr id="NEWID">
<td>
<input type="text" name="part_NEWID">
</td>
</tr>
</table>
Like #Andrea said in her comment, some more details would be appreciated ...
I think what you are after is:
const $template = $('.template').clone()
$template.attr('id', 'someId')
$template.find('input[name="part_NEWID"]').attr('name', 'part_someId')
$('.landingzone').append($template)
And if you need it in a function:
function appendTemplateToLandingZone (newId) {
const $template = $('.template').clone()
$template.attr('id', newId)
$template.find('input[name="part_NEWID"]').attr('name', 'part_' + newId)
$('.landingzone').append($template)
}
I haven't tested this, so it might need a slight adjustment. If you'll provide a basic jsbin I'll make it work there.
I have then following table:
<table style="width:100%" id="testTable">
<tr>
<th>length per</th>
<th>width per</th>
<th>length</th>
<th>width</th>
<th>total</th>
</tr>
<tr align='right'>
<td>
<input type="text" name="length-per-input">
</td>
<td>
<input type="text" name="width-per-input">
</td>
<td>
<input type="text" name="length-total-input">
</td>
<td>
<input type="text" name="width-total-input">
</td>
<td>
<input type="text" name="total-output" disabled="disabled">
</td>
</tr>
<tr align='right'>
<td>
<input type="text" name="length-per-input">
</td>
<td>
<input type="text" name="width-per-input">
</td>
<td>
<input type="text" name="length-total-input">
</td>
<td>
<input type="text" name="width-total-input">
</td>
<td>
<input type="text" name="total-output" disabled="disabled">
</td>
</tr>
</table>
<input type=button value='+' onclick="addRow()" />
<input type=button value='Calculate' onclick="Calculate()" />
I also have the javascript which adds the value and puts it in total:
<script>
function Calculate() {
var lengthPerInput = $("input[name='length-per-input']").val();
var widthPerInput = $("input[name='width-per-input']").val();
var lengthTotal = $("input[name='length-total-input']").val();
var widthTotal = $("input[name='width-total-input']").val();
var total = (lengthTotal/lengthPerInput) + (widthTotal/widthPerInput);
$("input[name='total-output']").val(total);
}
</script>
The aim here is to have it iterate over the two rows, then add each one separately.
I know how to get each row by using:
$('#testTable tr').each(function(){
console.log(this);
$(this).find('length-per-input').each(function(){
console.log(this);
})
})
But using the row (accessed via "this") I don't know how to get the correct cells, get their value, then perform the calculate on that row for the total.
Any advice on this please? Thank you!
function Calculate(tr_row) {
var lengthPerInput = tr_row.find("input[name='length-per-input']").val();
var widthPerInput = tr_row.find("input[name='width-per-input']").val();
var lengthTotal = tr_row.find("input[name='length-total-input']").val();
var widthTotal = tr_row.find("input[name='width-total-input']").val();
var total = (lengthTotal/lengthPerInput) + (widthTotal/widthPerInput);
tr_row.find("input[name='total-output']").val(total);
}
For every row you call function to summ the values
To the function you pass the row, then it can collect values on that row
$('#testTable tr').each(function(){
Calculate($(this))
})
You can use each() function to iterate through table and use find() function to find cell values.
function Calculate() {
$('#testTable tr').each(function() {
var lengthPerInput = $(this).find("input[name='length-per-input']").val();
var widthPerInput = $(this).find("input[name='width-per-input']").val();
var lengthTotal = $(this).find("input[name='length-total-input']").val();
var widthTotal = $(this).find("input[name='width-total-input']").val();
var total = (lengthTotal/lengthPerInput) + (widthTotal/widthPerInput);
$(this).find("input[name='total-output']").val(total);
});
}
Working Plunker
How to get a table cell value using jQuery?