Using Jquery functions with Multiple Text Fields With Same ID - javascript

I looking for help on how to reference specific text fields with jquery that are generated with javascript.
What I get works only on the first instance of the field reference.
HTML Code:
Record ID<input type="text" name="ri[]" id="ri1" size="7" style="font-size:0.9em;">
Qty Per Box<input type="text" name="qpb[]" id="qpb1" size="7" style="font-size:0.9em;">
Javascript Used To Generate More Rows Like Above
<!--Dynamically Create New Rows For Data Entry-->
<script language="javascript">
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;
//alert(newcell.childNodes);
switch(newcell.childNodes[0].type) {
case "text":
newcell.childNodes[0].value = "";
break;
case "checkbox":
newcell.childNodes[0].checked = false;
break;
}
}
}
function deleteRow(tableID) {
try {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
for(var i=0; i<rowCount; i++) {
var row = table.rows[i];
var chkbox = row.cells[0].childNodes[0];
if(null != chkbox && true === chkbox.checked) {
if(rowCount <= 1) {
alert("Cannot delete all the rows.");
break;
}
table.deleteRow(i);
rowCount--;
i--;
}
}
}catch(e) {
alert(e);
}
}
</script>
So what I end up getting is multiple rows with the same id / name. What I simply want to do is validate input on keyup so I decided to use the (this).val method but it only works on the first row.
<script>
$(document).ready(function() {
$("#ri1").keyup(function() {
$(this).val($(this).val().replace(/[^\d]/g, ""));
});
});
</script>
Anybody know a better solution to validating input on when generating multiple rows of input fields this way?
Js fiddle http://jsfiddle.net/nS2LM/22/

Using an ID more than once is not recommended but if you are using the latest jQuery then event delegation is your answer:
<input type="text" name="ri[1]" id="ri1" size="7" style="font-size:0.9em;" class="do_stuff">
<input type="text" name="ri[2]" id="ri2" size="7" style="font-size:0.9em;" class="do_stuff">
<script>
$(document).ready(function() {
$('body').on('keyup', '.do_stuff', function() {
$(this).val($(this).val().replace(/[^\d]/g, ""));
});
});
</script>
The code above binds keyup to the body's child .do_stuff elements so any dynamically created elements with a class of .do_stuff will be caught by the keyup event.

Related

Disable selected option of the first select box in the second select box

I want to find student's data by inserting their subject name and their score range. The teacher can add a new subject with an add button and can remove the subject too. Also the subject/option that has been already selected in the previous row will disable in the next new row.
Here is the html code
<button type="button" class="btn btn-bricky btn-sm" onclick="deleteRow('dataTable')"><span class="glyphicon glyphicon-remove"></span> Delete Row</button>
<table id="dataTable" class="table table-striped" style="font-size: 12px" >
<tr>
<td><input type="checkbox" name="chk"/></td>
<td>
<select name="subject" id="subject">
<option value="Math">Math</option>
<option value="Physic">Physic</option>
<option value="Chemistry">Chemistry</option>
<option value="Biology">Biology</option>
</select>
Score Min : <input type="number" name="comsMin" style="width:70px" min="0" max="100"/>
Max : <input type="number" name="comsMax" style="width:70px" min="0" max="100"/></td>
</tr>
</table>
And here is the JavaScript code
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;
//alert(newcell.childNodes);
switch(newcell.childNodes[0].type) {
case "#text":
newcell.childNodes[0].value = "";
break;
case "#checkbox":
newcell.childNodes[0].checked = false;
break;
case "#select-one":
newcell.childNodes[0].selectedIndex = 0;
break;
}
}
}
//--------------
function deleteRow(tableID) {
try {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
for(var i=0; i<rowCount; i++) {
var row = table.rows[i];
var chkbox = row.cells[0].childNodes[0];
if(null != chkbox && true == chkbox.checked) {
if(rowCount <= 1) {
alert("Cannot delete all the rows.");
break;
}
table.deleteRow(i);
rowCount--;
i--;
}
}
}catch(e) {
alert(e);
}
}
My problem is that I don't know how and where to write a code to disable the selected option that had been chosen in the first select box in the new added select box.
Is this possible?
Here's JS fiddle
We can have a separate table for storing the dataset in hidden mode and maintain the selection state in it.
Instead of hidden element you can also maintain the state in javascript variables.
function syncModdelAdd(tableID){
// Get the available selections
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var dataTable = document.getElementById('dataTable');
for(var i=0; i<rowCount; i++){
var selectedIndex = table.rows[i].cells[1].childNodes[1].selectedIndex;
dataTable.rows[0].cells[1].childNodes[1].options[selectedIndex].disabled=true;
}
}
function syncModelDelete(selectedIndex){
var dataTable = document.getElementById('dataTable');
dataTable.rows[0].cells[1].childNodes[1].options[selectedIndex].disabled=false;
var table = document.getElementById('resultTable');
var totalRows = table.rows.length;
table.rows[totalRows-1].cells[1].childNodes[1].options[selectedIndex].disabled=false;
}
Fiddle Link : https://jsfiddle.net/2tfacL9k/

jQuery autocomplete not working for multiple text inputs

I have the issue that autocomplete on works for the first textbox, but not for the other ones that I can add via a button. Here's my code:
HTML:
<input class="button" type="button" value="+" onclick="addRow('positionen')" />
<input class="button" type="button" value="-" onclick="deleteRow('positionen')" />
<table id="positionen">
<tr>
<td><input type="checkbox" name="chk[]" /></td>
<td><input class="ui-widget" type="text" name="text[]" placeholder = "Text" /></td>
<td><input type="text" name = "val[]" placeholder = "Val" /></td>
</tr>
</table>
Function addRow:
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;
switch(newcell.childNodes[0].type) {
case "text":
newcell.childNodes[0].value = "";
break;
case "checkbox":
newcell.childNodes[0].checked = false;
break;
}
}
}
Function deleteRow:
function deleteRow(tableID) {
try {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
for(var i=0; i<rowCount; i++) {
var row = table.rows[i];
var chkbox = row.cells[0].childNodes[0];
if(null != chkbox && true == chkbox.checked) {
if(rowCount <= 1) {
alert("Can't delete all rows");
break;
}
table.deleteRow(i);
rowCount--;
i--;
}
}
} catch(e) {
alert(e);
}
}
Autocomplete code:
$(function() {
$(".ui-widget").focusin(function(){
$(this).autocomplete({
source: 'search.php'
});
});
});
The first textbox that is already on the page by default is working fine with autocomplete. However when I add a textbox with the button, autocomplete is not working for this textbox.
Events are bind to the html when page is loaded, new rows are not there, you just need to bind it to the created rows by simply adding this to your addRow function
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;
switch(newcell.childNodes[0].type) {
case "text":
if (newcell.childNodes[0].className === 'ui-widget ui-autocomplete-input') {
$(newcell.childNodes).autocomplete({
source: 'search.php'
});
}
newcell.childNodes[0].value = "";
break;
case "checkbox":
newcell.childNodes[0].checked = false;
break;
}
}
}

Add class to a Dynamic Row using Javascript

I am using a script to add a row to my form table which is working absoulty fine. On my first input box I am using a datepicker which is working on the first row but when I add another row the datepicker isnet working. I'm assuming it's because there is no class. I have tried adding using this bit of code but with no luck: newcell.className = 'datepicker';
function addRow(tableID) {
var table = document.getElementById(tableID).getElementsByTagName('tbody')[0];
var rowCount = table.rows.length;
if(rowCount < 50){ // limit the user from creating fields more than your limits
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;
newcell.className = 'datepicker';
}
}else{
alert("Too many rows.");
}
}
You need to actually create the datepicker on the element, at the end of the for-loop body. Also, don't copy the innerHTML of the original row, as will also copy the id of the input, which must be unique and will break the date picker logic.
A complete working example is below.
function addRow(tableID) {
var table = document.getElementById(tableID).getElementsByTagName('tbody')[0];
var rowCount = table.rows.length;
if(rowCount < 50){ // limit the user from creating fields more than your limits
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.appendChild(document.createElement('input'));
$(newcell).find('input').addClass('datepicker');
$(newcell).find('input.datepicker').datepicker();
}
}else{
alert("Too many rows.");
}
}
$(function () {
$('.datepicker').datepicker();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link href="https://code.jquery.com/ui/1.11.4/themes/ui-lightness/jquery-ui.css" rel="stylesheet"/>
<button onclick="addRow('table')">Add Row</button>
<table id="table">
<tbody>
<tr>
<td><input class="datepicker" /></td>
</tr>
</tbody>
</table>

how to call 2 function inside 1 input type

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);
if (i==2) {
newcell.innerHTML="<div id='txtHint"+xx+"'></div>";
}
else if(i==0){
newcell.innerHTML = "<INPUT type='checkbox' name='chk[]'/>";
}
else if (i==1) {
newcell.innerHTML = table.rows[1].cells[1].innerHTML;
switch(newcell.childNodes[0].type) {
case "select-one":
newcell.childNodes[0].setAttribute("onchange","showUser(this.value,"+xx+");showrole(this.value,"+xx+")");
}
}
else if (i==3) {
newcell.innerHTML="<div id='txtHintrole"+xx+"'></div>";
}
this is my function show select option depend on username i choose
after did some modification finally it work
and now i want to show role depend on username
so i have 2 show
1.for password
2.for username
onchange="showpassword(this.value)
this is my onchange inside select box
and now i want to showrole too
so when i choose the select
it will showed me password and role ad diferent cell
newcell.childNodes[0].setAttribute("onchange","showUser(this.value,"+xx+");showrole(this.value,"+xx+")");
and i foudn that i have tu put semi colon to devide the function
and i still show an error that the show only show role and it happen to 2 of them
it should showpassword and showrole when i select the value
You can use the innerHTML property of the cell.
Do something like
newcell.innerHTML = '<div id="txthint' + i + '">content</div>';
Hope this help

I need to dynamically add more fields to a form and have the new fields inputs values change as well

I have a jsfiddle here of the script I'm using to dynamically add rows to a field but have a problem.
On my form I have the 1st row that I want to duplicate with the script. The row consists of 6 inputs named job_date1, tech_name1, cost_code1, pay_rate1, total_hours1, and sub_total1.
When the second row is created via the script I now need the new rows input names to be set by the script if possible to job_date2, tech_name2, cost_code2 and so on and with each new row created I need the end digit to move up one.
Here is the code:
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;
switch(newcell.childNodes[0].type) {
case "text":
newcell.childNodes[0].value = "";
break;
case "checkbox":
newcell.childNodes[0].checked = false;
break;
case "select-one":
newcell.childNodes[0].selectedIndex = 0;
break;
}
}
}
function deleteRow(tableID) {
try {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
for(var i=0; i<rowCount; i++) {
var row = table.rows[i];
var chkbox = row.cells[0].childNodes[0];
if(null !== chkbox && true === chkbox.checked) {
if(rowCount <= 1) {
alert("Cannot delete all the rows.");
break;
}
table.deleteRow(i);
rowCount--;
i--;
}
}
}
catch(e) {
alert(e);
}
}
Here's a simple solution:
newcell.children[0].name = newcell.children[0].name + rowCount;
As you count each newly added row, add that variable to each of the input elements.
Here's the jsFiddle (be sure to check your console when you run the function to see the console log).
For the first log, it returns:
chk1
txt1
tech_name1
cost_code1
txt1
For the second element that's created
chk2
txt2
tech_name2
cost_code2
txt2
etc.
I have a simpler suggestion. Instead of having job_date1, job_date2, etc., name your fields job_date[] (all of the job date fields).
E.g. PHP automatically recognizes this and $_POST["job_date"] would be an array with all the values for job date in the order they appear on the html page. So instead of $_POST["job_date" . $i] you would use $_POST["job_date"][$i].
I don't know what technology you use for the backend, but I'm sure you can achieve the same effect.
It will be more robust and elegant and you don't have to care about re-numbering when you add nor remove rows.
Edit: More details about this technique in PHP can be found in PHP FAQ and Example #3 here.

Categories