I have gone through google and some of SO questions (such as this & this) as well but I didn't find the solution.
I am working for validation of a dynamically generated rows in a table,initially I am trying to validate the first td, loop and alert is working all fine but document.getElementById() is giving a null value. The script is at the very bottom of the page.
and here is the JS code.
edit: I have added the code, and what I am trying to do is display the error (Please fill) when field is left blank on the click of submit button and hide it when it is filled.
$(function(){
$(document).on("click",".addRowAux",function(){
/*var valanx1 = $(this).parents("tr").children("td:nth-child(2)").children("input").val();
var valanx2 = $(this).parents("tr").children("td:nth-child(3)").children("input").val();
var valanx3 = $(this).parents("tr").children("td:nth-child(4)").children("select").val();
var valanx4 = $(this).parents("tr").children("td:nth-child(4)").children("input").val();*/
var countrow= $("#annextable tr").length;
/*countrow++;*/
if(countrow<11)
{
$("#aux").append('<tr><td align="center">'+countrow+'</td><td align="center"><input type="text" name="ref_name[]" id="ref_name"/><span id="refNm_error">Please fill</span></td><td align="center"><input type="text" name="ref_desg[]" id="ref_desg"/></td><td align="center"><input type="text" name="ref_address[]" id="ref_address"/></td><td align="center"><input type="text" name="ref_email[]" id="ref_email"/></td><td align="center"><input type="text" name="ref_mobile[]" id="ref_mobile"/></td><td align="center"><input type="text" name="ref_pan[]" id="ref_pan"/></td><td align="center"><span class="addRowAux">Add</span> <span id="removeRowaux">Remove</span></td></tr>');
}
else
{
//countrow--;
alert("Can not add more then 10 record.");
}
});
});
$(document).on('click', '#removeRowaux', function () { // <-- changes
var countrow= $("#annextable tr").length;
if(countrow>3)
{
$(this).closest('tr').remove();
var tblObj = document.getElementById('annextable');
var no_of_rows = tblObj.rows.length;
for(var i=0; i<no_of_rows-1; i++)
{
tblObj.rows[i+1].cells[0].innerHTML = i+1;
tblObj.rows[i+1].cells[1].setAttribute( "delThis", i+1);
////alert(kj);
//document.getElementById("refNm_error").id ="refNm_error"+j;
}
}
else{
alert("you can not delete this")
}
});
$(document).on('click', '#hods', function () {
var tblObj = document.getElementById('annextable');
var no_of_rows = tblObj.rows.length;
for(var i=0; i<no_of_rows-1; i++)
{tblObj.rows[i+1].cells[1].setAttribute( "delThis", i+1)
var j=tblObj.rows[i+1].cells[1].getAttribute("delThis");
document.getElementById("refNm_error").id ="refNm_error"+j;
}
});
$(function(){
$(document).on('change', '.rel_type', function() {
var relation = $(this).val();
if(relation =='OT'){
$(this).next("input").show();
$(this).next("input").val("Please Specify");
}
else{
$(this).next("input").hide();
$(this).next("input").val("")
}
});
});
function yoVal(){
var refNm =document.getElementsByName('ref_name[]');
for(var i=0;i<=refNm.length;i++) {
if(refNm[i].value==""){
alert("success");
}
else{
var ch ='refNm_error'+(i+1);
alert(ch);
//document.getElementById(ch).style.display = "none";
alert("fail")
}
}}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="refForm">
<table width="99%" border="1" id="annextable" style="border-collapse:collapse" align="center">
<thead>
<tr style="background:#ddd;">
<th>S.No</th>
<th>Name</th>
<th>Designation</th>
<th>Address</th>
<th>Email</th>
<th>Mobile</th>
<th>PAN</th>
<th>Action</th>
</tr>
</thead>
<tbody id="aux">
<tr>
<td align="center">1</td>
<td align="center"><input type="text" name="ref_name[]" id="ref_name"/><br/><span id="refNm_error">Please fill</span></td>
<td align="center"><input type="text" name="ref_desg[]" id="ref_desg"/></td>
<td align="center"><input type="text" name="ref_address[]" id="ref_address"/></td>
<td align="center"><input type="text" name="ref_email[]" id="ref_email"/></td>
<td align="center"><input type="text" name="ref_mobile[]" id="ref_mobile"/></td>
<td align="center"><input type="text" name="ref_pan[]" id="ref_pan"/></td>
<td align="center">
<span class="addRowAux">Add</span> <span id="removeRowaux">Remove</span></td>
</tr>
</tbody></table>
<input type="button" onclick="yoVal()" value="Test" id="hods"/>
</div>
Because you are adding extra quotes in beginning and end in variable k. use:
var k = 'refNm_error' + (i+1);
You might need to reload the DOM after adding dynamic elements.
This link might help
Update, when you created your dynamic table rows for the table you didn't assign unique ids for input elements. So I updated the addRow handler:
$(document).on("click", ".addRowAux", function () {
to add unique input ids, like following:
$("#aux").append('<tr><td align="center">' + countrow + '</td><td align="center"><input type="text" name="ref_name[]" id="ref_name_' + countrow + '"/><span id="refNm_error_' + countrow + '">Please fill</span>...
and also I changed in the code:
<span id="removeRowaux">Remove</span>
to use class instead of an id:
<span class="removeRowaux">Remove</span>
Now the remove row handler listens to events from spans with class removeRowaux:
$(document).on('click', '.removeRowaux', function ()
Now the remove row functionality works and there are no spans with identical ids. So I don't think there was anything wrong with getElementById() in the code - it works fine :-)
Updated Fiddle
Related
I have a script to generate a 10 character code when a button is clicked. I want to transplant the code into the value field of a input text-box. I believe there is a conflict because the text-box is within a form that has a click(function(event) { attached.
HTML/CSS
<div id="add_wrap">
<form method="post" action="voucher_add_post.php">
<table width="100%" border="0" cellspacing="2" cellpadding="2">
<tr>
<td>Voucher value: </td>
<td><input type="text" id="value" size="10"></td>
</tr>
<tr>
<td>Code</td>
<td><input type="text" id="code" size="20"> <button id="generate">Generate</button></td>
</tr>
<tr>
<td>How many vouchers?</td>
<td><input type="text" id="amount" placeholder="Leave blank for only one voucher" size="40"></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" id="submit" value="Submit" /></td>
</tr>
</table>
</form>
<div id="message"></div>
</div>
Javascript/JQuery
<script>
$("#submit").click(function(event) {
event.preventDefault();
var headline = $('#headline').val();
var author = $('#author').val();
var details = $('#details').val();
var question = $('#question').val();
var reward_img = $('#reward_img').val();
var reward_cap = $('#reward_cap').val();
var days = $('#days').val();
$.ajax({
type: "POST",
url: "pages/comp_add_post.php",
data: "headline="+headline+"&author="+author+"&details="+details+
"&question="+question+"&reward_img="+reward_img+"&reward_cap="+reward_cap+"&days="+days,
success: function(data){
$("#message").html(data);
}
});
});
$("#generate").click(function(event) {
event.preventDefault();
function codeGen(length)
{
var code = "";
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i=0; i<length; i++);
code += chars.charAt(Math.floor(Math.random() * chars.length));
return code;
}
$("#code").val(codeGen(10));
});
</script>
The problem is it only generates a single character into the value= attribute of the input box with an ID of generate.
If I use the onClick="codeGen()" method of doing it, then it submits the form.
I think the issue is in your for loop. You currently have it written as:
for (var i=0; i<length; i++);
code += chars.charAt(Math.floor(Math.random() * chars.length));
But the ; after the for loop declaration terminates the statement. If you rewrite it as:
for (var i = 0; i < length; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length));
}
It seems to work.
Fiddle: https://jsfiddle.net/s3ndkpue/
The for loop with the semi colon is the issue, however I would also try and simplify the JS + Jquery so it is easier to read as below:
$("#generate").click(function(event) {
event.preventDefault();
var code = "";
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i=0; i < 10; i++)
code += chars.charAt(Math.floor(Math.random() * chars.length));
$("#code").val(code);
});
Hope that helps :)
I have a web page for applying. In this web page, rows are dynamic add after addp button clicked.I can add new row successfully with addPf() method. And these input name attribute should be enName0, enName1, enName2....., but it works fail with name="enName"+aDWI.
Here is my html code:
<div>
<table>
<tr>
<td>
<input type="button" id="addP" onclick="addPf()" value="addPeople">
</td>
</tr>
<tr>
<td>
new row added in here;
</td>
</tr>
</table>
</div>
Here is my javascript code:
<script>
var aDWI=0;
function addPf()
{
newrow = '<tr><td><input style="width:98%" name="enName"+aDWI></td></tr>';
$(newrow).insertAfter($('#staTable tr:eq('+aDWI+')'));
aDWI = aDWI + 1;
}
</script>
name="enName"+aDWI is not right.I have no idea about this, who can help me ?
Change from
newrow = '<tr><td><input style="width:98%" name="enName"+aDWI></td></tr>';
to
newrow = '<tr><td><input style="width:98%" name="enName'+aDWI+'"></td></tr>';
The issue is because you need to concatenate the variable in the string correctly, using the ' character.
Also note that you should really be using unobtrusive event handlers instead of the outdated on* event attributes. In addition, you can simplify the logic by using jQuery's append(), like this:
var aDWI = 0;
$('#addP').click(function() {
newrow = '<tr><td><input style="width:98%" name="enName' + aDWI + '" value="' + aDWI + '"></td></tr>';
$('#staTable').append(newrow);
aDWI = aDWI + 1;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<table id="staTable">
<tr>
<td>
<input type="button" id="addP" value="addPeople">
</td>
</tr>
<tr>
<td>
new row added in here;
</td>
</tr>
</table>
</div>
Just update it with
<script>
var aDWI=0;
function addPf()
{
newrow = '<tr><td><input style="width:98%" name="enName'+aDWI+'"></td></tr>';
$(newrow).insertAfter($('#staTable tr:eq('+aDWI+')'));
aDWI = aDWI + 1;
}
</script>
I am pretty new to jquery. I have the following code. Here I wants to get new rows in the table on clicking add button in Fill 3. I succeend to add that row, but when I get new divs then I wants to get new rows in the table on clicking add button in Fill 3. It added into wrong div.
can someone tell me what mistake I've done here?
var id = 0; //global id to create unique id
$(document).ready(function() {
//attach click event to element/button with id add and remove
$("#add,#remove").on('click', function() {
var currentElemID = $(this).attr('id'); //get the element clicked
if (currentElemID == "add") { //if it is add elem
var cloneParent = $("#dataTes").clone(); //clone the dataTes element
id=$("div[id^=dataTes]").length + 1;//get the count of dataTes element
//it will be always more than last count each time
cloneParent.find('[id]').each(function() {
//loop through each element which has id attribute in cloned set and replace them
//with incremented value
var $el = $(this); //get the element
$el.attr('id', $el.attr('id') + id);
//ids would now be add1,add2 etc.,
});
cloneParent.attr('id', cloneParent.attr('id') + id);//replace cloneParent id
cloneParent.appendTo('#result');//append the element to fieldset
$("#remove").show();//show remove button only if there is more than one dataTes element
} else {
$("div[id^=dataTes]:last").remove();
//just remove the last dataTes
//[id^=dataTes]:last annotates remove last div whose id begins with dataTes
//remember we have id like dataTes1,dataTes2 etc
if($("div[id^=dataTes]").length==1){
//check if only one element is present
$("#remove").hide();//if yes hide the remove button
}
}
});
});
function addRow(tableID) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
var colCount = table.rows[0].cells.length;
for (var i = 0; i < colCount; i++) {
var newcell = row.insertCell(i);
newcell.innerHTML = table.rows[0].cells[i].innerHTML;
}
}
function deleteRow(tableID) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
if (rowCount > 1) {
table.deleteRow(rowCount - 1);
}
else {
alert("Tidak dapat menghapus semua baris!");
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<fieldset id="result">
<legend>Test</legend>
<input type="submit" class="button" id="add" value="+" title="#">
<input type="submit" class="button" id="remove" value="-" style="display:none;" title="#">
<!--hide the remove button with display:none initially-->
<div id="dataTes">
<table align="center" cellpadding="3" cellspacing="0" style="border-collapse:collapse;margin-top:10px;" width="97%">
<tr>
<td width="100px">Test</td>
<td width="2px">:</td>
<td>
<input type="text" name="usrname">
</td>
</tr>
<table align="center" cellpadding="3" cellspacing="0" style="border-collapse:collapse;margin-top:5px;margin-left:40px;" width="97%">
<tr>
<td width="2px"></td>
<td width="100px">Fill 1</td>
<td width="2px">:</td>
<td>
<input type="text" name="usrname">
</td>
</tr>
<tr>
<td width="2px"></td>
<td width="100px">Fill 2</td>
<td width="2px">:</td>
<td>
<input type="text" name="usrname">
</td>
</tr>
<table id="dataIP" align="center" cellpadding="3" cellspacing="0" style="border-collapse:collapse;margin-left:40px;" width="97%">
<tr>
<td width="2px"></td>
<td width="100px">Fill 3</td>
<td width="2px">:</td>
<td width="2px">
<input type="text" name="usrname">
</td>
<td>
<input type="submit" class="button" value="+" onClick="addRow('dataIP')" title = "#">
<input type="submit" class="button" value="-" onClick="deleteRow('dataIP')" title = "#">
</td>
</tr>
</table>
</table>
</table>
</div>
</fieldset>
Thanks in advance!
<table id="dataIP" align="center" cellpadding="3" cellspacing="0" style="border-collapse:collapse;margin-left:40px;" width="97%">
<tr>
<td width="2px"></td>
<td width="100px">Fill 3</td>
<td width="2px">:</td>
<td width="2px">
<input type="text" name="usrname">
</td>
<td>
<input type="submit" class="button" value="+" onClick="addRow('dataIP')" title = "#">
<input type="submit" class="button" value="-" onClick="deleteRow('dataIP')" title = "#">
</td>
</tr>
</table>`
so what will we do here is that we will change addRow(this) instead of addRow('dataIp') because we know that "this" keyword has a high priority in terms of passing the ID of the element .. the "this" keyword has a general purpose vs passing of id into a function .. just try changing all parameter to the "this".
function addRow(tableID) {
var par = tableID.parentNode.parentNode.parentNode.id;
var table = document.getElementById(par);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
var colCount = table.rows[0].cells.length;
for (var i = 0; i < colCount; i++) {
var newcell = row.insertCell(i);
newcell.innerHTML = table.rows[0].cells[i].innerHTML;
}
this is what ive done when I change the parameter of the add and delete function in your input i get the param parent node the element for the purpose of specific element inside the parent element...
}
by the way.. you must change your third index table to tbody. the result of getting the parentnode will be a tbody. because putting table inside a table is redundant window read it as tbody
we must follow the rule
<table>
<tbody>
</tbody>
<tfoot>
</tfoot>
</table>
I don't have much experience in jQuery, I'm facing the following challenge
I have the following table
<table>
<thead>
<tr>
<td>Qty</td>
<td>Description</td>
<td>Unit Price</td>
<td>Total Price</td>
<tr>
</thead>
<tbody>
<tr id="itemRow">
<td><input type="text" name="quantity"/></td>
<td><input type="text" name="description"/></td>
<td><input type="text" name="unitPrice"/>/td>
<td><input type="text" name="totalPrice"/></td>
<tr>
</tbody>
</table>
<input type="text" name="total"/>
Additionally, I'm able to clone #itemRow as many times as required, enlarging the amount of items.
The idea is to calculate the total price for each row (by quantity * unitPrice) and assign it to totalPrice. And assign the sum of totalPrice to total.
This is the javascript I'm using, but I get an error that says "cantidades[i].val() is not a function"
function calculate(){
var $total = $('#total');
var $cantidades = $('input[name=quantity]')
var $unitarios = $('input[name=unitPrice]')
var $totales = $('input[name=totalPrice]')
var len = $cantidades.length;
$total.val(0);
for (var i = 0; i < len; i++){
// calculate total for the row. ERROR HERE!
$totales[i].val($cantidades[i].val() * $unitarios[i].val());
// Accumulate total
$total.val($totalExento.val() + $totales[i].val());
}
}
What am I missing? I think I'm not getting "jQuery objects" from the selector but I'm not sure hot to do this.
Thanks in advance!
This line: var $cantidades = $('input[name=quantity]') retrieves a jQuery instance that cannot be accessed like you did with $cantidades[i].
Fix it like this:
var singleElementCantidades = $($cantidades[i]);
singleElementCantidades.val();
What happened is that $('input[name=quantity]') retrieves an array that is an instance of jQuery. And when you access its content by using cantidades[i] you are not managing a jQuery instance anymore, you are accessing something else wich doesn't have the definition of val.
$cantidades would give you a jquery object however by using index or 'get' property would actually give you the equivalent javascript object. So in your case, you would need to use $cantidades[i].value. instead of $cantidades[i].val().
for (var i = 0; i < len; i++){
$totales[i].value = $cantidades[i].value * $unitarios[i].value;
$total.val($totalExento.val() + $totales[i].value);
}
I think you cannot globally get $('input[name=quantity]'), $('input[name=unitPrice]') and $('input[name=totalPrice]').
You should identify them for each row.
Here a example on jsfiddle
<table>
<thead>
<tr>
<td>Qty</td>
<td>Description</td>
<td>Unit Price</td>
<td>Total Price</td>
</tr>
</thead>
<tbody>
<tr>
<td><input type="number" name="quantity"/></td>
<td><input type="text" name="description"/></td>
<td><input type="number" name="unitPrice"/></td>
<td><input type="number" name="totalPrice"/></td>
</tr>
</tbody>
</table>
<button type="button" id="addRow">addRow</button>
<button type="button" id="calculate">calculate</button>
<input type="number" name="total" id="total"/>
The js part:
$(document).ready(function () {
var $total = $('#total');
var $addRow = $('#addRow');
var $calculate = $('#calculate');
var $emptyRow = $('tbody tr').clone();
var $body = $('tbody');
$addRow.on('click', function () {
$body.append($emptyRow.clone());
});
$calculate.on('click', function () {
var total = 0;
$body.find('tr').each(function () {
var $row = $(this);
var q = Number($row.find('[name=quantity]').val());
var p = Number($row.find('[name=unitPrice]').val());
var subTotal = q * p;
$row.find('[name=totalPrice]').val(subTotal)
total += subTotal;
});
$total.val(total);
})
});
i created a button that allows you to clone a tree of elements. This is my code:
function add_party(number) {
var n = number.replace("party", "");
var newparty = document.getElementById("party"+n);
var div = document.createElement("div");
var con = document.getElementById("party1").innerHTML;
document.createElement("div");
div.id = 'party' + ++n;
div.innerHTML = con;
newparty.parentNode.insertBefore(div, newparty.nextSibling);
renumberDivs(div, n, "div","party");
}
This is my HTML:
<div id="party1">
<h1>Party 1</h1>
<table>
<tbody>
<tr>
<th>party name:</th>
<td><input type="text" name="name1" value="some name"></td>
</tr>
<tr>
<th>party time:</th>
<td><input type="text" name="time1" value="some time"></td>
</tr>
</tbody>
</table>
<input type="button" onclick="add_party(this.parentNode.id)" value="add party">
</div>
However, since each element has an unique ID or name the clone should not have the same IDs or names. Instead the new IDs and names should add up by 1. So the cloned tree should look like this:
<div id="party2">
<h1>Party 2</h1>
<table>
<tbody>
<tr>
<th>party name:</th>
<td><input type="text" name="name2" value=""></td>
</tr>
<tr>
<th>party time:</th>
<td><input type="text" name="time2" value=""></td>
</tr>
</tbody>
</table>
<input type="button" onclick="add_party(this.parentNode.id)" value="add party">
</div>
Also, the input values should be empty for the clone. How can i do it with javascript? (no jQuery please).
Thank you.
EDIT:
this code updates the count numbers so they always appear in order:
function renumberDivs(el, n, tagn, ass) {
while (el = el.nextSibling) {
if (el.tagName && el.tagName.toLowerCase() == tagn){
el.id = ass + ++n;
}
}
}
Generally, this solution is a 2-step process:
manipulate existing parties one by one from the last to the insert point.
insert new party to the insert point.
function add_party(divId) {
var party = document.getElementById(divId);
var newParty = party.cloneNode(true);
var allParties = document.querySelectorAll('div[id^="party"]');
var newId = parseInt(divId.replace('party', ''), 10) + 1;
for(var i = allParties.length-1; i > newId-2; i--) {
allParties[i].setAttribute('id', 'party' + (i+2));
allParties[i].querySelector('h1').innerHTML = 'Party ' + (i+2);
var partyInputs = allParties[i].querySelectorAll('input[type="text"]');
for(var j = 0; j < partyInputs.length; j++) {
var prefix = partyInputs[j].getAttribute("name").replace(/\d+/, "");
partyInputs[j].setAttribute("name", prefix + (i+2));
}
}
newParty.setAttribute('id', 'party' + newId);
newParty.querySelector('h1').innerHTML = 'Party ' + newId;
var inputs = newParty.querySelectorAll('input[type="text"]');
for(var i = 0; i < inputs.length; i++) {
var prefix = inputs[i].getAttribute("name").replace(/\d+/, "");
inputs[i].setAttribute("name", prefix + newId);
inputs[i].setAttribute("value", "");
inputs[i].value = "";
}
party.parentNode.insertBefore(newParty, party.nextSibling);
}
<div id="party1">
<h1>Party 1</h1>
<table>
<tbody>
<tr>
<th>party name:</th>
<td><input type="text" name="name1" value="some name"></td>
</tr>
<tr>
<th>party time:</th>
<td><input type="text" name="time1" value="some time"></td>
</tr>
</tbody>
</table>
<input type="button" onclick="add_party(this.parentNode.id)" value="add party">
</div>
you'd better attach event to element using addEventListener. I found it works fun. Please refer to DEMO..., but there is a question, for the new generated form, there is no event handler attached, so you should attach new event handler for new generated form. if you can use jQuery or some others, you can use function like Delegate that bind event handler automatically