Retrieving HTML Table Values - javascript

I created a table and borrowed a javascript function from http://www.fourfront.us/blog/store-html-table-data-to-javascript-array to retrieve the contents of the table the way I wanted to. It almost works, but for some reason I cannot access the value that the user inputs.
I have made a JS fiddle at http://jsfiddle.net/danielmdavies/4mu80x2L/1/
The code is also posted below. If I use "time_cutoff": $(tr).find('td:eq(2)').html() instead of "time_cutoff": $(tr).find('td:eq(2)').val(), I get the html code that is correct I believe.
This is the relevant html code:
<table id="cycler_table">
<tr>
<th>Cycle Step</th>
<th>Mode</th>
<th>Time Cutoff</th>
<th>Voltage Cutoff</th>
<th>Current Cuttoff</th>
</tr>
<tr>
<td>1</td>
<td>
<select name='cyc_mode1'>
<option value='galvanostatic'>Galvanostatic</option>
<option value='Potentiostatic'>Potentiostatic</option>
<option name='rest'>Rest</option>
</td>
<td>
<input type='text' name='time_cutoff1' value='10'>
</td>
<td>
<input type='text' name='voltage_cutoff1' value='0'>
</td>
<td>
<input type='text' name='current_cutoff1' value='0'>
</td>
</tr>
<tr>
<td>2</td>
<td>
<select name='cyc_mode2'>
<option value='galvanostatic'>Galvanostatic</option>
<option value='Potentiostatic'>Potentiostatic</option>
<option name='rest'>Rest</option>
</td>
<td>
<input type='text' name='time_cutoff2' value='10'>
</td>
<td>
<input type='text' name='voltage_cutoff2' value='0'>
</td>
<td>
<input type='text' name='current_cutoff2' value='0'>
</td>
</tr>
<tr>
<td>3</td>
<td>
<select name='cyc_mode3'>
<option value='galvanostatic'>Galvanostatic</option>
<option value='Potentiostatic'>Potentiostatic</option>
<option name='rest'>Rest</option>
</td>
<td>
<input type='text' name='time_cutoff3' value='10'>
</td>
<td>
<input type='text' name='voltage_cutoff3' value='0'>
</td>
<td>
<input type='text' name='current_cutoff3' value='0'>
</td>
</tr>
<tr>
<td>4</td>
<td>
<select name='cyc_mode4'>
<option value='galvanostatic'>Galvanostatic</option>
<option value='Potentiostatic'>Potentiostatic</option>
<option name='rest'>Rest</option>
</td>
<td>
<input type='text' name='time_cutoff4' value='10'>
</td>
<td>
<input type='text' name='voltage_cutoff4' value='0'>
</td>
<td>
<input type='text' name='current_cutoff4' value='0'>
</td>
</tr>
</table>
<textarea id="tbTableValuesArray" name="tblValuesArray" rows="10"></textarea>
</div>
<p id="cyc_confirm">Waiting for Properties to be Confirmed
<button onclick="storeAndShowTableValues()">Send the Setup</button>
And the Javascript
$(document).ready(function () {
console.log("ready!");
storeAndShowTableValues();
});
function storeAndShowTableValues() {
var TableData;
TableData = storeTblValues();
$('#tbTableValuesArray').val('TableData = \n' + print_r(TableData));
}
function storeTblValues() {
var TableData = new Array();
$('#cycler_table tr').each(function (row, tr) {
TableData[row] = {
"cyc_mode": $(tr).find('td').eq(1).val(),
"time_cutoff": $(tr).find('td:eq(2)').val(),
"voltage_cutoff": $(tr).find('td:eq(3)').val(),
"current_cutoff": $(tr).find('td:eq(4)').val()
}
});
TableData.shift(); // first row will be empty - so remove
return TableData;
}
function convertArrayToJSON() {
var TableData;
TableData = $.toJSON(storeTblValues());
$('#tbConvertToJSON').val('JSON array: \n\n' + TableData.replace(/},/g, "},\n"));
}
function print_r(arr, level) {
var dumped_text = "";
if (!level) level = 0;
//The padding given at the beginning of the line.
var level_padding = "";
for (var j = 0; j < level + 1; j++) level_padding += " ";
if (typeof (arr) == 'object') { //Array/Hashes/Objects
for (var item in arr) {
var value = arr[item];
if (typeof (value) == 'object') { //If it is an array,
dumped_text += level_padding + "'" + item + "' \n";
dumped_text += print_r(value, level + 1);
} else {
dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
}
}
} else { //Stings/Chars/Numbers etc.
dumped_text = "===>" + arr + "<===(" + typeof (arr) + ")";
}
return dumped_text;
}
This is probably super easy but for whatever reason I can't work out how to make it give me the values.
Any help would be awesome.

Try something like this to get the values:
TableData[row] = {
"cyc_mode": $(tr).find('select').val(),
"time_cutoff": $(tr).find('input:eq(0)').val(),
"voltage_cutoff": $(tr).find('input:eq(1)').val(),
"current_cutoff": $(tr).find('input:eq(2)').val()
};
You need to find the actual input and select elements to get their values.
Or better:
var elem = $(tr);
TableData[row] = {
"cyc_mode": elem.find('select').val(),
"time_cutoff": elem.find('input:eq(0)').val(),
"voltage_cutoff": elem.find('input:eq(1)').val(),
"current_cutoff": elem.find('input:eq(2)').val()
};
Which avoids recreating the jquery object four times.

Related

Problems with HTML and Javascript dynamic table

I am facing problems in:
the function saveRow does not save the row. I get this error:
Uncaught TypeError: Cannot set property name of undefined at at saveRow at HTMLInputElement.onclick.
2) the deleteRow does not work. I get a similar error:
Uncaught TypeError: Cannot set property 'innerHTML' of null.
3) in the editRow, I fields to become editable, but with the default values as what was saved before. For example, the list is always A, B, C which is not what I want. I want the initial value of the list to be what was selected previously.
There should be something wrong I am doing. Here is the code:
HTML:
<html>
<head>
</head>
<body>
<div id="wrapper">
<table align='center' cellspacing=2 cellpadding=5 id="data_table" border=1>
<thead>
<tr>
<th>Name</th>
<th>Level</th>
<th>Action</th>
</tr>
</thead>
<tbody id="table-rows">
<tr>
<td><input type="text" id="name-text"></td>
<td>
<select name="levels-list" id="levels-list">
<option value="A" id="option-1">A</option>
<option value="B" id="option-2">B</option>
<option value="C" id="option-3">C</option>
</select>
</td>
<td><input type="button" class="add" value="Add Row" id="add-button"></td>
</tr>
</tbody>
</table>
</div>
<script src="get-text.js"></script>
</body>
</html>
The script:
var myArray = [{
"name": "aaa",
"level": "A"
}, {
"name": "bbb",
"level": "B"
}, {
"name": "ccc",
"level": "C"
}];
display();
function display() {
var length = myArray.length;
var htmlText = "";
for (var i = 0; i < length; i++) {
htmlText +=
"<tr id='row" + i + "'>\
<td>" + myArray[i].name + "</td>\
<td>" + myArray[i].level + "</td>\
<td>\
<input type='button' id='edit_button" + i + "' value='Edit' class='edit' onclick='editRow("+i+")'> \
<input type='button' id='save_button" + i + "' value='Save' class='save' onclick='save_row(" + i + ")'> \
<input type='button' value='Delete' class='delete' onclick='delete_row(" + i + ")'>\
</td>\
</tr>";
}//end loop
htmlText+=
"<tr>\
<td><input type='text' id='name-text'></td>\
<td>\
<select name='levels-list' id='levels-list'>\
<option value='A' id='option-1'>A</option>\
<option value='B' id='option-2'>B</option>\
<option value='C' id='option-3'>C</option>\
</select>\
</td>\
<td><input type='button' class='add' value='Add Row' id='add-button' ></td>\
</tr>";
document.getElementById("table-rows").innerHTML = htmlText;
}//end display
var addButton=document.getElementById("add-button");
addButton.addEventListener('click', addRow, false);
function addRow(){
event.preventDefault();
var newData= document.getElementById("name-text").value;
var newLevel = document.getElementById("levels-list").value;
var table = document.getElementById("data_table");
var tableLength = (table.rows.length)-1;
// console.log(tableLength);
var row = table.insertRow(tableLength).innerHTML=
"<tr id= 'row"+tableLength+"'>\
<td id='name-text"+tableLength+"'>"+newData+"</td>\
<td id='levels-list"+tableLength+"'>"+newLevel+"</td>\
<td><input type='button' id='edit-button"+tableLength+"' value='Edit' class='edit' onclick='editRow("+tableLength+")'> \
<input type='button' id='save-button"+tableLength+"' value='Save' class='save' onclick='saveRow("+tableLength+")'> \
<input type='button' id= 'delete-button"+tableLength+"' value='Delete' class='delete' onclick='deleteRow("+tableLength+")'>\
</td>\
</tr>";
document.getElementById("name-text").value="";
}//end addRow
function editRow(no)
{
document.getElementById("edit-button"+no).disabled=true;
//document.getElementById("save-button"+no).style.display="block";
var name=document.getElementById("name-text"+no);
var level=document.getElementById("levels-list"+no);
var nameData=name.innerHTML;
var levelData=level.innerHTML;
name.innerHTML="<input type='text' id='name_text"+no+"' value='"+nameData+"'>";
level.innerHTML='<select id="levels-list'+no+'">\
<option value="A" id="option-1">A</option>\
<option value="B" id="option-2">B</option>\
<option value="C" id="option-3">C</option>\
</select>' ;
document.getElementById("levels-list"+no).value = levelData;
}
function deleteRow(no) {
myArray.splice(no, 1);
document.getElementById("row"+no).innerHTML="";
//display();
} //end deleteRow
function saveRow(no)
{
myArray[no].name = document.getElementById("name-text"+no).value;
myArray[no].level = document.getElementById("levels-list"+no).value;
document.getElementById("row"+no).innerHTML =
"<tr id= 'row"+no+"'>\
<td id='name-text"+no+"'>"+myArray[no].name+"</td>\
<td id='levels-list"+no+"'>"+myArray[no].level+"</td>\
<td><input type='button' id='edit-button"+no+"' value='Edit' class='edit' onclick='editRow("+no+")'> \
<input type='button' value='Delete' class='delete' onclick='deleteRow("+no+")'>\
</td>\
</tr>";
}//end saveRow
I refactored a bit your code and created a new jsfiddle. You can refactor it more and more, and if possible to insert jQuery in your project, you will simply it a lot more.
So few notes:
1) Keep you model up to date with your UI changes. In the before sample you were manipulating HTML but you were not updating the array model
2) Try to keep your common code in functions, in order to avoid repetitions.
For example I moved the logic for creating row inside a function, and just calling that function every time that you need to create a new row (for displaying at the beginning and when clicking add row)
3) When you call your functions in the row, pass also the current HTML element. You can pass it in order to know which current HTML element has been clicked, so that you can easily manipulate that row.
4) Use two tbodies. One for the data and another one for the actions. It makes easier to distinct data from actions, avoiding to repeat every time also that row for actions
And few other things that you can check alone with the code.
You have to manage just the logic of disabling the buttons in the right operations, in order to avoid for example to click edit again when editing, but it would be a good exercise to do it yourself :)
Here the sample:
var myArray = [{
"name": "aaa",
"level": "A"
}, {
"name": "bbb",
"level": "B"
}, {
"name": "ccc",
"level": "C"
}];
function createDataRow(el, ind) {
var row = document.createElement('tr');
row.id = 'row-' + ind;
var cell1Content = `
<div class="name-content">${el.name}</div>
<input class="name-edit" type="text" id="name-text-${ind}" value="${el.name}" style="display:none;">
`;
var cell2Content = `
<div class="level-content">${el.level}</div>
<select class="level-edit" id="levels-list-${ind}" style="display:none;">
<option value="A">A</option>\
<option value="B">B</option>\
<option value="C">C</option>\
</select>
`;
var cell3Content = `
<input type="button" id='edit_button" + i + "' value="Edit" class="edit" onclick="editRow(this, ${ind})">
<input type="button" id='save_button" + i + "' value="Save" class="save" onclick="saveRow(this, ${ind})">
<input type="button" value="Delete" class="delete" onclick="deleteRow(this, ${ind})">
`;
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
cell1.innerHTML = cell1Content;
cell2.innerHTML = cell2Content;
cell3.innerHTML = cell3Content;
document.getElementById('table-data').appendChild(row);
}
function displayData() {
myArray.forEach(function(el, ind) {
createDataRow(el,ind);
});
}
function deleteRow(el, ind) {
el.parentElement.parentElement.parentElement.removeChild(el.parentElement.parentElement);
myArray.splice(ind, 1);
}
function addRow(){
event.preventDefault();
var newEl = {
"name": document.getElementById("name-text").value,
"level": document.getElementById("levels-list").value
};
myArray.push(newEl);
createDataRow(newEl, myArray.length - 1);
document.getElementById("name-text").value = '';
document.getElementById("levels-list").value = 'A';
}//end addRow
function editRow(el, ind)
{
var currentRow = el.parentElement.parentElement;
currentRow.cells[0].getElementsByClassName("name-content")[0].style.display = 'none';
currentRow.cells[0].getElementsByClassName("name-edit")[0].style.display = 'block';
currentRow.cells[1].getElementsByClassName("level-content")[0].style.display = 'none';
currentRow.cells[1].getElementsByClassName("level-edit")[0].value = myArray[ind].level;
currentRow.cells[1].getElementsByClassName("level-edit")[0].style.display = 'block';
}
//end deleteRow
function saveRow(el, ind)
{
var currentRow = el.parentElement.parentElement;
var nameContent = currentRow.cells[0].getElementsByClassName("name-content")[0];
var nameEdit = currentRow.cells[0].getElementsByClassName("name-edit")[0];
nameContent.innerHTML = nameEdit.value;
nameContent.style.display = 'block';
nameEdit.style.display = 'none';
var levelContent = currentRow.cells[1].getElementsByClassName("level-content")[0];
var levelEdit = currentRow.cells[1].getElementsByClassName("level-edit")[0];
levelContent.innerHTML = levelEdit.value;
levelContent.style.display = 'block';
levelEdit.style.display = 'none';
myArray[ind].name = nameEdit.value;
myArray[ind].level = levelEdit.value;
}//end saveRow
var addButton=document.getElementById("add-button");
addButton.addEventListener('click', addRow, false);
displayData();
<body>
<div id="wrapper">
<table align='center' cellspacing=2 cellpadding=5 id="data_table" border=1>
<thead>
<tr>
<th>Name</th>
<th>Level</th>
<th>Action</th>
</tr>
</thead>
<tbody id="table-data">
</tbody>
<tbody id="table-rows">
<tr>
<td><input type="text" id="name-text"></td>
<td>
<select name="levels-list" id="levels-list">
<option value="A" id="option-1">A</option>
<option value="B" id="option-2">B</option>
<option value="C" id="option-3">C</option>
</select>
</td>
<td><input type="button" class="add" value="Add Row" id="add-button"></td>
</tr>
</tbody>
</table>
</div>
</body>
And here the jsfiddle (this time saved :D ):
https://jsfiddle.net/u0865zaa/8/
I hope it helps. For any queries let me know.

Get the field-index of same-name-combos (select / dropdown), added after page-load

I want to get the field-index of same-names-field i.e. 'item_id[]'.
As I select/change an item from 'Item Name' drop-down, its combo-field-index should be shown in 'span' under 'Available' against this dropdown.
Actually the purpose of getting the index of current combo is to show Available-Quantity in 'Span' against this combo under 'Available'.
(dropdown field is named 'item_id[]', index is started from 0, counting from upper most drop down to the current one)
Please copy/paste all code along with Javascript, use 'Add Rows' link and force Javascript/jQuery to work for all rows (previous and newly added elements). Thanks.
EDITED:
In short, I need to alert() the current index of item-name-combo-field after using 'Add Row' link (onchange event). This is enough for my solution (and I will manage everything else).
CODE I HAVE USED:
But it works just if used for text-box not for combo AND only for elements which are loaded on page-load not for added (appended) elements using 'Add Row' link.
var my_field = $('select[name="item_id[]"]');
my_field.on('change', function() {
var index = my_field.index( this );
alert( this.value + ', ' + index );
});
<form id="form1" enctype="multipart/form-data" name="form1" method="post" action="">
<table width="41%" border="0" align="center" cellpadding="0" cellspacing="0" id="contentstable">
<tr>
<th width="35%" align="center">Item Name </th>
<th width="14%" align="center">Quantity </th>
<th width="26%" align="center">item Sr. # </th>
<th width="18%" align="center">Store Status </th>
<th width="18%" align="center">Mode </th>
<th width="7%" align="center">Available </th>
</tr>
<tr>
<td>
<select name="item_id[]" id="item_id[]" class="combo" style="width:326px;" onchange="showIssuableQty(this.value);">
<option value="0"> </option>
<option value="1">item-1 ( Model# BN004 ) </option>
<option value="2">item-2-check ( Model# FG-56 ) </option>
<option value="3">Item - 3 - Piston of Crane's Engine (Hitachi) Large size heavy duty ( Model# machine2-model-3CD ) </option>
</select>
</td>
<td>
<input name="quantity[]" type="number" id="quantity[]" value="" class="field_3" style="width:99px;">
</td>
<td>
<input name="item_sr_no[]" type="text" id="item_sr_no[]" value="" class="field_3" style="width:199px;">
</td>
<td>
<select name="store_status[]" class="combo" id="store_status[]" style="width:119px;">
<option value="New" selected="">New </option>
<option value="Repaired">Repaired </option>
<option value="Used">Used </option>
</select>
<td>
<select name="type[]" class="combo" id="type[]" style="width:119px;">
<option value="Consume" selected="">Consume </option>
<option value="Borrow">Borrow </option>
</select>
</td>
<td>
<span id="qty_avail">Qty-Here </span>
</td>
</tr>
<tr>
<td colspan="6">
<table width="100%">
<tr>
<td width="25%" style="text-align:left; vertical-align:top; font-size:17px">
<br>
<span "> <input name="add_rows " id="add_rows " type="number " value="1 " style="width:63px; " onkeypress="handle_addRows(event); "> Add Rows </span"> </td>
<td width="55%">
<p id="issuable_qty">Issuable Qty </p>
</td>
<td width="20%" class="submittd" style="text-align:right"> <br> <input name="save" type="submit" class="submit" id="addnewcategory" value="Save Record"> </td>
</tr>
</table>
</td>
</tr>
</tbody> </table>
</form>
Javascript Used:
<script>
/*var textboxes = $('select[name="item_id[]"]');
textboxes.on('change', function() {
var index = textboxes.index( this );
alert( this.value + ', ' + index );
});
alert('abc');*/
function addMoreRow() {
var tbl_name = document.getElementById("contentstable");
var rowCount = tbl_name.rows.length;
var row = tbl_name.insertRow(rowCount - 1);
var cell1 = row.insertCell(0);
cell1.innerHTML = " <select name=\"item_id[]\" class=\"combo\" id=\"item_id[]\" onchange=\"showIssuableQty(this.value);\" value=\"\" style=\"width:326px;\" > <option> </option> <option value='1'>item-1 ( Model# BN004 ) </option> <option value='2'>item-2-check ( Model# FG-56 ) </option> <option value='3'>Item - 3 - Piston of Crane's Engine (Hitachi) Large size heavy duty ( Model# machine2-model-3CD ) </option> </select>";
var cell2 = row.insertCell(1);
cell2.innerHTML = " <input name=\"quantity[]\" type=\"number\" class=\"input\" id=\"quantity[]\" value=\"\" style=\"width:99px;\" /> <input name=\"prev_quantity[]\" type=\"hidden\" class=\"input\" id=\"prev_quantity[]\" value=\"\" style=\"width:99px;\" />";
var cell3 = row.insertCell(2);
cell3.innerHTML = " <input name=\"item_sr_no[]\" type=\"text\" class=\"input\" id=\"item_sr_no[]\" value=\"\" style=\"width:199px;\" />";
var cell4 = row.insertCell(3);
cell4.innerHTML = " <select name=\"store_status[]\" class=\"combo\" id=\"store_status[]\" value=\"\" style=\"width:119px;\" > <option value='New' selected >New </option> <option value='Repaired'>Repaired </option> <option value='Used'>Used </option> </select> <input name=\"prev_store_status[]\" type=\"hidden\" class=\"input\" id=\"prev_store_status[]\" value=\"\" style=\"width:119px;\" />";
var cell5 = row.insertCell(4);
cell5.innerHTML = " <select name=\"type[]\" class=\"combo\" id=\"type[]\" value=\"\" style=\"width:119px;\" > <option value='Consume' selected >Consume </option> <option value='Borrow'>Borrow </option> </select>";
var cell6 = row.insertCell(5);
cell6.innerHTML = " <span class=\"qty_avail\"> </span>";
}
function addRows() {
var add_rows = document.getElementById('add_rows');
//alert(add_rows.value);
for ($i = 1; $i <= add_rows.value; $i++) {
addMoreRow();
}
}
function handle_addRows(e) {
if (e.keyCode === 13) {
e.preventDefault(); // Ensure it is only this code that runs
addRows();
}
}
var itemIds = new Array('1', '2', '3');
var itemNames = new Array('', '', '');
var newItems = new Array('2357', '452', '215');
var usedItems = new Array('12', '333', '57');
var toRepairItems = new Array('234', '65', '321');
var repairedItems = new Array('789', '3', '56');
var itemThreshold = new Array('34', '56', '67');
function showIssuableQty(item_id) { // This function is not working properly, see it later.
document.getElementById('issuable_qty').innerHTML = 'abc';
var item_index = itemIds.indexOf(item_id);
var strQtyMsg = 'Issuable Qty ( <b>' + (parseInt(newItems[item_index]) + parseInt(repairedItems[item_index]) + parseInt(usedItems[item_index])) +
' </b> )' + ' <br />' + 'New ( <b>' + newItems[item_index] + ' </b> ), Repaired ( <b>' + repairedItems[item_index] + ' </b> ), Used ( <b>' + usedItems[item_index] + ' </b> )';
if (parseInt(newItems[item_index]) + parseInt(repairedItems[item_index]) < parseInt(itemThreshold[item_index])) {
//if( parseInt(newItems[item_index]) + parseInt(repairedItems[item_index]) < 100 ){
strQtyMsg = strQtyMsg + ' <br />Qty. below threshold ( ' + itemThreshold[item_index] + ' ) ';
strQtyMsg = strQtyMsg + ' Request Items ';
alert('Qty. is below threshold! Please generate a request to purchase.');
}
document.getElementById('issuable_qty').innerHTML = strQtyMsg;
//alert(item_index);
}
</script>
your code could be much shorter.
you should only have one item per id, so I have changed the id names
in your html to classes.
for the select in your first bit of code you can move the selector
to become an argument of the function, this means the new change
selectors will be recognised after the dom has been updated.
your first table row making function has been removed and replaced
by simply copying the html into a variable and using that to
duplicate new rows.
your last function contents have been changed to numbers to
eliminate all of the string parsing and simplify
here's a working fiddle.
$('body').on('change', 'select.combo', function() {
var $this = $(this);
var index = $this.parent().parent('tr').index();
alert($this.val() + ', ' + index);
});
var rowTemplate = $('#contentstable tr').eq(1).html(); // make a copy of the standard row html content as defined in the html
rowTemplate = '<tr>' + rowTemplate + '</tr>';
function addRows() {
var add_rows = parseFloat($('input#add_rows').val());
for (var i, i = 1; i <= add_rows; i++) {
$('#panel').before(rowTemplate); // insert the standard row above the addrow area
}
}
function handle_addRows(e) {
if (e.keyCode === 13) {
e.preventDefault(); // Ensure it is only this code that runs
addRows();
}
}
var itemIds = [1, 2, 3];
var itemNames = ['', 0, 0, 0];
var newItems = ['', 2357, 452, 215];
var usedItems = ['', 12, 333, 57];
var toRepairItems = ['', 234, 65, 321];
var repairedItems = ['', 789, 3, 56];
var itemThreshold = ['', 34, 56, 67];
function showIssuableQty(item_id) { // This function is not working properly, see it later.
// $('#issuable_qty').html('abc');
var item_index = parseFloat(item_id); // parseInt(itemIds.indexOf(item_id));
var newAndRepaired = newItems[item_index] + repairedItems[item_index];
var strQtyMsg = 'Issuable Qty ( <b>' + (newAndRepaired + usedItems[item_index]) +
' </b> )' + ' <br />' + 'New ( <b>' + newItems[item_index] + ' </b> ), Repaired ( <b>' + repairedItems[item_index] + ' </b> ), Used ( <b>' + usedItems[item_index] + ' </b> )';
if (newAndRepaired < itemThreshold[item_index]) {
//if( parseInt(newItems[item_index]) + parseInt(repairedItems[item_index]) < 100 ){
strQtyMsg = strQtyMsg + ' <br />Qty. below threshold ( ' + itemThreshold[item_index] + ' ) ';
strQtyMsg = strQtyMsg + ' Request Items ';
alert('Qty. is below threshold! Please generate a request to purchase.');
}
if (item_index === 0) {
strQtyMsg = 'Issuable Qty ( </b> )';
}
$('#issuable_qty').html(strQtyMsg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form1" enctype="multipart/form-data" name="form1" method="post" action="">
<table width="41%" border="0" align="center" cellpadding="0" cellspacing="0" id="contentstable">
<tr>
<th width="35%" align="center">Item Name</th>
<th width="14%" align="center">Quantity</th>
<th width="26%" align="center">item Sr. #</th>
<th width="18%" align="center">Store Status</th>
<th width="18%" align="center">Mode</th>
<th width="7%" align="center">Available</th>
</tr>
<tr>
<td>
<select name="item_id[]" id="" class="item_id[] combo" style="width:326px;" onchange="showIssuableQty(this.value);">
<option value="0"></option>
<option value="1">item-1 ( Model# BN004 )</option>
<option value="2">item-2-check ( Model# FG-56 )</option>
<option value="3">Item - 3 - Piston of Crane's Engine (Hitachi) Large size heavy duty ( Model# machine2-model-3CD )</option>
</select>
</td>
<td>
<input name="quantity[]" type="number" id="" value="" class="quantity[] field_3" style="width:99px;">
</td>
<td>
<input name="item_sr_no[]" type="text" id="" value="" class="item_sr_no[] field_3" style="width:199px;">
</td>
<td>
<select name="store_status[]" class="combo store_status[]" id="" style="width:119px;">
<option value="New" selected="">New</option>
<option value="Repaired">Repaired</option>
<option value="Used">Used</option>
</select>
<td>
<select name="type[]" class="type[] combo" id="" style="width:119px;">
<option value="Consume" selected="">Consume</option>
<option value="Borrow">Borrow</option>
</select>
</td>
<td>
<span class="qty_avail">Qty-Here </span>
</td>
</tr>
<tr id='panel'>
<td colspan="6">
<table width="100%">
<tr>
<td width="25%" style="text-align:left; vertical-align:top; font-size:17px">
<br>
<span> <input name="add_rows" id="add_rows" type="number" value="1" style="width:63px; " onkeypress="handle_addRows(event); "> Add Rows </span>
</td>
<td width="55%">
<p id="issuable_qty">Issuable Qty</p>
</td>
<td width="20%" class="submittd" style="text-align:right">
<br>
<input name="save" type="submit" class="submit" id="addnewcategory" value="Save Record">
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</form>

Jquery .on(change) event on <select> input only changes first row.

I have a table whereby people can add rows.
There is a select input in the table that when changed, changes the values in a second select field via ajax.
The problem I have is that if a person adds an additional row to the table, the .on(change) event alters the second field in the first row, not the subsequent row.
I've been racking my brain, trying to figure out if I need to (and if so how to) dynamically change the div id that the event binds to and the div that it affects. Is this the solution? If so, could someone please demonstrate how I'd achieve this?
The HTML form is
<form action="assets.php" method="post">
<button type="button" id="add">Add Row</button>
<button type="button" id="delete">Remove Row</button>
<table id="myassettable">
<tbody>
<tr>
<th>Asset Type</th>
<th>Manufacturer</th>
<th>Serial #</th>
<th>MAC Address</th>
<th>Description</th>
<th>Site</th>
<th>Location</th>
</tr>
<tr class="removable">
<!--<td><input type="text" placeholder="First Name" name="contact[0][contact_first]"></td>
<td><input type="text" placeholder="Surname" name="contact[0][contact_surname]"></td>-->
<td><select name="asset[0][type]">
<option><?php echo $typeoption ?></option>
</select></td>
<td><select class="manuf_name" name="asset[0][manuf]">
<option><?php echo $manufoption ?></option>
</select></td>
<td><input type="text" placeholder="Serial #" name="asset[0][serial_num]"></td>
<td><input type="text" placeholder="Mac Address" name="asset[0][mac_address]"></td>
<td><input type="text" placeholder="Name or Description" name="asset[0][description]"></td>
<td><select id="site" name="asset[0][site]">
<option><?php echo $siteoption ?></option>
</select></td>
<td><input type="text" placeholder="e.g Level 3 Utility Room" name="asset[0][location]"></td>
<td><select id="new_select" name="asset[0][contact]"></select></td>
<!--<td><input type="email" placeholder="Email" name="contact[0][email]"></td>
<td><input type="phone" placeholder="Phone No." name="contact[0][phone]"></td>
<td><input type="text" placeholder="Extension" name="contact[0][extension]"></td>
<td><input type="phone" placeholder="Mobile" name="contact[0][mobile]"></td>-->
</tr>
</tbody>
</table>
<input type="submit" value="Submit">
<input type="hidden" name="submitted" value="TRUE" />
</form>
The script I have is
<script type="text/javascript">
$(document).ready(function() {
$("#add").click(function() {
var newgroup = $('#myassettable tbody>tr:last');
newgroup
.clone(true)
.find("input").val("").end()
.insertAfter('#myassettable tbody>tr:last')
.find(':input')
.each(function(){
this.name = this.name.replace(/\[(\d+)\]/,
function(str,p1) {
return '[' + (parseInt(p1,10)+1)+ ']'
})
})
return false;
});
});
$(document).ready(function() {
$("#delete").click(function() {
var $last = $('#myassettable tbody').find('tr:last')
if ($last.is(':nth-child(2)')) {
alert('This is the only one')
} else {
$last.remove()
}
});
});
$(document).ready(function() {
$("#myassettable").on("change","#site",function(event) {
$.ajax ({
type : 'post',
url : 'assetprocess.php',
data: {
get_option : $(this).val()
},
success: function (response) {
document.getElementById("new_select").innerHTML=response;
}
})
});
});
</script>
and the assetprocess.php page is
<?php
if(isset($_POST['get_option'])) {
//Get the Site Contacts
$site = $_POST['get_option'];
$contact = "SELECT site_id, contact_id, AES_DECRYPT(contact_first,'" .$kresult."'),AES_DECRYPT(contact_surname,'" .$kresult."') FROM contact WHERE site_id = '$site' ORDER BY contact_surname ASC";
$contactq = mysqli_query($dbc,$contact) or trigger_error("Query: $contact\n<br />MySQL Error: " .mysqli_errno($dbc));
if ($contactq){
//$contactoption = '';
echo '<option>Select a Contact (Optional)</option>';
while ($contactrow = mysqli_fetch_assoc($contactq)) {
$contactid = $contactrow['contact_id'];
$contactfirst = $contactrow["AES_DECRYPT(contact_first,'" .$kresult."')"];
$contactsurname = $contactrow["AES_DECRYPT(contact_surname,'" .$kresult."')"];
$contactoption .= '<option value="'.$contactid.'">'.$contactsurname.', '.$contactfirst.'</option>';
echo $contactoption;
}
}
exit;
}
?>
The code is ugly as sin, but this is only a self-interest project at this stage.
Any assistance would be greatly appreciated.
Cheers,
J.
Working Example: https://jsfiddle.net/Twisty/1c98Ladh/3/
A few minor HTML changes:
<form action="assets.php" method="post">
<button type="button" id="add">Add Row</button>
<button type="button" id="delete">Remove Row</button>
<table id="myassettable">
<tbody>
<tr>
<th>Asset Type</th>
<th>Manufacturer</th>
<th>Serial #</th>
<th>MAC Address</th>
<th>Description</th>
<th>Site</th>
<th>Location</th>
</tr>
<tr class="removable">
<td>
<select name="asset[0][type]">
<option>---</option>
<option>Type Option</option>
</select>
</td>
<td>
<select class="manuf_name" name="asset[0][manuf]">
<option>---</option>
<option>
Manuf Option
</option>
</select>
</td>
<td>
<input type="text" placeholder="Serial #" name="asset[0][serial_num]">
</td>
<td>
<input type="text" placeholder="Mac Address" name="asset[0][mac_address]">
</td>
<td>
<input type="text" placeholder="Name or Description" name="asset[0][description]">
</td>
<td>
<select id="site-0" class="chooseSite" name="asset[0][site]">
<option>---</option>
<option>
Site Option
</option>
</select>
</td>
<td>
<input type="text" placeholder="e.g Level 3 Utility Room" name="asset[0][location]">
</td>
<td>
<select id="new-site-0" name="asset[0][contact]">
</select>
</td>
</tr>
</tbody>
</table>
<input type="submit" value="Submit">
<input type="hidden" name="submitted" value="TRUE" />
</form>
This prepares the id to be incrementd as we add on new elements. Making use of the class, we can bind a .change() to each of them.
$(document).ready(function() {
$("#add").click(function() {
var newgroup = $('#myassettable tbody>tr:last');
newgroup
.clone(true)
.find("input").val("").end()
.insertAfter('#myassettable tbody>tr:last')
.find(':input')
.each(function() {
this.name = this.name.replace(/\[(\d+)\]/,
function(str, p1) {
return '[' + (parseInt(p1, 10) + 1) + ']';
});
});
var lastId = parseInt(newgroup.find(".chooseSite").attr("id").substring(5), 10);
newId = lastId + 1;
$("#myassettable tbody>tr:last .chooseSite").attr("id", "site-" + newId);
$("#myassettable tbody>tr:last select[id='new-site-" + lastId + "']").attr("id", "new-site-" + newId);
return false;
});
$("#delete").click(function() {
var $last = $('#myassettable tbody').find('tr:last');
if ($last.is(':nth-child(2)')) {
alert('This is the only one');
} else {
$last.remove();
}
});
$(".chooseSite").change(function(event) {
console.log($(this).attr("id") + " changed to " + $(this).val());
var target = "new-" + $(this).attr('id');
/*$.ajax({
type: 'post',
url: 'assetprocess.php',
data: {
get_option: $(this).val()
},
success: function(response) {
$("#" + target).html(response);
}
});*/
var response = "<option>New</option>";
$("#" + target).html(response);
});
});
Can save some time by setting a counter in global space for the number of Rows, something like var trCount = 1; and use that to set array indexes and IDs. Cloning is fast and easy, but it also means we have to go back and append various attributes. Could also make a function to draw up the HTML for you. Like: https://jsfiddle.net/Twisty/1c98Ladh/10/
function cloneRow(n) {
if (n - 1 < 0) return false;
var html = "";
html += "<tr class='removable' data-row=" + n + ">";
html += "<td><select name='asset[" + n + "][type]' id='type-" + n + "'>";
html += $("#type-" + (n - 1)).html();
html += "<select></td>";
html += "<td><select name='asset[" + n + "][manuf]' id='manuf-" + n + "'>";
html += $("#manuf-" + (n - 1)).html();
html += "<select></td>";
html += "<td><input type='text' placeholder='Serial #' name='asset[" + n + "][serial_num]' id='serial-" + n + "' /></td>";
html += "<td><input type='text' placeholder='MAC Address' name='asset[" + n + "][mac_address]' id='mac-" + n + "' /></td>";
html += "<td><input type='text' placeholder='Name or Desc.' name='asset[" + n + "][description]' id='desc-" + n + "' /></td>";
html += "<td><select name='asset[" + n + "][site]' class='chooseSite' id='site-" + n + "'>";
html += $("#site-" + (n - 1)).html();
html += "<select></td>";
html += "<td><input type='text' placeholder='E.G. Level 3 Utility Room' name='asset[" + n + "][location]' id='loc-" + n + "' /></td>";
html += "<td><select name='asset[" + n + "][contact]' id='contact-" + n + "'><select></td>";
html += "</tr>";
return html;
}
It's more work up front, yet offers a lot more control of each part. And much easier to use later.

Display text with conditions on dropdown [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am updating my previous Question:
User has to enter the amounts in text boxes: amt1, amt2, amt3
If they are selecting the option to pay 'Self' value 'S' and they need an Advance payment 'ad' as Yes 'y' then the text box adv1 should display a sum of amt1 + amt2 + amt 3 + $750.
In any other case the value in adv1 should be a 0.00 and of course the text box totalAmt should have the sum always of the amounts always.
I have tried the javascript to get the values of the options onChange and try to evaluate.
However values are not been passed on.
HTML
<table width="800" border="1" cellspacing="0" cellpadding="0">
<tr>
<th>Estimated Travel Cost</th>
<th>AED</th>
<td>
<input name="total" type="text" id "totalAmt"value="" readonly="true" style="text-align:center"/>
</td>
</tr>
<tr>
<th>Amount (AED)</th>
<th>Arranged By</th>
</tr>
<tr>
<td>Arrival (incl Taxes)</td>
<td>
<input name="amt1" id="amt1" type="text" value="0" style="text-align:center"/>
</td>
<td>
<select name = "drop1" id = "str" onChange="updateTextVal()">
<option value="S">Self</option>
<option value="C">Company</option>
</select>
</td>
</tr>
<tr>
<td>Local Travel</td>
<td>
<input name="amt2" type="text" value="" style="text-align:center"/>
</td>
<td>
<select name="drop2">
<option>Self</option>
<option>Company</option>
</select>
</td>
</tr>
<tr>
<td>Accomodation</td>
<td>
<input name="amt3" type="text" value="" style="text-align:center"/>
</td>
<td>
<select name="drop3">
<option>Self</option>
<option>Company</option>
</select>
</td>
</tr>
<td>Estimated Total Cost</td>
<td>
<input name="amt6" type="text" value="" style="text-align:center" />
</td>
<td>
<select name="drop6">
<option>Self</option>
<option>Company</option>
</select>
</td>
</tr>
<tr>
<td>Advance Required</td>
<td>
<select name="advReq" id="ad">
<option value="n">No</option>
<option value="y">Yes</option>
</select>
</td>
<td>
<input name="adv1" type="text" id="adv1" value="0" readonly="readonly" style="text-align:center"/>
</td>
</tr>
</table>
JavaScript
<script>
function updateText() {
var str = this.value;
var $vel = parseInt(document.getElementById("amt1"));
var $el = document.getElementById("adv1");
var val = document.getElementById('ad').value;
var $eval = document.getElementById('str').value;
if(val == 'y'){
if($eval == 's'){
$el.value = "750" + $vel;
} else {
$el.value = "0";
}
}
}
</script>
Html:
<table>
<tr>
<td><input name="amt1" id="txtAmt" type="text" value="" align="left" style="text-align:center" /></td>
<td><select name = "drop1" id="sc"><option value="S">Self</option><option value="C">Company</option></select></td>
</tr>
<tr>
<td>Advance Required</td>
<td><select name="advReq" id="ad">
<option value="y">Yes</option>
<option value="n">No</option>
</select>
</td>
<td><input id='re' name="adv1" type="text" readonly="readonly" value="" /></td>
</tr>
</table>
Javascript
document.getElementById('txtAmt').onkeyup = function(){
var txtV = parseInt(this.value);
var re = document.getElementById('re');
var ad = document.getElementById('ad').value;
var sc = document.getElementById('sc').value;
if(ad == 'y'){
// Yes in Advance Required
if(sc == 'S'){
// Self
re.value = 'Self: ' + (txtV + 750) + '$';
}
else{
re.value = 'Company: ' + (txtV + 750) + '$';
}
}
else{
// No in Advance Required
if(sc == 'S'){
re.value = 'Self: ' + '0.00';
}
else{
re.value = 'Company: ' + '0.00';
}
}
}
Here is demo
You should write a function that gathers the amt1, drop1 and advReq values and sets the appropriate value to adv1.
Then call it when the page is loaded OR the key is released in amt1 OR drop1/advReq select value is changed.
Don't forget that the value in amt1 might be left empty or not be an actual number.
Simply add a onClick function to each of the select elements as onclick="calculateAdvance()" defined as
function calculateAdvance()
{
if(document.forms[0].drop1.getSelectedValue == 'S' && document.forms[0].advReq.getSelectedValue == 'y')
{
var sum = eval(document.forms[0].amt1.value) + 750;
document.forsm[0].amt1.value = sum;
}
}
and change the HTML to
<td><select name = "drop1" onchange="calculateAdvance()"><option value="S">Self</option><option value="C">Company</option></select></td>
and
<select name="advReq" id="ad" onchange="calculateAdvance()">

Remove/delete part of hidden field value on button click

I am trying to build a form where users can add a course using select boxes.
When a course is added, it creates a new table row displaying the course to the user and also adds the course prefix and number (e.g. MATH120) to a hidden form field value. Finally, it adds a delete button.
The delete button should remove the table row AND the hidden input value that corresponds to the course being deleted.
Here's my jsfiddle: http://jsfiddle.net/MtJF2/10/
My script is deleting the row just fine, but its not removing the input value correctly. It's not throwing any errors. Sometimes I've noticed that it will delete the zero in the correct value (e.g. MATH120, becomes MATH12,). Any ideas what might be causing this?
HTML:
<script type="text/javascript">
function deleteCourse($course){
$('#' + $course).remove();
$course = $course + ','
alert($course);
$('#required-courses').val(function($course, value) {
return value.replace($course, '');
});
}
</script>
<table width="80%" align="center">
<tr id="add-required-course">
<td><input type="button" value="+ Add a Required Course" class="MC-big-button" onclick="$('#course-menu').slideToggle()" /></td>
</tr>
</table>
<input type="hidden" id="required-courses" name="required-courses" value="null" />
<table id="course-menu" width="80%" align="center">
<tr>
<td>Select the course prefix:</td>
<td><select id="1" name="course-prefix">
<option value="MATH">MATH</option>
<option value="BIOL">BIOL</option>
</select>
</td>
</tr>
<tr>
<td>Select the course number:</td>
<td><select id="2" name="course-num">
<option value="101">101</option>
<option value="120">120</option>
</select>
</td>
</tr>
<tr>
<td colspan="2">
<input type="button" value="Add this course" class="MC-big-button" id="save-course" />
</td>
</tr>
</table>
Javascript:
document.getElementById("save-course").onclick = buildCourse;
function buildCourse() {
var $coursePrefix = ($('#1').val());
var $courseNum = ($('#2').val());
var $course = $coursePrefix + $courseNum;
var $HTMLoutput = '<tr id="' + $course + '"><td>' + $course + '<input type="button" value="Delete" onclick="deleteCourse(\'' + $course + '\')" /></td></tr>';
var $VALUEoutput = ($('#required-courses').val());
if ($VALUEoutput == 'null') {
$VALUEoutput = $course + ',';
}
else {
$VALUEoutput = $VALUEoutput + $course + ',';
}
$('#course-menu').slideToggle();
$('#add-required-course').before($HTMLoutput);
$('#required-courses').val($VALUEoutput);
}
I found this question to be helpful, but I think my implementation is off.
You are replacing $course with a new value in the delete function at
$('#required-courses').val(function($course, value) {
// here it gets a new value which is wrong
Use it like this
function deleteCourse($course){
$('#' + $course).remove();
$course = $course + ','
alert($course);
$('#required-courses').val(function(_, value) {
return value.replace($course, '');
});
}

Categories

Resources