<tr>
<td><input type="text" name="description" required /></td>
<td><input type="text" name="quantity" id="quantity" onkeyup="sum();" required /></td>
<td><input type="text" name="price" id="price" onkeyup="sum();" required /></td>
<td><input type="text" name="lineTotal" id="lineTotal" readonly /></td>
<td><input type="button" onclick="addLine();" value="+" /></td>
</tr>
Below is my javascript code
<script type="text/javascript">
function addLine() {
var tabLines = document.getElementById("tabLines");
var tabLinesRow = tabLines.insertRow(tabLines.rows.length-1);
var col1html = "<input type='text' name='description' />";
var col2html = "<input type='text' name='quantity' id='quantity' onkeyup='sum();' />";
var col3html = "<input type='text' name='price' id='price' onkeyup='sum();' />";
var col4html = "<input type='text' name='lineTotal' id='lineTotal' readonly />";
var col5html = "<input type='button' onclick='removeLine(this);' value='-'>";
var col1 = tabLinesRow.insertCell(0); col1.innerHTML=col1html;
var col2 = tabLinesRow.insertCell(1); col2.innerHTML=col2html;
var col3 = tabLinesRow.insertCell(2); col3.innerHTML=col3html;
var col4 = tabLinesRow.insertCell(3); col4.innerHTML=col4html;
var col5 = tabLinesRow.insertCell(4); col5.innerHTML=col5html;
}
function removeLine(lineItem) {
var row = lineItem.parentNode.parentNode;
row.parentNode.removeChild(row);
}
function sum() {
var q = document.getElementById('quantity').value;
var p = document.getElementById('price').value;
var result = parseInt(q) * parseInt(p);
if(q=="" || p==""){
document.getElementById('lineTotal').value = 0;
}
if (!isNaN(result)) {
document.getElementById('lineTotal').value = result;
}
}
</script>
I am trying to do some calculations here. When i calculate the default single row, it does calculate, when i press on add button and i do some calculations in the second row it works, but when i add more rows it does not calculate. I don't know how to solve it. Please help as i a newbie in javascript
Looks like your problem is that you are duplicating ID's
Try adding an index for your ID's for each row added
ID's are something that has to be unique. If you need to refer to elements that are the same, use class instead.
That right there is your problem. The id attribute in an HTML element should be unique in the entire page. However, you could try to add an index as a suffix for each repeated element in your rows, like "quantity1", "price1", etc.
I also suggest trying out the developer tools within your browser, specially the console and the debugger. There you can run your javascript code step by step (debugger) or on demand (console) to check where do you have an error.
Related
I have HTML snippet which looks like this. I generate this snippet multiple times form the backend. When I click the Save button, I catch which Save button was clicked using $(this) selector. Now I want to grab the attribute item-id of the corresponding Save button. I have the following jquery code snippet. But it does not work. I have tried to look but I don't know where the error is.
<td><input type="text" size="10" value="val1" item-id="id1"></td>
<td><input type="text" value="val2" size="4"></td>
<td>
<button class="btn btn-primary save-btn">Save</i></button>
</td>
Here is the jquery snippet
$(".save-btn").click(function(){
var ems = $(this).parent().siblings();
var item_id = ems[0].child().attr("item-id");
}
click doesn't work on dynamically added elements.You need to use on('click'). Also there is no method .child() so you need to use .children().first().
This is the corrected code:
$(document).on('click', '.save-btn', function(){
var ems = $(this).parent().siblings();
var item_id = ems.children().first().attr("item-id");
});
// The text
var text="";
text += "<td><input type=\"text\" size=\"10\" value=\"val1\" item-id=\"id1\"><\/td>";
text += "<td><input type=\"text\" value=\"val2\" size=\"4\"><\/td> ";
text += "<td>";
text += " <button class=\"btn btn-primary save-btn\">Save<\/i><\/button>";
text += "<\/td>";
// Adding the text to html
$('body').html(text);
$(document).on('click', '.save-btn', function(){
var ems = $(this).parent().siblings();
console.log(ems);
var item_id = ems.children().first().attr("item-id");
alert(item_id);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
better replace item-id="id1" to data attribute html5 data-id="id1" then replace code attr('item-id') to data('id')...
$(document).on('click','.save-btn', function(){
var ems = $(this).parent().siblings(),
item_id = ems.eq(0).children('input').attr("item-id");
alert(item_id);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td><input type="text" size="10" value="val1" item-id="id1"></td>
<td><input type="text" value="val2" size="4"></td>
<td>
<button class="btn btn-primary save-btn"><i>Save</i></button>
</td>
</tr>
</table>
I have a table with some records, In each row tr I have two Textbox in two TD,
All textboxes don't have Id and Class, They just have a Name, Their Names Are like below
PurchaseDetails[some number].Quantity
PurchaseDetails[some number].PurchasePrice
Like:
PurchaseDetails[1457160526936].Quantity
PurchaseDetails[1457160526936].PurchasePrice
I use below codes but doesn't work:
var ProductQuantity = $(this).find("input[name=PurchaseDetails[/^[0-9]+$/].Quantity]").val();
var ProductPurchase = $(this).find("input[name=PurchaseDetails[/^[0-9]+$/].PurchasePrice]").val();
my complete html code is :
<tr >
<td><input type="text" class="form-control" name="PurchaseDetails[1457161853893].Quantity" ></td>
<td><input type="text" class="form-control" name="PurchaseDetails[1457161853893].PurchasePrice" ></td>
</tr>
If there is only one element with that prefix and suffix in the current context($(this)), attribute starts with selector and attribute ends with selector can be used.
$(this)
.find('input[name^="PurchaseDetails"][name$="Quantity"]').val();
You can use filter() for filtering using regex
// replace `$('input')` to `$(this).find('input')` to avoid searching in global context
var ProductQuantity = $("input").filter(function() {
return /^PurchaseDetails\[\d+\]\.Quantity$/.test(this.name);
}).val();
var ProductPurchasePrice = $("input").filter(function() {
return /^PurchaseDetails\[\d+\]\.PurchasePrice$/.test(this.name);
}).val();
console.log(ProductQuantity, ProductPurchasePrice);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input name="PurchaseDetails[1457160526936].Quantity" value=1 />
<input name="PurchaseDetails[1457160526936].PurchasePrice" value=2 />
JSFiddle with the code: http://jsfiddle.net/wxLa80od/
I have a html page which is looks like:
<form action="cvformphp.php" method="post">
<table id="cvtable">
<tr><td><h2>Personal Info</h2></td></tr>
<tr><td>Name* </td> <td><input type="text" name="name"></td></td>
<tr><td>Email* </td><td><input type="Email" name="email"></td></tr>
<tr><td><h2>Experiences</h2></td></tr>
<tr><td>Job role </td><td><input type="text" id="role1" name="role1"></td> <td>Company name</td><td><input type="text" id="comp1" name="comp1"></td </tr>
<input type="text" hidden="hidden" value="1" id="countexp" name="countexp"/>
<tbody id="exp" name="exp"></tbody>
<tr><td></td><td><input type="button" id="2" value="+ Add More" onclick="addExp()"/></td></td></tr>
</table>
</form>
with javascript code
<script>
var countBox =2;
function addExp()
{
document.getElementById("countexp").value= countBox;
document.getElementById("exp").innerHTML +="<br/><tr><td>Job role</td><td>
<input type='text' id='role"+ countBox +"' name='role"+ countBox+"'/></td>
<td>Company name</td><td><input type='text' name='comp"+ countBox +"'
id='comp"+countBox +"''/> </td></tr>";
countBox += 1;
}
</script>
The code is running well but the problem is when I click "Add more" button the dynamic added fields is getting empty!
I want to fill all data in the form so I can pass them to php file.
Could someone perhaps tell me please how I can not clear the fields?
Thanks in advance.
When using innerHtml, you ALWAYS replace the content with the newly defined content, even if you use +=. That's why your dynamic content is empty after each click on the button.
I will provide 2 solutions for this problem. One of them requires the use of jQuery, the other doesn't (but is more complicated):
Solution 1 (WITH jQuery)
function addExp()
{
document.getElementById("countexp").value= countBox;
$("#exp").append("<tr><td>Job role</td> \
<td><input type='text' id='role"+ countBox +"' \
name='role"+ countBox+"'/></td><td>Company name</td>\
<td><input type='text' name='comp"+ countBox +"' \
id='comp"+countBox +"''/> </td></tr>");
countBox += 1;
}
jsFiddle: http://jsfiddle.net/wxLa80od/4/
Solution 2 (WITHOUT jQuery)
function addExp()
{
document.getElementById("countexp").value= countBox;
var newChild = document.createElement("tr");
document.getElementById("countexp").value= countBox;
// Create an empty <tr> element and add it to the 1st position of the table:
var row = document.getElementById("exp").insertRow(-1);
// Insert new cells (<td> elements) at the 1st and 2nd position of the "new" <tr> element:
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var cell4 = row.insertCell(3);
// Add some text to the new cells:
cell1.innerHTML = "Job role";
cell2.innerHTML = "<input type='text' id='role"+ countBox +"' name='role"+ countBox+"'/>";
cell3.innerHTML = "Company name";
cell4.innerHTML = "<input type='text' name='comp"+ countBox +"'id='comp"+countBox +"''/>";
countBox += 1;
}
jsFiddle: http://jsfiddle.net/wxLa80od/2/
Also a quick note: do NOT use <br/> in between two rows <tr>, it can create a mess really quickly. Please use css for this (example: margin-bottom: 15px;)
innerHTML does not get the value inputted from keyboard. You may use appendChiled. In that case you should create element using createElement statement. It is easier to use jquery. Try following code
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script>
var countBox =2;
function addExp()
{
document.getElementById("countexp").value= countBox;
$("#exp").append("<br><tr><td>Job role</td><td><input type='text' id='role"+ countBox +"' name='role"+ countBox+"'/></td><td>Company name</td><td><input type='text' name='comp"+ countBox +"' id='comp"+countBox +"''/> </td></tr>");
countBox += 1;
}
</script>
</head>
<body>
<form action="cvformphp.php" method="post">
<table id="cvtable">
<tr><td><h2>Personal Info</h2></td></tr>
<tr><td>Name* </td> <td><input type="text" name="name"></td></td>
<tr><td>Email* </td><td><input type="Email" name="email"></td></tr>
<tr><td><h2>Experiences</h2></td></tr>
<tr><td>Job role </td><td><input type="text" id="role1" name="role1"></td> <td>Company name</td><td><input type="text" id="comp1" name="comp1"></td ></tr>
<input type="text" hidden="hidden" value="1" id="countexp" name="countexp"/>
<tbody id="exp" name="exp"></tbody>
<tr><td></td><td><input type="button" id="2" value="+ Add More" onclick="addExp()"/></td></td></tr>
</table>
</form>
</body>
</html>
According to answer of this question I agreed. But! we can do the needful for the required/expected result as below and also can make your own stuff for the expected/required result if you know JavaScript well.
function getInputValues(container){
if(!(container instanceof Node) || !(container instanceof HTMLElement)){
container = document.querySelector(container);
}
let values = {};
container.querySelectorAll("INPUT").forEach((el)=>{
values[el.name] = el.value;
});
return values;
}
function setInputValues(container, values){
if(!(container instanceof Node) || !(container instanceof HTMLElement)){
container = document.querySelector(container);
}
Object.keys(values).forEach((key)=>{
container.querySelector("INPUT[name='"+key+"']").value = values[key];
});
}
Before the document.getElementById("exp").innerHTML += you have to get the values and after the added/updated html you have to set the values for the same inputs and if you want to use input name as array then you can set the index values also and also can change the input attribute from name to id or any other unique attribute from the function of getInputValues to make everything woks perfectly.
I wrote this code for my own project and you also can make your own if required otherwise it'll help's you
FIDDLE DEMO
var oldValue;
$(document).on('keydown','.main', function (e) {
oldValue = $(this).val();
});
var newValue;
$(document).on('keyup', '.main',function (e) {
newValue = $(this).val();
foo(oldValue,newValue);
});
function foo(orig){
$('#table2').find('tbody tr').each(function (i) {
var $td2 = $(this).find('td input:text');
if (orig == $td2.val()) {
$td2.val(newValue);
}
});
}
This is what happens,if I change "Apple" on table 1 slowly typing, "Apple" input field changes, but If I type too fast, my code is not working.
What if you add some relation between the original input-field and the corresponding like:
<input type='text' class= 'main' value="Apple" rel="sec_apple"/>
and
<input type='text' value="Apple" class="sec_apple"/>
for the second input.
Then you javascript could look like this:
$(document).on('keyup', '.main',function (e) {
foo($(this));
});
function foo(orig){
rel = orig.attr('rel');
var sec = $('.' + rel);
sec.val(orig.val());
}
Demo
Use JavaScript rather than jQuery. jQuery has a lot of overhead and can be too slow.
Probably not the case here. You do need to explain the issue a little better.
I ran a test and could not miss a key stroke, with my code.
My test routine changes the color of the background on each onkeyup.
I only used the two text inputs in table 1 to the right of Apple and banana.
Because I do not understand what you are doing, my test routine changes the color of the background on each onkeyup. If I type in 123456789 as fast as possible in both text fields they both come end with the correct color.
You may notice that I declare the inputs globally and use arrays instead of if else. Things that cannot be done efficiently with jQuery.
The reason I abandoned jQuery is I found jQuery to be way too slow on an iPad.
The following is tested at: This test Location
<!DOCTYPE HTML>
<html lang="en"><head><title>keys</title></head><body>
Table1
<form id='form1'>
<table id='table1'><tbody>
<tr><td><input type='text' class= 'main' value="Apple"/></td>
<td><input id="t1" type='text' class= 'main' value="" onkeyup="key(1)"/></td>
</tr><tr>
<td><input type='text' class= 'main' value="Banana" /></td><td><input id="t2" type='text' value="" onkeyup="key(2)"/></td>
</tr></tbody></table>
Table2
<table id='table2'><tbody>
<tr><td><input type='text' value="Apple" /></td></tr>
<tr><td><input type='text' value="Banana" /></td></tr>
<tr><td><input type='text' value="Banana" /></td></tr>
</tbody></table>
<br />
</form>
<script type="text/javascript">
//<![CDATA[
var color = new Array;
color[0] = '#f00';
color[1] = '#f0f';
color[2] = '#ff0';
color[3] = '#0ff';
var nc=[0,0,0];
var next = [1,2,3,0];
var txt=new Array;
txt[1] = document.getElementById('t1');
txt[2] = document.getElementById('t2');
function key(id){
nc[id] = next[nc[id]];
txt[id].style.background=color[nc[id]];
}
//]]></script></body></html>
I have this form.
<table><tr><td>
<FORM>
<label> ID </label></td>
<td>
<input type=text id="inputp1_id" size=24 class="text">
</td></tr>
<tr><td>
<label>Type</label></td><td><select id="inputp1_type" name="inputp1_type"><option value="text">Text</option><option value="integer">Integer</option><option value="float">Float</option><option value="list_values">List of values</option>
<option value="range">Range</option><option value="selection_collapsed">Selection (collapsed)</option><option value="selection_expanded">Selection (expanded)</option><option value="subimage">Subimage selection</option>
<option value="polygon">Polygon selection</option><option value="horizontal_separator">Horizontal separator</option></select>
</td></tr>
<tr><td> <label > Description</label></td> <td><input type=text id="inputpi_description" size=24 class="text"> </td><!--style=" width:300px; height:20px;"-->
</tr>
<tr><td> <label>Value</label></td><td> <input type="text" name="inputp1_value" id="inputp1_value" class="text" size=24></td></tr>
<tr><td> <label > Info (help)</label></td><td>
<input type=text id="input1_value" size=24 class="text"></td></tr>
<tr><td><label > Visible?</label></td><td><input type="checkbox" name="inputp1_visible" id="inputp1_visible"></td></tr></table>
<!--</form>--></div>
But (it's possible?) can create the id's input box?
Because the variable these are "numbered".
For example the first id in the form is inputp1_id but the number i want use how variable.
It's possible create the id with the Javascript o Jquery?
l=3
Id='inputp' +l+'_id'
After this create the input text has the id=inputp3_id
Here is one example on how to generate html contents dynamically with jquery and javascript. Both methods, although they look similar, give a bit different results: jquery generates one additional <tbody> tag, while javascript inserts the new rows directly to <table>. I recommend you to inspect the result in the Firefox's DOM Inspector by pressing Ctrl+Shift+I. IT's very handy and effective tool. And here is the algorythm:
var i=0; // this is simple counter
function generate_row_dynamically_in_jquery() {
i++;
var new_row = $('<tr/>');
var new_cell1 = $('<td>ID <input type="text" name="inputp'+i+'_id" id="inputp'+i+'_id" size="24" class="text"/></td>');
var new_cell2 = $('<td>Visible? <input type="checkbox" name="inputp'+i+'_visible" id="inputp'+i+'_visible"> </td>');
new_row.append(new_cell1).append(new_cell2);
$('#table1').append(new_row);
}
function generate_row_dynamically_in_javascript() {
i++;
var new_row = document.createElement('tr');
var new_cell1 = document.createElement('td');
new_cell1.innerHTML = 'ID <input type="text" name="inputp'+i+'_id" id="inputp'+i+'_id" size="24" class="text"/>';
var new_cell2 = document.createElement('td');
new_cell2.innerHTML = ' Visible? <input type="checkbox" name="inputp'+i+'_visible" id="inputp'+i+'_visible">';
new_row.appendChild(new_cell1);
new_row.appendChild(new_cell2);
document.getElementById('table1').appendChild(new_row);
}
& #jsfiddle