JQuery/Ajax function not working for a new row generated - javascript

I'm trying to implement a function for a dinamic table, the table starts like this:
<table>
<thead><tr><th>Código</th><th>Nombre</th><th>Cantidad</th><th>Precio</th></tr></thead>
<tbody id="bodyVender">
<tr>
<td><input id="inp0" type="text" autofocus="true" class="form-control"></td> <td id="tdN0"></td> <td><input id="tdC0" type="text" class="form-control"></td> <td id="tdP0"></td>
</tr>
</tbody>
</table>
And then i'm adding more table rows to the tbody when the JQuery function is called, like this:
$('#bodyVender').append('<tr><td><input id="inp'+count+'" type="text" class="form-control"></td> <td id="tdN'+count+'"></td> <td><input id="tdC'+count+'" type="text" class="form-control"></td> <td id="tdP'+count+'"></td></tr>');
As you can see, the new row created will have tds and inputs with a new ID determined by the "count" variable, so that input ID could look like: inp0 , inp1, inp2 after each function call.
This works, but just the first time, even when I'm calling the function for that new created ID.
I'm using $(document).on to call the function, and I think that should work for the new row created.
Here's the entire code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Panel de Administración</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="estilo3.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(Principal);
function Principal(){
var count = 0; //sell's counter
$(document).on('keydown','#inp'+String(count), function(e){ //when press key on input with id="inp0"
if(event.keyCode == 13){ //if the key pressed is Enter
VenderConsulta($(this).val(),count); //call function VenderConsulta with the typed code
}
});
function VenderConsulta(Codigo,ntd){
datos={codigo:Codigo}; // the code to send
$.ajax({
url:"bringMeTheData.php",
type: "POST",
data: datos,
success: function(datos){
console.log(datos); //i'm recibing something like [{"Nombre":"A product name","P_venta":"990"}]
count+=1; //next time i'll choose the new input with id="inp1"
$(':focus').blur(); //blur the input
var arr = JSON.parse(datos);
var tdNombre = arr[0].Nombre;
var tdPrecio = arr[0].P_venta;
$('#tdN'+ntd+'').html(tdNombre);
$('#tdC'+ntd+'').val(1);
$('#tdP'+ntd+'').html(tdPrecio);
$('#bodyVender').append('<tr><td><input id="inp'+count+'" type="text" class="form-control"></td> <td id="tdN'+count+'"></td> <td><input id="tdC'+count+'" type="text" class="form-control"></td> <td id="tdP'+count+'"></td></tr>');
$('#inp'+count).focus(); //setting focus to the new created input
}
});
}
}
</script>
</head>
<body>
<div class="container-fluid">
<section class="tablaVender">
<div class="row">
<div class="table-responsive" style="background:white">
<h3 style="margin-left:15px"> Venta de productos </h3>
<table class='table table-hover table-bordered'>
<thead><tr><th>Código</th><th>Nombre</th><th>Cantidad</th><th>Precio</th></tr></thead>
<tbody id="bodyVender">
<tr> <!-- This is the input and i'll add more trs like this in the function VenderConsulta -->
<td><input id="inp0" type="text" autofocus="true" class="form-control"></td> <td id="tdN0"></td> <td><input id="tdC0" type="text" class="form-control"></td> <td id="tdP0"></td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
</div>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</body>
</html>
Why this works just the first time and then no more? I'm working wrongly with that new row created?
Sorry for my bad english and thanks.

Your selector for the keydown function will only trigger it for the first input. You only call .on() once, and you give it '#inp'+String(count) as the selector. Your variable count is 0 at that point, so it will only work with the input that has the id inp0. You could fix this by using a selector that will work with all input[x] ids. And attribute selector that checks the beginning of the id would work. Like:
$(document).on('keydown','[id^=inp]'function(e){ //when press key on input with id="inp0"
if(event.keyCode == 13){ //if the key pressed is Enter
VenderConsulta($(this).val(),count); //call function VenderConsulta with the typed code
}
});

It's because this code:
$(document).on('keydown','#inp'+String(count), function(e){ //when press key on input with id="inp0"
if(event.keyCode == 13){ //if the key pressed is Enter
VenderConsulta($(this).val(),count); //call function VenderConsulta with the typed code
}
});
will only get executed once, and when it does, the value of count is 0. So you're only binding the event to the first element.
Instead, you should probably use a class to target those elements.

Related

randomly choose input entered, add to table

i am struggling to get it to work since this is my first try making something on my own.
I want to take input from the input field inside the form, click the submit button, and on each row i want a new input[type='text'] in a table.
for example: david, jan, mark
each of the above names needs to be added on a new row separetly, randomly chosen, below each other
hope this makes sense.
in the example below, it adds the input next to each other.
// when the page is loaded
// hiding the table in the DOM = document object model
$(document).ready(function() {
$('.table').hide();
});
// Get input from 'inputNames' text area
$('#button').click(function() {
var name = $('input[type="text"]').val().split(',');
// checking to see if the "input[type='text']" value is empty
if ($('#inputNames').val() !== '') {
// iterate over de names
$('#inputNames').each(function() {
for (var i = 0; i < name.length; i++) {
name[i];
//Create a new td add to tr
$('.inserted').append('<td>' + name[i] + '</td>');
}
});
// log the variable name to see the object
console.log(name);
// slide in the table
$('.table').fadeIn(2500);
// without it wont load the fadeIn effect
return false;
} else {
alert('You need to fill in the input field');
};
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Roulatie Schema</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div class="container">
<div class="jumbotron">
<h1>Roulatie Schema</h1>
<p class="lead">Gewoon een simpel roulatie schema, waarbij alleen de namen van de betreffende mensen hoeft te worden ingevuld</p>
<hr class="my-4">
<form id="myForm">
<div class="form-group">
<label for="inputNames">Fill in the names separated by a comma</label>
<input type="text" class="form-control" id="inputNames" required='true' aria-describedby="emailHelp" placeholder="Example name, name">
<small id="emailHelp" class="form-text text-muted">the field above can not be empty!!</small>
</div>
<button id="button" type="submit" class="btn btn-primary btn-lg">Submit</button>
</div>
<table class="table" align='center'>
<thead class="thead-dark">
<tr>
<th>#Rounds</th>
<th>#First Round</th>
<th>#Second Round</th>
<th>#Third Round</th>
</tr>
</thead>
<tbody>
<tr class="inserted">
<td>Luxe lades</td>
</tr>
<tr class="inserted">
<td>Meta lades</td>
</tr>
<tr class="inserted">
<td>Inpak</td>
</tr>
<tr class="inserted">
<td>Controle 100%</td>
</tr>
<tr class="inserted">
<td>Lades inhangen</td>
</tr>
<tr class="inserted">
<td>Deuren</td>
</tr>
<tr class="inserted">
<td>Planken</td>
</tr>
<tr class="inserted">
<td>Panelen</td>
</tr>
</tbody>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="script.js"></script>
</body>
</html>
Ok, so this answer has two steps, in the hope that I understood what you want to do correctly.
Step #1:
You are currently fishing the names properly but instead of adding them to the table in new rows you just add them as cells to each and every row. So changing the append() content can fix that:
$('#inputNames').each(function() {
for (var i = 0; i < name.length; i++) {
name[i];
$('tbody').append('<tr class="inserted"><td>' + name[i] + '</td></tr>');
}
});
Step #2:
Now you want them to be added randomly. There are many ways to go about this but I will just offer one, which in the code actually comes before the 1st step:
randomize the name array.
how? simple:
var name = $('input[type="text"]').val().split(',');
name.sort(function(a, b){return 0.5 - Math.random()});
notice you do not to set name=name.sort() the method already sets it for you.
Now the code takes the names, randomizes them, and appends them as new rows in the table.

Obtaining value from td in a row where input button was clicked (using jQuery)

I am having troubles getting a value from a td using jQuery.
It keeps saying "undefined" or no result comes out however I edited my code.
I do not know what's wrong...
Here's my code:
(originally, data from mySQL DB should be there in the table. but I omitted them in order to make question briefer)
<html>
<head>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.validation/1.16.0/jquery.validate.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.validation/1.16.0/additional-methods.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".delete").click(function(){
var currentrow=$(this).closest('tr');
var item=currentrow.find('.id').text();
alert("delete item number:".item);
});
$(".approve").click(function(){
alert("approve!");
});
$(".edit").click(function(){
alert("edit!");
});
});
</script>
</head>
// Table that contains data
<body>
<table>
<tr>
<td class='id'>
</td>
<td>
</td>
<td>
<input type='button' class='delete' value='Delete'/>
</td>
<td>
<input type='button' class='approve' value='Approve'/>
</td>
<td>
<input type='button' class='edit' value='Edit'/>
</td>
</tr>
</table>
</body>
</html>
find() using a class will return an array of elements. You need to grab the first element and then perform the text lookup, like this:
var item=$(currentrow.find('.id')[0]).text();
Also, in Javascript you concatenate strings using + (and not using . like in PHP)
alert("delete item number:" + item);

How to add input field using jQuery and call Ajax into new input field

I am using a table with input fields. I use jQuery for adding new row/ input field, and then I want to call Ajax into new row/input field. But its not working. Because it's not filling up the condition of document.ready() function..
here is my html form:
<table>
<thead>
<tr>
<th>Account Name:</th>
<th>Branch:</th>
</tr>
</thead>
<tr>
<td>
<div>
<input type="text" name="ac_name" class="auto-search-ac">
</div>
</td>
<td>
<div>
<input type="text" name="branch">
</div>
</td>
</table>
Script for add new row in the table ( It is working perfectly) :
<script>
$(document).on("focus",'#table tr:last-child td:last-child',function() {
//append the new row here.
var table = $("#table");
table.append('<tr>\
<td style="width:250px;"><div> <input type="text" name="ac_name" class="auto-search-ac"></div>\
</td>\
<td><div><input type="text" name="branch"></div>\
</td>\
</tr>');
});
</script>
Ajax call into new inserted input field:: (in first row - ajax is working nicely)
<script type="text/javascript">
$(".auto-search-ac").autocomplete({
source: "/ca-list",
minLength: 1,
select: function( event, ui ) {
$('.auto-search-ac').val(ui.item.value);
$('#ca-id-val').val(ui.item.ca_id);
}
});
</script>
Note That :: I am using all scripts and html in Modal. In First row, everything is OK.
after adding new row by jQuery then I can not call ajax. May it could be the issue of document.ready().
Question : how may I call any script/ajax/jQuery after adding a new input field/row using jquery in html ? Thanks in Advanced.
Use class selector as you do not have element having is as auto-search-ac. After appending element, find element having class as auto-search-ac from the appended tr and initialize autocomplete
Try this:
$(".auto-search-ac").autocomplete({
source: "/ca-list",
minLength: 1,
select: function(event, ui) {
alert(ui.item.value);
alert(ui.item.ca_id);
}
});
$(document).on("focus", '#table tr:last-child td:last-child', function() {
var table = $("#table");
var element = '<tr>\
<td style="width:250px;"><div> <input type="text" name="ac_name" class="auto-search-ac"></div>\
</td>\
<td><div><input type="text" name="branch"></div>\
</td>\
</tr>';
table.append(element);
$("#table tr:last-child").find(".auto-search-ac").autocomplete({
source: "/ca-list",
minLength: 1,
select: function(event, ui) {
alert(ui.item.value);
alert(ui.item.ca_id);
}
});
});
<table id='table'>
<thead>
<tr>
<th>Account Name:</th>
<th>Branch:</th>
</tr>
</thead>
<tr>
<td>
<div>
<input type="text" name="ac_name" class="auto-search-ac">
</div>
</td>
<td>
<div>
<input type="text" name="branch">
</div>
</td>
</table>
Fiddle demo

How to add row in html table on top of specific row?

I have a table, and each row has a button to add a new row on top of it. Each row has new inputs.
I know how to add a row on top of the table, but not on top of each row that I'm clicking on the button. Would anyone have a tip on how to solve it? I might be able to do it, but the solution I see is very complicated, and I'm sure there must be a smarter solution.
Oh, also I don't know how to update the parameter sent in the insertNewRow(id) function.
So far this is what I have:
<script type="text/javascript">
function insertNewRow(id){
var row = document.getElementById("bottomRow");
var newrow = row.cloneNode(true);
console.log(newrow);
var newInputs = newrow.getElementsByTagName('input');
var allRows = row.parentNode.getElementsByTagName('tr');
row.parentNode.insertBefore(newrow, row);
var i=row.rowIndex;
console.log(i);
}
</script>
<table id="myTable">
<tr>
<td>Title1:</td>
<td></td>
<td>Title2:</td>
<td></td>
<td>Title3:</td>
<td></td>
<td></td>
</tr>
<tr>
<td><input class="c1" readonly maxlength="9" size="7" id="gTop" type="text" value ="11"></td>
<td> <-></td>
<td id="l1"><input class="c2" style="width:35px;" maxlength="9" size="7" type="text" id="lTop" value="33"></td>
<td>=</td>
<td id="rv1"><input id="rvTop" input class="c2" style="width:105px;" maxlength="100" size="37" type="text" value="blahblahblah"></td>
<td></td>
<td>x</td>
</tr>
<tr id="bottomRow">
<td><input class="c1" readonly maxlength="9" size="7" id="gBottom" type="text" value =""></td>
<td> </td>
<td id="l1"><input class="c2" style="width:35px;" maxlength="9" size="7" type="text" id="lBottom" value="11"></td>
<td>=</td>
<td id="rv1"><input id="rvBottom" input class="c2" style="width:105px;" maxlength="100" size="37" type="text" value="blahblahblah"></td>
<td><button type="button" onclick="insertNewRow(1)">+</button></td>
<td>x</td>
</tr>
</table>
In the onclick attribute, instead of just calling insertNewRow(), do something like
insertNewRow.apply(this);
The this keyword inside the onclick attribute is a reference of the clicked element. With insertNewRow.apply(this), we'll be calling insertNewRow() and at the same time, assign the this keyword inside that function call to the clicked element or in this case, the button (if we don't do that, this inside insertNewRow() will be a reference to the Window object instead). Then in, your insertNewRow() function, check if the current element being clicked on is a tr element. If not, go up by one level and see if that element is a tr element. Keep doing that until you get to the first tr element. So, basically you'll be searching for the closest tr element.
<button type="button" onclick="insertNewRow.apply(this);">+</button>
function insertNewRow(){
var row = null,
el = this;
// Get the closest tr element
while (row === null)
{
if (el.tagName.toLowerCase() === 'tr')
{
row = el; // row is now the closest tr element
break;
}
el = el.parentNode;
}
// Rest of the code here
}​
JsFiddle
If you're still not sure what Function.apply() is, take a look at the documentation here.

Setting an input to its most recent valid value

I'm trying to write a polyfill for HTML5's input type="number" element. Here's a comparative example if your browser already supports it.
If you enter a value that cannot be parsed as a number, such as "abc", when you blur, Chrome will set the value back to whatever the most recent valid value you was. I suppose I could do that by storing the value in a data- attribute whenever the field gets focus, just in case I need to set it back, but is there any more natural way to go about "remembering" the most recent valid value a form field had?
This is often called undo. This fellow shows you how to do it with JavaScript:
<html>
<head>
<title>Title</title>
<script type="text/javascript" language="javascript">
function InputBalance_OnChange(sender) {
if(isNaN(sender.value)) {
sender.value = isNaN(sender.prevValue) ? 0 : sender.prevValue;
} else {
sender.prevValue = sender.value;
}
}
</script>
</head>
<body>
<table>
<tr>
<td>Account Number</td>
<td><input id="inputAccountNumber" type="text" /></td>
</tr>
<tr>
<td>Balance</td>
<td><input id="inputBalance" type="text" onChange="InputBalance_OnChange(this)" value="0" /></td>
</tr>
</table>
</body>
</html>

Categories