Form last value removed after add another field with Javascript - javascript

In my html form I can add extra fileds with javascript. But problem is it's removed the last submitted value when I add another field.
For example:
There is a form fileds called: Ingredient and Quantity. I can add another ingredient and Quantity field by click on "Add more" buttion. Ok suppose, I added a new fields and wrote it's value. But if I again click on the "Add more" buttion it's deleted my last fields value.
**Add more = (Ajouter un autre ingrédient)
Html Code:
<table width="700" border="0" cellspacing="0" cellpadding="5" class="table" style="float:">
<td width="180">Ingrédients</td>
<td>
<input type="text"class="tr" name="ingredients[]" id="ingredients" placeholder="Ingredient"/>
</td>
</tr>
<tr>
<td>Quantité</td>
<td><input name="quantity[]" type="text" id="quantity" placeholder="Quantity" class="tr" /></td>
</tr>
<tr>
<td></td>
<td><input type="button" onclick="addmyrow()" name="add" value="Ajouter un autre ingrédient" /><br/><br/> <div id="row"></td>
</tr>
</table>
Javascript Code:
<script language="javascript">
fields = 0;
function addmyrow() {
if (fields != 10) {
document.getElementById('row').innerHTML += "<input type='text' class='tr' name='ingredients[]' id='ingredients' placeholder='Ingredient'/><br/>";
document.getElementById('row').innerHTML += "<input name='quantity[]' type='text' id='quantity' placeholder='Quantity' class='tr' /><br/>";
fields += 1;
} else {
document.getElementById('row').innerHTML += "<br />Only 10 upload fields allowed.";
document.form.add.disabled=true;
}
}
</script>
Thanks.

When you append contents like this: document.getElementById('row').innerHTML += ...
you're technically replacing the innerHTML with new HTML.
This causes any changes (i.e., form value changes) to be erased.
The correct way is to create brand new DOM elements and then append those elements. What you're doing now is just appending additional HTML.
Here's the corrected version:
<table width="700" border="0" cellspacing="0" cellpadding="5" class="table" style="float:">
<tr>
<td width="180">Ingrédients</td>
<td>
<input type="text"class="tr" name="ingredients[]" id="ingredients" placeholder="Ingredient"/>
</td>
</tr>
<tr>
<td>Quantité</td>
<td><input name="quantity[]" type="text" id="quantity" placeholder="Quantity" class="tr" /></td>
</tr>
<tr>
<td></td>
<td><input type="button" onclick="addmyrow()" name="add" value="Ajouter un autre ingrédient" /><br/><br/> <div id="row"></div>
</td>
</tr>
</table>
<script language="javascript">
fields = 0;
function addmyrow() {
if (fields != 10) {
var newIngredients = document.createElement('input');
var newQuantity = document.createElement('input');
var brTag = document.createElement('br');
newIngredients.setAttribute('type', 'text');
newQuantity.setAttribute('type', 'text');
newIngredients.setAttribute('placeholder', 'Ingredient');
newQuantity.setAttribute('placeholder', 'Quantity');
newIngredients.setAttribute('name', 'ingredients[]');
newQuantity.setAttribute('name', 'quantity[]');
newIngredients.setAttribute('class', 'tr');
newQuantity.setAttribute('class', 'tr');
document.getElementById('row').appendChild(newIngredients);
document.getElementById('row').appendChild(brTag);
document.getElementById('row').appendChild(newQuantity);
document.getElementById('row').appendChild(brTag);
fields += 1;
} else {
document.getElementById('row').innerHTML += "<br />Only 10 upload fields allowed.";
document.form.add.disabled=true;
}
}
</script>
And here's a working fiddle: http://jsfiddle.net/tC7Dm/

changes in innerHTML causes all child DOMs to be destroyed. this link might help
Is it possible to append to innerHTML without destroying descendants' event listeners?
here you go, whoever minusoned me deserves a spoonful of feed.
<script>
function addmyrow() {
var mydiv = document.getElementById("row");
var newcontent = document.createElement('div');
newcontent.innerHTML = "<input type='text' class='tr' name='ingredients[]' id='ingredients' placeholder='Ingredient'/><br/><input name='quantity[]' type='text' id='quantity' placeholder='Quantity' class='tr' /><br/>";
if (fields < 10) {
while (newcontent.firstChild) {
mydiv.appendChild(newcontent.firstChild);
}
fields=fields+1;
}
else {
document.getElementById('row').innerHTML += "<br />Only 10 upload fields allowed.";
document.form.add.disabled=true;
}
}
</script>

#Babu, the reason behind this issue is when you get the existing value with innerHTML it doesn't get the value for input dom elements because the value stored in the property not in the attribute. You could find the same in following links
Inner HTML with input values
So rather than using JS you could try jQuery, Below is a working demo
var fields = 0;
function addmyrow() {
if (fields != 10) {
$("#row").append("<input type='text' class='tr' name='ingredients[]' id='ingredients' placeholder='Ingredient' value='' /><br/>");
$("#row").append("<input name='quantity[]' type='text' id='quantity' placeholder='Quantity' class='tr' /><br/>");
fields += 1;
}
else {
$("#row").append("<br />Only 10 upload fields allowed.");
document.form.add.disabled=true;
}
}
Fiddle Demo

Related

JavaScript won't include tr- and td-tags in string

i am trying to insert a <tr> and a <td> into a table using javascript.
I have a fairly simple javascript-code that prints a string every time I click a button. It's being printed into a <table>, but javascript ignores the <tr> and <td>tags.
How do I make Javascript include <tr> and <td> tags?
I gave already tried escaping the string in various ways.
code used:
<script>
function MoreCameras() {
document.getElementById("AddCamera").innerHTML += "<tr><td><input type='text' name='SSIDSetup[]' class='form-control' placeholder='Camera SSID'></td><td><input type='text' name='NameSetup[]' class='form-control' placeholder='Camera Name'></td><td><input type='password' name='PasswordSetup[]' class='form-control' placeholder='Camera Password'></td><td><input type='checkbox' name='EnabledSetup[]'/></td></tr>";
}
</script>
<button onclick="MoreCameras()">Try it</button>
<table>
<div id="AddCamera">
</div>
</table>
screenshot for clarification
It's generally not a good idea to use inline event handlers.
You can't add table rows to a div. Here's a snippet using event delegation and adding the innerHTML to the table. It may be more approriate to create a row using DOM-scripting, cf MDN. Added a function for that to the snippet.
It is not uncommon to see innerHTML used to insert text into a web
page. There is potential for this to become an attack vector on a
site, creating a potential security risk.
document.addEventListener("click", MoreCameras);
function MoreCameras(evt) {
if (evt.target.id === "ih") {
document.querySelector("#AddCamera").innerHTML += getRowHtml();
}
if (evt.target.id === "ds") {
document.querySelector("#AddCamera").appendChild(createRow());
}
}
function createRow() {
const row = document.createElement("tr");
const cells = [...Array(4)].map(td => document.createElement("td"));
const inputs = [...Array(4)].map(input => document.createElement("input"));
inputs[0].type = "text";
inputs[0].name = "SSIDSetup[]";
inputs[0].classList.add("form-control");
inputs[0].setAttribute("placeholder", "Camera SSID");
inputs[1].type = "text";
inputs[1].name = "NameSetup[]";
inputs[1].classList.add("form-control");
inputs[1].setAttribute("placeholder", "Camera Name");
inputs[2].type = "password";
inputs[2].name = "PasswordSetup[]";
inputs[2].classList.add("form-control");
inputs[2].setAttribute("placeholder", "Camera Password");
inputs[3].type = "checkbox";
inputs[3].name = "EnabledSetup[]";
cells.forEach((cell, i) => {
cell.appendChild(inputs[i]);
row.appendChild(cell);
});
return row;
}
function getRowHtml() {
return `
<tr>
<td>
<input
type="text"
name="SSIDSetup[]"
class="form-control"
placeholder="Camera SSID">
</td>
<td>
<input
type="text"
name="NameSetup[]
class="form-control"
placeholder="Camera Name">
</td>
<td>
<input
type="password"
name="PasswordSetup[]"
class="form-control"
placeholder="Camera Password">
</td>
<td>
<input
type="checkbox"
name="EnabledSetup[]">
</td>
</tr>`;
}
<button id="ih">Try it (innerHTML)</button>
<button id="ds">Try it (DOM scripting)</button>
<table>
<tbody id="AddCamera"></tbody>
</tabe>
You are inserting cell based elements into a div, this is not valid html.
add a tbody thead and add the id you insert into to the tbody
Just remove div and put id="AddCamera" on table. You where inserting td tr in wrong way.
EDIT:
actually add tbody with that id, that will give you right HTML syntax
<tbody id="AddCamera">
<script>
function MoreCameras() {
document.getElementById("AddCamera").innerHTML += "<tr><td><input type='text' name='SSIDSetup[]' class='form-control' placeholder='Camera SSID'></td><td><input type='text' name='NameSetup[]' class='form-control' placeholder='Camera Name'></td><td><input type='password' name='PasswordSetup[]' class='form-control' placeholder='Camera Password'></td><td><input type='checkbox' name='EnabledSetup[]'/></td></tr>";
}
</script>
<button onclick="MoreCameras()">Try it</button>
<table>
<tbody id="AddCamera">
</tbody>
</table>

Calculation for input array in every row Jquery

I am new into JQuery, My code is only working for the first row, it doesn't calculate for other rows. I have two button, one for adding another row and one for deleting it. What I try to do it to calculate price+vat*quantity and put it in total field in every row.
here if the code for my html
<table border='1' id="mytable" dir="rtl" style='border-collapse: collapse;'>
<thead>
<tr>
<th> partnumber </th>
<th>name</th>
<th>price </th>
<th>vat</th>
<th>quantity</th>
<th> price + vat</th>
<th> total quantity*(price+vat) </th>
<th> </th>
</tr>
</thead>
<tbody>
<tr class='tr_input'>
<td><input type='text' name="partnumber[]" class='username' id='partnumber_1' placeholder='پارت نه‌مبه‌ر '></td>
<td><input type='text' class='name' name="name[]" id='name_1' ></td>
<td><input type='text' class='price' name="price[]" id='price_1' ></td>
<td><input type='text' class='vat' name="vat[]" id='vat_1' ></td>
<td><input type='text' class='quantity' name="quantity[]" id='quantity_1' ></td>
<td><input type='text' class='amount' name="amount[]" id='amount_1' ></td>
<td><input type='text' class='total' name="total[]" id='total_1' ></td>
</tr>
</tbody>
</table>
<br>
<input type='button' value='Add fields' id='addmore' class="btn btn-success">
<input type='button' value='remove' id='remove' class="btn btn-danger">
Here is the screenshot for the interface.
And this is JS code for adding new row
$('#addmore').click(function(){
var lastname_id = $('.tr_input input[type=text]:nth-child(1)').last().attr('id');
var split_id = lastname_id.split('_');
var index = Number(split_id[1]) + 1;
var html = "<tr class='tr_input'><td><input type='text' name='partnumber[]' class='username' id='username_"+index+"' placeholder='بگه‌ری بۆ پارت نه‌مبه‌ر '></td><td><input type='text' class='name' name='name[]' id='name_"+index+"'></td><td><input type='text' class='price' name='price[]' id='price_"+index+"' ></td><td><input type='text' class='vat' name='vat[]' id='vat"+index+"'></td><td><input type='text' class='quantity' name='quantity[]' id='quantity_"+index+"' ></td><td><input type='text' class='amount' name='amount[]' id='amount_"+index+"' ></td><td><input type='text' class='total' name='total[]' id='total_"+index+"' ></td><td align='center'><input type='checkbox' name='record'></td></tr>";
// Append data
$('tbody').append(html);
});
and finally this is code for calculation the total, only working for the first row.
$('.total').each(function() {
$(this).on('click',function (ev) {
// var total=0;
var quantity=$(this).attr('id');
var splitid = quantity.split('_');
var index = splitid[1];
var price= parseFloat($('#price_'+index).val());
var vat=parseFloat($('#vat_'+index).val());
var quan=parseFloat($('#quantity_'+index).val());
var amount=$('#amount_'+index).val();
amount=price+vat;
$('#amount_'+index).val(amount);
alert(amount);
//alert(price);
var total=amount*quan;
//var qunatity_num=parseInt(quantity.val());
$('#total_'+index).val(total);
//alert(total);
// $('#total_'+index).val(total);
});
});
please, could you tell me what's is wrong with my code, it's been a week I am trying to solve this. Thank you.
Some issues:
There is an underscore missing in the HTML that you add for a new row: vat should be vat_
Don't use $('.total').each(function() {: it is not necessary to loop. The click handler will work on all matching elements, if you take the next point into account:
Use event delegation to make sure your click handler also gets called for future cells that have the total class:
$(document).on('click', '.total', function (ev) {
With that it works.
However it would be better not to use dynamic id attributes all and use CSS classes only. With jQuery methods you can easily find out which is the "current" row that was clicked on (.closest("tr")) and then to .find() the element you need in your formula.

print javascript results into div tag

I have been able to make this work as it adds into <div></div> tags now I want to remove this array numbers 0,1,2,3 and feed the data into <div></div> tags in HTML, How can this be done, How do I make it insert inside the div tags
<html>
<head></head>
<title>Js test</title>
<h1>Js Test</h2>
<body>
<script type="text/javascript">
var data = new Array();
function addElement(){
data.push(document.getElementById('ins_name').value);
data.push(document.getElementById('gpa').value);
data.push(document.getElementById('da').value);
document.getElementById('ins_name').value='';
document.getElementById('gpa').value='';
document.getElementById('da').value='';
display();
}
function display(){
var str = '';
for (i=0; i<data.length;i++)
{
//str+="<tr><td>" + data[i] + "</td></tr>";
"<tr>
<td align=center width=176>Institution </td>
<td align=center>GPA</td>
<td align=center width=187>Degree Awarded</td>
</tr>"
"<tr>
<td align=center width=176> </td>
<td align=center> </td>
<td align=center width=187> </td>
</tr>"
}
document.getElementById('display').innerHTML = str;
}
</script>
<form name="jamestown" id="jamestown" method="post" action="samris.php" />
Institution : <input type="text" name="ins_name" id="ins_name" /></br>
GPA : <input type="text" name="gpa" id="gpa" /></br>
Degree Awarded : <input type="text" name="da" id="da" /></br>
</p>
<input type="button" name="btn_test" id="btn_test" value="Button Add Test" onClick='addElement()'; /></br>
</form>
<div id=display></div>
</body>
</html>
Since you've been adding more and more requirements in the comments, the innerHTML += "" approach stops working.
I advice you to create elements using document.createElement and add them to your document using Node.appendChild.
It's not really an answer to the initial question, but I figured it helps you more than continuing conversation in the comments. Maybe you can edit your question to reflect the additional requirements.
Let me know if there's stuff I used that you don't yet understand. Happy to elaborate!
var inputIds = ["ins_name", "gpa", "da"];
var inputElements = inputIds.map(getById);
var tbody = getById("display");
// Create a new row with cells, clear the inputs and add to tbody
function addRow() {
// Create a row element <tr></tr>
var row = document.createElement("tr");
inputElements.forEach(function(input) {
// For each input, create a cell
var td = document.createElement("td");
// Add the value of the input to the cell
td.textContent = input.value;
// Add the cell to the row
row.appendChild(td);
// Clear the input value
input.value = "";
});
// Add the new row to the table body
tbody.appendChild(row);
}
getById("btn_test").addEventListener("click", addRow);
// I added this function because document.getElementById is a bit too long to type and doesnt work with `map` without binding to document
function getById(id) {
return document.getElementById(id);
}
Institution : <input type="text" name="ins_name" id="ins_name" /><br>
GPA : <input type="text" name="gpa" id="gpa" /><br>
Degree Awarded : <input type="text" name="da" id="da" /><br>
<input type="button" id="btn_test" name="btn_test" value="Add Test"/><br>
<table>
<thead>
<tr>
<th>Institution</th>
<th>GPA</th>
<th>Degree</th>
</tr>
</thead>
<tbody id="display">
</tbody>
</table>

Generate table code( not table) based on input value (HTML, JavaScript)

I want to generate table code based on two input fields. One input field contains number of rows and another one contains number of columns. There is one more button called submit on click of that I need to generate table code for no of rows / no of columns.
Suppose If gave rows 3 and column 2, then it should generate code like
<table>
<tbody>
<tr>
<td> </td><td> </td>
</tr>
<tr>
<td> </td><td> </td>
</tr>
<tr>
<td> </td><td> </td>
</tr>
</tbody>
</table>
This code I need to save into one string.
Please help me how to do this. I am beginner for JavaScript.
need to save into one string.
var form = document.getElementsByTagName("form")[0];
form["button"].onclick = function() {
var html = "<table><tbody>";
for (var i = 0; i < form["rows"].value; i++) {
html += "<tr>";
for (var j = 0; j < form["columns"].value; j++) {
html += "<td> </td>"
}
html += "</tr>"
}
html += "</tbody></table>";
console.log(html)
}
<form>
<input type="number" min="1" max="10" name="rows" required />rows
<input type="number" min="1" max="10" name="columns" required />columns
<input type="button" name="button" value="create table" />
</form>
I made an example for you here:
JS-FIDDLE
function buildTable() {
var rows = document.getElementById("setRows").value;
var cols = document.getElementById("setCols").value;
var table = "<table>";
table += "<tbody>";
for (i=0;i<rows;i++) {
table += "<tr>";
for (j=0;j<cols;j++) {
table += "<td> </td>";
}
table += "</tr>";
}
table += "</tbody>";
table += "</table>";
document.getElementById("tableHolder").innerHTML=table;
}

Dynamically Added Rows and Calculation Function Error After First Row

I'm working a project, it is almost done but I got a problem to finish it. I tried a lot of things and searched on the web, but unfortunately I could not succeed it.
The problem is about dynamically added rows at the table. Auto-calculating script is just working on the first row of the table, at 2nd, 3rd, ... rows of the table it does not work.
jsFiddle for below the code:
<script type='text/javascript'>//<![CDATA[
$(window).load(function(){
$("#AddLine").click(function () {
//var row = "<tr><td><input type=text /></td><td><input type=text /></td><td><input type=text /></td><td><button>X</button></td></tr>";
var row = "<tr><td><input type=\"text\" style=\"width:100%;\" name=\"stokkodu[]\"></td><td><input type=\"text\" style=\"width:100%;\" name=\"stokadi[]\"></td><td><input type=\"text\" style=\"width:100%;\" id=\"miktar\" class=\"miktar\" name=\"miktar[]\"></td><td><input type=\"text\" style=\"width:100%;\" name=\"birim[]\"></td><td><input type=\"text\" style=\"width:100%;\" id=\"birimfiyat\" class=\"birimfiyat\" name=\"birimfiyat[]\"></td><td><input type=\"text\" style=\"width:100%;\" readonly id=\"tutar\" class=\"tutar\" name=\"tutar[]\"></td><td><input type=\"text\" style=\"width:100%;\" class=\"indirim\" name=\"indirim[]\"></td><td><input type=\"text\" style=\"width:100%;\" readonly class=\"indirimtutar\" name=\"indirimtutari[]\"></td><td><input type=\"text\" style=\"width:100%;\" class=\"kdv\" name=\"kdv[]\"></td><td><input type=\"text\" style=\"width:100%;\" readonly class=\"satirtoplami\" name=\"satirtoplami[]\"></td><td><button>X</button></td></tr>";
$("#table").append(row);
});
$("#table").on("click", "button", function() {
$(this).closest("tr").remove();
});
});
$(document).ready(function() {
$('input[id=miktar],input[id=birimfiyat],input[id=indirim],input[id=kdv], input[id=satirtoplami]').change(function(e) {
var total_mnozi = 0;
//var $row = $(this).parent();
var $row = $(this).closest("tr"); //this is the closest common root of the input elements
var miktar = parseFloat( $row.find('input[id=miktar]').val() );
var birimfiyat = parseFloat( $row.find('input[id=birimfiyat]').val() );
var indirim = parseFloat( $row.find('input[id=indirim]').val() );
var kdv = parseFloat( $row.find('input[id=kdv]').val() );
//total_mnozi = ((dep + minpre + adjpre) * procombase * profcomper) || 0; //calculate traditionally; display zero until result is meaningful
tutar = (miktar * birimfiyat) || 0; // tutar hesaplama. miktar x birim fiyat = tutar
indirimtutar= (tutar * indirim / 100) || 0; // indirim tutarı hesaplama input'a girilen %'ye göre hesaplar.
satirtoplami= ((tutar - indirimtutar) * ((kdv / 100) + 1 )) || 0;
$row.find('input[id=tutar]').val(tutar.toFixed(2)); // tutar'ın id="tutar"'a virgülden sonra 2 hane alacak şekilde yazdrılması.
$row.find('input[id=indirimtutar]').val(indirimtutar.toFixed(2));
$row.find('input[id=satirtoplami]').val(satirtoplami.toFixed(2));
});
});
//]]>
</script>
<input type="button" id="AddLine" value="add"/>
<table id="table">
<tr>
</tr>
<tr>
<td scope="col">Stok Kodu</th>
<td scope="col">Stok Adı</th>
<td scope="col">Miktar</th>
<td scope="col">Birim</th>
<td scope="col">Birim Fiyat</th>
<td scope="col">Tutar</th>
<td scope="col">İndirim (%)</th>
<td scope="col">İndirim Tutarı</th>
<td scope="col">KDV (%)</th>
<td scope="col">Satır Toplamı</th>
<td scope="col"></th>
</tr>
<tr>
<td><input type="text" style="width:100%;" name="stokkodu[]"></td>
<td><input type="text" style="width:100%;" name="stokadi[]"></td>
<td><input type="text" style="width:100%;" id="miktar" class="miktar" name="miktar[]"></td>
<td><input type="text" style="width:100%;" name="birim[]"></td>
<td><input type="text" style="width:100%;" id="birimfiyat" class="birimfiyat" name="birimfiyat[]"></td>
<td><input type="text" style="width:100%;" readonly id="tutar" class="tutar" name="tutar[]"></td>
<td><input type="text" style="width:100%;" id="indirim" class="indirim" name="indirim[]"></td>
<td><input type="text" style="width:100%;" readonly id="indirimtutar" class="indirimtutar" name="indirimtutari[]"></td>
<td><input type="text" style="width:100%;" id="kdv" class="kdv" name="kdv[]"></td>
<td><input type="text" style="width:100%;" readonly id="satirtoplami" class="satirtoplami" name="satirtoplami[]"></td>
<td><button>X</button></td>
</tr>
</table>​
How can I do this?
Your problem is with duplicate Ids.
You should not add two or more elements with the same Id. So, to solve the problem, your dynamically added elements should not have id attributes, then you use the class attribute to target the elements in each row.
Working sample: http://jsfiddle.net/3W48W/2/ (incorporating #Barmar 's answer)
HTM
There are two problems with your code:
First, you're using the same IDs in each row that you add dynamically. IDs are required to be unique.
Second, the .change() binding only applies to elements that are in the DOM at the time the page is loaded. To handle elements added dynamically, you need to use .on() to bind to a permanent element and delegate to the dynamic elements, or bind the event handler to the new row's elements after you append it to the DOM.

Categories