How to traverse dom tree from a list of elements - javascript

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>

Related

How can I change the value that is connected to select change in dynamic form using jquery?

I was trying to make a form, which has two elements, one select item and one input price, select option are stored in database, so I retrieve it and display it.
User can add new row with same elements when button add is clicked, when the select option is changed, I am using ajax to get the price from database and displayed it in the text input.
It all worked fine with the first row but when user add new row I cannot retrieve the price and get the following message
"the specified value "NaN" is not a valid number. The value must match
to the following regular expression:
-?(\d+|\d+.\d+|.\d+)([eE][-+]?\d+)?"
How can I solve this problem or is there is another way to change the value of input using the row id
<table id="tab_logic">
<tr id='row0'>
<td>1</td>
<td>
<select class="form-control item" name="item[]" required>
<?php
$items = "SELECT itemCode, itemName FROM items";
$itemslist = $conn->query($items);
while($row = $itemslist->fetch_assoc()) {
echo "<option value='" . $row["itemCode"] . "'>" . $row["itemName"]. "</option>" ;
}
?>
</select>
</td>
<td>
<input type="text" name='price[]' class="form-control price" required/>
</td>
</tr>
<tr id='row1'></tr>
</table>
<button id="add_row" class="btn btn-default">Add Row</button>
<script>
function get_price(sel, item)
{
$.ajax({
type: "POST",
url : "getData.php",
data: {itemCode: sel },
success: function(data) {
$(item).find("input").val(data.price)
},
});
}
$(document).ready(function(){
//add new row when add buttomn clicked
var i = 1;
$("#add_row").click(function(){
var a = i-1;
$('#row' + i).html( $('#row' + a).html() )
.find('td:first-child')
.html(i+1);
$('#tab_logic').append('<tr id="row' + (i+1) + '"></tr>');
i++;
});
//when selected item change get parent and call function
$('#tab_logic select').on('change', function() {
var item = $(this).parent().parent();
get_price(this.value, item);
});
});
</script>
I solved it finally, the problem was that get_price is only called one time on first change so I solved it using this way by calling the function onclick
<select class="form-control item" name="item[]" onclick="get_price(this.value,$(this).parent().parent());" id='1' required>

javascript not calculating value with same ID

<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.

Javascript adding fields dynamically in table without updating the form

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

How to clear Input data from within JQuery Div

I have a simple form users can fill out and also add a new form to add multiple entries.
Everything works fine except when I enter data in the first set of inputs and click create new memberships it will take the data from the form and put it in the text boxes.
How can I stop that?
http://jsfiddle.net/811yohpn/2/
I have tried a couple different ways.
$('#education').find('input:text').val('');
$('#education: input').val('');
However that will clear all entries.
Call find on the newDiv, instead of all inputs within #education.
Updated fiddle
newDiv.find('input:text').val('');
var ed = 1;
function new_education() {
ed++;
var newDiv = $('#education div:first').clone();
newDiv.attr('id', ed);
var delLink = '<a class="btn btn-danger" style="text-align:right;margin-right:65px" href="javascript:deled(' + ed + ')" > Delete Education ' + ed + ' </a>';
newDiv.find('tr:first th').text('Education ' + ed);
newDiv.append(delLink);
newDiv.find('input:text').val(''); // <----------- added this
$('#education').append(newDiv);
}
function deled(eleId) {
d = document;
var ele = d.getElementById(eleId);
var parentEle = d.getElementById('education');
parentEle.removeChild(ele);
//ed--;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<legend>Education</legend>
<div id="education">
<div id="1">
<table border=3>
<tr>
<th colspan="4" style="background-color:#b0c4de;">Education 1</th>
</tr>
<tr>
<td>
<label>School Name</label>
<input type="text" name="schoolname[]" maxlength="30" size="30"/>
</td>
<td>
<label>Degree Type</label>
<input type="text" name="degreetye[]" maxlength="30" size="30"/>
</td>
<td>
<label>Degree Field</label>
<input type="text" name="degreefield[]" maxlength="30" size="30"/>
</td>
</tr>
</table>
</div>
</div>
<br/><a class="js-addNew btn btn-info" href="javascript:new_education()"> Add New Education </a>
You need to clear the inputs under the cloned element
newDiv.find('input').val('')
Demo: Fiddle
Your selectors are selecting all input elements within the #education container, that is not what you want. The newDiv variable refers to the newly created element so you can use that to find the input elements within in and then clear it

Get Html Attributes inside div

<div>
<table>
<tr>
<td>
<input type="text" id="one" value="1" name="textbox"/>
</td>
<td>
<input type="hidden" id="two" value="2" name="hidden"/>
</td>
</tr>
<tr>
<td>
<input type="radio" name="group2" value="Water"> Water<br>
<input type="radio" name="group2" value="Beer"> Beer<br>
</td>
<td>
<span id="sdf" title="sdf">ok</span>
</td>
</tr>
</table>
<div>
Get Html Attributes inside div,How to get attribute like type,name,value
from above div using dom(traversing) for each elements like input,span etc
a simple search on google returned this guide for javascript. here you can find everything you need
I assume you're asking how to do this with javascript. Here's sample code for the objects with id values. For the other values, put id names on them too and use the same technique.
var input_one = document.getElementById("one");
var input_two = document.getElementById("two");
alert("Input one: type='" + input_one.type + "', name='" + input_one.name + "', value='" + input_one.value + "'");
And a fiddle that shows it in action: http://jsfiddle.net/jfriend00/nZyjN/
using getAttribute( "type" ) we can get value of the particular attribute
The querySelectorAll(selectors) method allows you, for a given element, to retrieve an array of its descendant elements that match given criteria.
For example:
// Replace "yourDiv" with a reference to you main div
var elements = yourDiv.querySelectorAll("input, span");
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
var name = element.name;
var type = element.type;
var value = element.value;
// Now you can do what you want with name, type and value, for example:
alert("Name: "+name+"\r\n"+"Type: "+type+"\r\n"+"Value: "+value);
}
According to the Mozilla Developer Network the querySelectorAll method is supported in IE8, Fx3.5, Chrome1, Opera 10 and Safari 3.2.

Categories