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, '');
});
}
Related
I have a table consist of 5 column: Code, Name, Qty, Price, and Total.
Code contain a dropbox menu which dynamically retrieve from another table. If user click the dropbox and select a code, name of the item will appear automatically in Name column.
For Total column, the value will appear from multiplying Qty and Price. The multiply script I used is:
<script language="javascript" type="text/javascript">
function multiply()
{
a=Number(document.calculator.qty.value);
b=Number(document.calculator.price.value);
c=a*b;
document.calculator.total.value=c;
}
</script>
My code for the table as below:
<table id="theTable" border="1">
<script>
var maxID = 0;
function getTemplateRow() {
var x = document.getElementById("templateRow").cloneNode(true);
x.id = "";
x.style.display = "";
x.innerHTML = x.innerHTML.replace(/{id}/, ++maxID);
return x;
}
function addRow() {
var t = document.getElementById("theTable");
var rows = t.getElementsByTagName("tr");
var r = rows[rows.length - 1];
r.parentNode.insertBefore(getTemplateRow(), r);
}
</script>
<thead>
<tr>
<th> Code </th>
<th> Name </th>
<th> Qty </th>
<th> Price </th>
<th> Total </th>
<tr>
</thead>
<tbody>
<tr id="templateRow">
<td type="text" name="code" id="code"/readonly>
<?php
mysql_connect("localhost","root","");
mysql_select_db("inventory");
$result = mysql_query("select * from input_code_data");
$jsArray = "var code = new Array();\n";
echo '<select name="code" onchange="changeValue(this.value)">';
echo '<option></option>';
while ($row = mysql_fetch_array($result)) {
echo '<option value="' . $row['code'] . '">' . $row['code'] . '</option>';
$jsArray .= "code['" . $row['code'] . "'] = {name:'" . addslashes($row['name']) . "',desc:'".addslashes($row['name'])."'};\n";
}
echo '</select>';
?>
</td>
<td><input type="text" name="name" id="name"/readonly>
<script type="text/javascript">
<?php echo $jsArray; ?>
function changeValue(id){
document.getElementById('code').value = code[id].name;
document.getElementById('name').value = code[id].desc;
};
</script>
</td>
<td><input type="text" name="qty"></td>
<td><input type="text" name="price"></td>
<td><input type="text" name="total" /readonly><INPUT type="button" value="Click" onclick="javascript:multiply();"></td>
</tr>
</tbody>
</table>
<INPUT type='button' value='+' onclick="addRow('theTable')" />
If I click add row, then a new row will appear and the format is right. The problem is, when I select a code (from the dropbox) in second row, the name appear in the first row instead, not in the second row. Another problem, Click button for multiply isn't working in the second row.
Would anybody tell me how I fix this? Thanks.
It's because your changeValue(id) function is being called with the select field's value, not the row Id. Additionally, you're getting element by static id's instead of passing them in. HTML assumes that an Id will only appear once per page, you're breaking that so it always returns the first match.
EDIT for some example code:
This deals with some of the issues (if I'm understanding you properly). You might find the MDN docs helpful around how ids and other selectors work.
multiply suffers from the same issues as your original code, but you should be able to figure it out based on what is below:
<table id="theTable" border="1">
<thead>
<tr>
<th> Code </th>
<th> Name </th>
<th> Qty </th>
<th> Price </th>
<th> Total </th>
<tr>
</thead>
<tbody>
<tr class="templateRow" id="invoice-line-1">
<td class="code">
<select onchange="changeValue(this.value, 'invoice-line-1')">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<!-- etc. -->
</select>
<span></span>
</td>
<td class="name"></td>
<td><input type="text" name="qty"></td>
<td><input type="text" name="price"></td>
<td>
<input type="text" name="total" /readonly>
<input type="button" value="Click" onclick="javascript:multiply();">
</td>
</tr>
</tbody>
</table>
<input type='button' value='+' onclick="addRow('theTable')" />
<script type="text/javascript">
var codes = {
"1": {value: 1, name: "Option 1"},
"2": {value: 2, name: "Option 2"},
// etc.
},
numRows = 1;
function changeValue(value, id){
document.querySelector('#' + id + ' td.name').innerHTML = codes[value].name;
document.querySelector('#' + id + ' td.code > span').innerHTML = code[value].value;
};
function addRow() {
var newRow = document.getElementById("invoice-line-1").cloneNode(true),
table = document.querySelector("#theTable > tbody");
newRow.id = "invoice-line-" + (numRows = numRows + 1);
table.appendChild(rewRow);
document.querySelector("#invoice-line-" + numRows + " .code > select").setAttribute('onchange', "changeValue(this.value, 'invoice-line-" + numRows + "')");
}
</script>
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.
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.
I have a form calculator, when customer submit the form(input.php), it will open another page display the results(output.php target _blank). However, when they want to use the same page(input.php) to get the result again, the submit button not working anymore, unless they change some value in the input field, and for the drop down menu, the submit button won't work, even you changed the drop down value.
Can someone please help me to fix the problems? thanks. I just want the button enabled all the time, here is the partially code from input.php.
<form name="form1" action="output.php" method="post" target="_blank">
<table id="distax" width="750">
<th colspan="6">F. Discount & Taxes</th>
<tr>
<td width="120"><b><input type="radio" name="discountmu" id="disc" value="-" />Discount (-)<br /> <input type="radio" name="discountmu" id="mu" value="+" />Markup (+)</b></td>
<td width="80">% <input type="text" name="discmuv" size="3" value="0"></td>
<td width="120"><b>2. Tax Goods:</b></td>
<td width="80">% <input type="text" name="txgood" size="3" value="0" onkeyup="data_change(this);"></td>
<td width="120"><b>3. Tax Services:</b><br />(for items in G)</td>
<td width="*">% <input type="text" name="txservice" size="3" value="0" onkeyup="data_change(this);"></td>
</tr>
<table id="extra" width="750">
<th colspan="6">E. Extras</th>
<tr>
<td width="170"><b>1. Extra railing (total):</b></td>
<td width="70"><input type="text" name="extrail" size="2" value="0" onkeyup="data_change(this);">ft</td>
<td width="110"><b>2. Custom Color: </b></td>
<td width="*"><select size="1" value="<?=$_SESSION['name']?> " name="R4" id="R4" onchange="showme()">
<option selected value="noSS">Sand Stone (Ral 1019)</option>
<option value="noEW">Euro White (Ral 9010)</option>
<option value="noQG">Quartz Grey (Ral 8014)</option>
<option value="noJB">Java Brown (Ral 8014)</option>
<option value="yes">Custom</option>
</select>
<input type="text" id="color1other" name="color1other" style=" position:relative;display:none;" Size=20 value="enter custom color here">
</td>
</tr>
<tr>
<td width="170"> <b>3. Height adjustment [ft // cm]:</b></td>
<td width="*">
<select size="1" name="D8">
<option value="1.125">+2'6" // +76cm</option>
<option value="1.1">+2'0" // +61cm</option>
<option value="1.075">+1'6" // +46cm</option>
<option value="1.05">+1'0" // +30cm</option>
<option value="1.025">+0'6" // +15cm</option>
<option selected value="1">0</option>
<option value="0.985">-0'6" // -15cm</option>
<option value="0.97">-1'0" // -30cm</option>
<option value="0.955">-1'6" // -46cm</option>
<option value="0.94">-2'0" // -61cm</option>
<option value="0.925">-2'6" // -76cm</option>
<option value="0.91">-3'0" // -91cm</option>
</select>
</td>
<td width="110"><b>4. Freight (Sea/Land/Air): </b></td>
<td width="*">
<input type="text" id="freight" name="freight" Size=12 value="0"><b>USD</b>
</td>
</tr>
<input type="Submit" Value="Get your quote"> as
<input type="radio" value="detail" checked name="report">Dealer <input type="radio" name="report" value="short"> Client version in English
</form>
thanks for the reply, here is the code for the javascript, didn't see anything related to the submit button
//Date: 05/27/2009 Edited by EG
function reload(form)
{
var val=form.cat.options[form.cat.options.selectedIndex].value;
var val3=document.form1.load.value;
//Date: 07/27/2009 Edited by EG
//self.location=self.location + '&cat=' + val + '&load=' + val3;
//self.location='webcalc_input.php?PHPSESSID=' + ssidjs + '&cat=' + val + '&load=' + val3;
self.location='webcalc_input.php?cat=' + val + '&load=' + val3;
}
function reload3(form)
{
var val=form.cat.options[form.cat.options.selectedIndex].value;
var val2=form.subcat.options[form.subcat.options.selectedIndex].value;
var val3=document.form1.load.value;
//Date: 07/27/2009 Edited by EG
self.location= 'webcalc_input.php?cat=' + val + '&cat3=' + val2 + '&load=' + val3;
//self.location='webcalc_input.php?PHPSESSID=' + ssidjs + '&cat=' + val + '&cat3=' + val2 + '&load=' + val3;
}
function data_change(field) {
var check = true;
var value = field.value; //get characters
//check that all characters are digits, ., -, or ""
for (var i = 0; i < field.value.length; ++i) {
var new_key = value.charAt(i); //cycle through characters
if (((new_key < "0") || (new_key > "9")) && !(new_key == "") && (new_key != ".")) { //Included . to enable decimal entry
check = false;
break;
}
}
//apply appropriate colour based on value
if (!check) {
field.style.backgroundColor = "red";
}
else {
field.style.backgroundColor = "white";
}
}
function validateEmpty(fld) {
var error = "";
if (fld.value.length == 0) {
fld.style.background = 'Yellow';
error = "The required field has not been filled in.\n"
} else {
fld.style.background = 'White';
}
return error;
}
The text input contains a javascript function which you don't show in your code called data_change(). If I understand the question, its likely that that function is disabling the submit button and enabling it when the text changes. This is only an assumption without seeing your javascript code.
enter code here
Find the definition of the data_change() function and look for something relating to the submit button and comment it out.
You may remove the onkeyup="data_change(this);" from the <input> tag, but that could break other functionality!
I am working on a new system and am stuck at a point with jquery + ajax and getting it work work correctly with the other things happening on the page.
Basically the page is to submit a quote and on the page you can add as many quote items as you want. When someone clicks on new item it runs the below code wich gets the value of a hidden element and uses it in all of the new elements Ids in order to keep them all unique.
New Product code:
function addFormField() {
var id = document.getElementById("field_id").value;
$("#products").append("
<table width='600' cellpadding='5' cellspacing='0' class='Add_Products' id='row" + id + "'>
<td width='250' class='left'>
<label>Select Product Category</label>
</td>
<td class='right' >
<label><select name='ProductCategory' id='ProductCategory'>
<?php foreach($categories as $key=>$category){
echo "<option value=".$key.">".$category."</option>";
}
?>
</select>
</label>
</td>
</tr>
<tr>
<td width='250' class='left'>
<label>Select Product Template</label>
</td>
<td class='right' >
<label>
<select name='data[QuoteItem][" + id + "][product_id]' id='QuoteItem" + id + "product_id'></select>
</label>
</td>
</tr>
<tr >
<td class='left'>Name</td>
<td class='right'>
<label>
<input name='data[QuoteItem][" + id + "][name]' type='text' id='QuoteItem" + id + "name' size='50' />
</label>
</td>
</tr>
<tr >
<td class='left'>
Price (ex GST)
</td>
<td class='right'>
<input type='text' name='data[QuoteItem][" + id + "][price]' id='QuoteItem" + id + "price' onchange='totalProductPrice();' class='quote-item-price' />
</td>
</tr>
<tr>
<td class='left'>
Description
</td>
<td class='right'>
<label>
<textarea name='data[QuoteItem][" + id + "][description]' cols='38' rows='5' id='QuoteItem" + id + "description'>
</textarea>
</label>
</td>
</tr>
<tr>
<td>
<a href='#' onClick='removeFormField(\"#row" + id + "\"); return false;'>Remove</a>
</td>
</tr>
</table>
");
$('#row' + id).highlightFade({
speed:1000
});
id = (id - 1) + 2;
document.getElementById("field_id").value = id;
}
The next thing i want to do is setup an AJAX query using jQuery that when selected will request the appropriate data and populate the products box but i cannot figure out how to get the ID of that set of elements to ensure that the correct dropdown box is populated and also to make sure that the onchange is detected for the correct box.
Ive tried methods like adding the ID to the id of the dropdown box but then the onchagne doesnt work.
My jquery ajax code is below that retreives the list of products
$(function(){
$("select#ProductCategory").change(function(){
var url = "productList/" + $(this).val() + "";
var id = $("select#ProductCategory").attr('name');
$.getJSON(url,{id: $(this).val(), ajax: 'true'}, function(j){
var options = '';
options += '<option value="0">None</option>';
$.each(j, function(key, value){
options += '<option value="' + key + '">' + value + '</option>';
})
$("select#QuoteItem" + id + "product_id").html(options);
})
})
})
For the life on my cannot figure this out so if anyone could shed some light on the best way to do it that would be great.
ALso if i need to clarify further let me know because im strugling to explain it.
Thanks in advance
I have similar functionality in my project. Here how I do it:
I have a global variable that start with 0, and increased every time new field added:
var num = 0;
jQuery(function($){
$("#add_field").click(function(){
num++;
//here add new field, with id contains 'num'
});
});
to make it easier to debug, you should start with a simple element, test it so it's bug free, and add more field to it.
To submit form via AJAX, use jQuery form plugins, so you don't need to add all fields manually in ajax code that submit the form.