straight to the point:
function dell(a) {
var id = a.split('');
var rs_array = ["nr", "ps", "aan", "des", "subs", "del"];
var r_array = ["artnr", "ps", "aan", "des", "subtots", "del"];
for (i = 0; i < 6; i++) //ligt aan nummer
{
var regels = document.getElementById(rs_array[i]);
regels.removeChild(document.getElementById(r_array[i] + id[3]));
}
}
With this code im trying to detele some input elements
for r = 0 to a_rows-1 step 1%>
<tr id="regels">
<td width="auto" id="nr">
<input type="text" name="artid" id="artnr<%=r%>" value="<%=records(1,r)%>" size="6">
</td>
<td id="ps">
<input type="text" name="ps" id="ps<%=r%>" onfocus="this.blur()" value="<%=records(2,r)%>" size="7">
</td>
<td id="aan">
<input type="text" name="aan" id="aan<%=r%>" onkeyup="sub(this.id,this.value);count()" value="<%=records(3,r)%>" size="2">
</td>
<td id="des">
<input type="text" name="omschr" id="des<%=r%>" value="<%=records(4,r)%>" size="50">
</td>
<td id="subs">
<input type="text" name="subtots" id="subtots<%=r%>" onfocus="this.blur()" value="<%=records(5,r)%>" size="7">
</td>
<td id="del">
<div id="del<%=r%>" onclick="dell(this.id)" style="cursor:pointer;border:1px black solid;font-size:20px">-</div>
</td>
</tr>
<% next
This comes out of the database of mine. I'm trying to delete the input elements by giving them a id with a number.
The strange thing is: I can delete the first row, but after that it says: 'NotFoundError: DOM Exception 8' when i try to delete another one.
Please help me. If you need more info about my code or something, you can ask it
It's a lot easier not to hardcode the parent element. Get the parent straight from the original element reference:
function dell(a) {
var id = a.split('');
var r_array = ["artnr", "ps", "aan", "des", "subtots", "del"];
for (var i = 0; i < r_array.length; i++) {
var element = document.getElementById(r_array[i] + id[3]);
if (element) {
element.parentNode.removeChild(element);
}
}
}
Related
so what im trying to do is to add the "change" functionality in my code, it works for only the first td but not any other, when i click the other td it automaticly edits the first one.
does anyone know why my code is only changing the td>name/td> and not the td>adress/td> or any other td>
html:
<form id="registrering">
<label>Navn: <input id="inpnavn" placeholder="Raahim Khan" type="text" required></label>
<label>Adresse: <input id="inpadresse" type="text" placeholder="Adresse 12" required></label>
<label>Mobilnummer: <input id="inpmobilnummer" placeholder="12345678" required></select></label>
<label>Kjønn:
<select id="inpkjønn" required>
<option value="" selected disabled hidden>Velg kjønn</option>
<option>Mann</option>
<option>Kvinne</option>
<option>intetkjønn</option>
</select>
</label>
<button type="submit">Send inn</button>
</form>
//showing the data on website
function hentruss(snapshot){
var pk = snapshot.key;
var nyruss = snapshot.val();
var russref = database.ref("russ/" + nyruss.russ);
russref.on("value", function(snapshotruss){
var russobj = snapshotruss.val();
txttabell.innerHTML += `
<tr id="${pk}">
<td><label class="russlabel" onclick="edit('${pk}')">${nyruss.navn}</label><input type="text" class="editItem" style="display:none"></td>
<td><label class="russlabel" onclick="edit('${pk}')">${nyruss.adresse}</label><input type="text" class="editItem" style="display:none"></td>
<td>${nyruss.mobilnummer}</td>
<td>${nyruss.kjønn}</td>
<td><label class="delete" onclick="slett('${pk}')"><button>Slett</button></label></td>
</tr>
`;
});
}
//update the name,adress etc by clicking the element.
function edit(pk) {
var russen = russ.child(pk);
var label = document.querySelector(`#${pk} .russlabel`);
label.style.display = "none";
var tekst = label.innerText;
var inputfelt = document.querySelector(`#${pk} .editItem`);
inputfelt.style.display = "block";
inputfelt.value = tekst;
inputfelt.focus();
inputfelt.onblur = function() {
inputfelt.style.display = "none";
label.style.display = "block";
};
inputfelt.onchange = function() {
russen.update( {tekst: inputfelt.value} )
inputfelt.style.display = "none";
label.style.display = "block";
label.innerText = inputfelt.value;
};
}
It's a little hard to give an exact solution as the code snippets you have shared have a lot of calls to function whose context is not clear.. I have done my best to illustrate how you can do what you are trying to.. Maybe this will help get started in the right direction:
function handleSubmit(form) {
// Simulate creation of item using a form
var name = form.name.value;
var mobile = form.mobile.value;
// Generate random pk for demonstration
var pk = `pk${+new Date()}`;
var tableBody = document.querySelector('table tbody');
tableBody.innerHTML += ` <tr>
<td>
<label class="russlabel" onclick="edit(this)" data-pk="1" data-field="name">${name}</label>
<input class="editItem" style="display:none;" />
</td>
<td>
<label class="russlabel" onclick="edit(this)" data-pk="1" data-field="mobile">${mobile}</label>
<input class="editItem" style="display:none;" />
</td>
</tr>`;
return false;
}
function edit(label) {
var pk = label.dataset.pk;
var field = label.dataset.field;
var input = label.parentElement.children[1]; // Use label.parent.querySelector('input') if DOM is more complex
label.style = 'display:none;';
input.style = 'disply:block;';
input.focus();
input.value = label.innerHTML;
input.onchange = function() {
// pk and field are available here
// to Update DB state?? not sure how this code works
//var russen = russ.child(pk);
//russen.update( {tekst: inputfelt.value} )
}
input.onblur = function() {
label.innerHTML = input.value;
label.style = 'display:block;';
input.style = 'display:none;';
}
}
td {
padding: 0.5rem 0;
border-bottom: 1px solid black;
}
form {
margin: 1rem auto;
}
<form id="entry" onsubmit="return handleSubmit(this);">
<input name="name" placeholder="Name" />
<input name="mobile" placeholder="mobile" />
<input type="submit" value="Add Entry" />
</form>
<table>
<thead>
<tr>
<th>Name</th>
<th>Mobile</th>
</thead>
<tbody>
<tr>
<td>
<label class="russlabel" onclick="edit(this)" data-pk="1" data-field="name">Tom</label>
<input class="editItem" style="display:none;" />
</td>
<td>
<label class="russlabel" onclick="edit(this)" data-pk="1" data-field="mobile">1234</label>
<input class="editItem" style="display:none;" />
</td>
</tr>
</tbody>
</table>
Some notes:
It may be a good idea to read up on/ brush up on JS Events Here and refactor out the in line event handlers - these make your code hard to maintain, read, reason about, debug and are generally a bad idea.
Same goes for inline styles - avoid them. Try using classes with supporting styles in a stylesheet instead. (For example, on clicking a label, we could add an active class to the td element which in turn automatically hides the label and shows the input.
It's bad practice to reassign listeners to the inputs each time the label is clicked. The same functionality can be handled in a simpler and more graceful manner by using something like Event Delegation
I'm trying to tab automatically to the next tabindex after a condition is met. Any idea how I can access the tabindex, without using the id tag of the next element?.
HTML:
<tr>
<td id = "t3"> <input type="text" id = "ate" oninput="ate()" tabindex= "1" class = "tabable"/> </td>
<td id = "t3"> <input type="text" id = "eaten" oninput ="eaten()" tabindex= "2" class = "tabable" /> </td>
</tr>
JS
function ate(){
var value = document.getElementById("ate").value;
var get_tab = document.getElementById("ate").getAttribute('tabindex');
var next_tab = get_tab + 1 ;
if (value == "ate") {
$('#ate').fadeTo(1000, 0);
$('#ate').prop('tabIndex', -1);
//document.getAttribute('tabindex'); ??
}
Yo can select an element with this selector:
$('input[tabindex="2"]')
Find the next input using the classname .tabable and add .focus().
Here is a live example:
function ate() {
var value = document.getElementById("ate").value;
var get_tab = document.getElementById("ate").getAttribute('tabindex');
var next_tab = get_tab + 1;
if (value == "ate") {
$('#ate').fadeTo(1000, 0);
$('#ate').prop('tabIndex', -1);
//document.getAttribute('tabindex'); ??
$('#ate').next('.tabable').focus();
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tr>
<td id="t3">
<input type="text" id="ate" oninput="ate()" tabindex="1" class="tabable" />
</td>
<td id="t3">
<input type="text" id="eaten" oninput="eaten()" tabindex="2" class="tabable" />
</td>
</tr>
Consider this HTML (part of a table in a form):
<tr id="EnterForRow">
<td>Entered for</td>
<td><input type="radio" name="enterfor" value "0" checked>Myself
<input type="radio" name="enterfor" value "1">Someone Else </td>
</tr>
<tr id="PrayerForRow">
<td>Prayer for </td>
<td> <input type="radio" name="prayerfor" value="0" checked>Myself
<input type="radio" name="prayerfor" value="1">Someone Else </td>
</tr>
When users click Someone Else, I have Javascript to make a new text input box appear on the row. The Javascript for PrayerForRow works but the Javascript for EnterForRow does not work. I can't see any obvious differences. I think I have been staring at it too long..
This works:
var prayforRad = document.getElementsByName('prayerfor');
for(var i = 0; i < prayforRad.length; i++)
{
prayforRad[i].onclick = function()
{
var theValue = radioValue(document.getElementsByName('prayerfor'));
if (theValue == "1")
{
if (!document.getElementById("pfor"))
{
var newTd = document.createElement("td");
newTd.setAttribute("id", "pfor");
var pforRow = document.getElementById("PrayerForRow");
pforRow.appendChild(newTd);
newTd.innerHTML = '<td>For: <input type="text" name="PrayFor" id="PrayFor" size="25"></td>';
}
}
else
{
if (document.getElementById("pfor"))
{
var pforRow = document.getElementById("PrayerForRow");
var pf = document.getElementById("pfor");
pforRow.removeChild(pf);
}
}
}
}
This does not:
var enterforRad = document.getElementsByName('enterfor');
for(var j = 0; j < enterforRad.length; j++)
{
enterforRad[j].onclick = function()
{
var theValue2 = radioValue(document.getElementsByName('enterfor'));
if (theValue2 == "1")
{
if (!document.getElementById("efor"))
{
var newTD2 = document.createElement("td");
newTD2.setAttribute("id", "efor");
var eforRow = document.getElementById("EnterForRow");
eforRow.appendChild(newTD2);
newTD2.innerHTML = '<td>For: <input type="text" name="EntFor" id="EntFor" size="25"></td>';
}
}
else
{
if (document.getElementById("efor"))
{
var eforRow = document.getElementById("EnterForRow");
var ef = document.getElementById("efor");
eforRow.removeChild(ef);
}
}
}
}
Any pointers are appreciated.
<td><input type="radio" name="enterfor" value "0" checked>Myself
<input type="radio" name="enterfor" value "1">Someone Else </td>
i think you have lost two "="
As I suggested in the comment, it is better to hide/display an existing element than creating those optional elements based on the condition like
<tr id="EnterForRow">
<td>Entered for</td>
<td>
<input type="radio" name="enterfor" value="0" checked />Myself
<input type="radio" name="enterfor" value="1" />Someone Else
</td>
<td id="efor" style="display: none">For:
<input type="text" name="EntFor" id="EntFor" size="25" />
</td>
</tr>
<tr id="PrayerForRow">
<td>Prayer for</td>
<td>
<input type="radio" name="prayerfor" value="0" checked />Myself
<input type="radio" name="prayerfor" value="1" />Someone Else
</td>
<td id="pfor" style="display: none">For:
<input type="text" name="PrayFor" id="PrayFor" size="25" />
</td>
</tr>
then
var prayforRad = document.getElementsByName('prayerfor');
for (var i = 0; i < prayforRad.length; i++) {
prayforRad[i].onclick = function () {
var theValue = radioValue(document.getElementsByName('prayerfor'));
var pf = document.getElementById("pfor");
pf.style.display = theValue == '1' ? '' : 'none'
}
}
var enterforRad = document.getElementsByName('enterfor');
for (var j = 0; j < enterforRad.length; j++) {
enterforRad[j].onclick = function () {
var theValue2 = radioValue(document.getElementsByName('enterfor'));
var ef = document.getElementById("efor");
ef.style.display = theValue2 == '1' ? '' : 'none'
}
}
Demo: Fiddle
Also I would recommend using addEventListener() to add the listener instead of using onclick property
In the code below it works great to clone the table, but it doesn't go deep enough to rename the inputs of each form field in the table. For example Attendee1, Attendee2, Attendee3 etc.
Is there a way instead of just grabbing NewEl.children a way to just find all the input elements within the table then rename them?
I am not trying to add a row, I need to clone the entire table.
Any help you all out there in cyberland can give will be greatly appreciated.
<form name="EditRoster" method="post" action="DoRoster.php">
<table id="RosterTbl" cellspacing="0" cellpadding="2">
<tr style="text-align:left;vertical-align:top;">
<td><b>Name</b>:</td>
<td>
<input type="text" name="Attendee" value="" size="25" onclick="alert(this.name)">
</td>
<td><b>Paid</b>:</td>
<td>
<input type="checkbox" name="Paid" value="Yes" size="25">
</td>
</tr>
<tr style="text-align:left;vertical-align:top;">
<td><b>Email</b>:</td>
<td>
<input type="text" name="Email" value="" size="25">
</td>
<td><b>Paid When</b>:</td>
<td>
<input type="text" name="PaidWhen" value="" size="10">
</td>
</tr>
</table>
<div style="padding:5px;">
<input type="hidden" name="NumStudents" value="0">
<input type="button" name="AddPersonButton" value="Add Person" onclick="CloneElement('RosterTbl','NumStudents');">
</div>
</form>
<script language="javascript">
var TheForm = document.forms.EditRoster;
function CloneElement(ElToCloneId, CounterEl) {
var CloneCount = TheForm[CounterEl].value;
CloneCount++;
TheForm[CounterEl].value = CloneCount;
var ElToClone = document.getElementById(ElToCloneId);
var NewEl = ElToClone.cloneNode(true);
NewEl.id = ElToCloneId + CloneCount;
NewEl.style.display = "block";
var NewField = NewEl.children;
for (var i = 0; i < NewField.length; i++) {
var InputName = NewField[i].name;
if (InputName) {
NewField[i].name = InputName + CloneCount;
}
var insertHere = document.getElementById(ElToCloneId);
insertHere.parentNode.insertBefore(NewEl, insertHere);
}
}
</script>
Looked like you were on the right track, but I think you were taking a few extra steps, so I think I simplified it ;)
One thing you were missing was that the value of NumStudents is returned as a string so you have to call parseInt() on it.
var theForm = document.forms.EditRoster;
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
function CloneElement(cloneID, counterName) {
var clone = document.getElementById(cloneID);
var newClone = clone.cloneNode(true);
var counter = theForm[counterName].value = parseInt(theForm[counterName].value) + 1;
// Update the form ID
newClone.id = newClone.id + counter;
// Update the child Names
var items = newClone.getElementsByTagName("*");
for (var i = 0; i < items.length; i++) {
if (items[i].name != null)
items[i].name = items[i].name + counter;
}
insertAfter(clone, newClone);
}
Here's a working copy on jsFiddle.
P.s. I wasn't sure if you wanted the new fields clearing so I left them.
I'm a bit stuck with javascript again. Basically when you click a button a new row of fields will appear, giving them a new name just a different number.
I now need these fields to be able to auto sum by themself, i can do this with the first row I just don't know how to do them with the new generated ones.
The Javascript code:
<script language="javascript" type="text/javascript">
var i=2;
function addRow()
{
var tbl = document.getElementById('customersAdd');
var lastRow = tbl.rows.length;
var iteration = lastRow - 1;
var row = tbl.insertRow(lastRow);
var firstCell = row.insertCell(0);
var el = document.createElement('input');
el.placeholder = 'Quantity';
el.type = 'text';
el.name = 'quantity' + i;
el.id = 'quantity' + i;
firstCell.appendChild(el);
var secondCell = row.insertCell(1);
var el2 = document.createElement('input');
el2.placeholder = 'Description';
el2.type = 'text';
el2.name = 'description' + i;
el2.id = 'description' + i;
secondCell.appendChild(el2);
var thirdCell = row.insertCell(2);
var el3 = document.createElement('input');
el3.placeholder = 'Rate';
el3.type = 'text';
el3.name = 'rate' + i;
el3.id = 'rate' + i;
thirdCell.appendChild(el3);
var forthCell = row.insertCell(3);
var el4 = document.createElement('input');
el4.placeholder = 'Amount';
el4.type = 'text';
el4.name = 'amount' + i;
el4.id = 'amount' + i;
forthCell.appendChild(el4);
// alert(i);
i++;
// alert(i);
}
function startCalc(){
interval = setInterval("calc()",1);
}
function calc(){
one = document.main.quantity1.value;
two = document.main.rate1.value;
document.main.amount1.value = (one * 1) * (two * 1);
}
function stopCalc(){
clearInterval(interval);
}
</script>
The HTML code:
<form action="submit.php" name="main" method="post">
<table style="border-collapse: collapse;" border="0" align="center" width="50%" class="horiz" id="customersAdd">
<tr>
<td align="center"><br/>
<input class="text" style="width:100%" type="button" align="middle"value="Add Aditional Row" onClick="addRow()" /></td>
</tr>
<tr align="center">
<td>
<br />
<input placeholder="Quantity" type="text" name="quantity1" id="quantity1" onFocus="startCalc();" onBlur="stopCalc();" />
<br /></td>
<td>
<br />
<input placeholder="Description" type="text" name="description1" id="description1"/>
<br /></td>
<td>
<br />
<input placeholder="Rate" type="text" name="rate1" id="rate1" onFocus="startCalc();" onBlur="stopCalc();"/>
<br /></td>
<td>
<br />
<input placeholder="Amount" type="text" name="amount1" id="amount1" onBlur="stopCalc();" onFocus="startCalc();" readonly="true" />
<br /></td>
</tr>
</table></form>
To make things easier for anyone who could help me I have made this in JSBin to see it easier of what i want to do. Any suggestions are appreciated.
http://jsbin.com/atabaz/1/edit
Thanks
In the end I managed to find a way on how to do this myself, if anyone is interested take a look at this:
http://jsfiddle.net/2sYgE/
var currentItem = 1;
$('#customersAdd').on('keyup', '.quantity, .rate, .amount', calculateRow);
$('#addnew').click(function() {
currentItem++;
$('#customersAdd').append('<tr><td><input placeholder="Quantity" type="text" name="quantity' + currentItem +'" id="quantity' + currentItem +'" class="qty form-input-rate" /></td><td><input placeholder="Description" type="text" name="description' + currentItem +'" id="description' + currentItem +'" class="form-input-rate"/></td><td><input placeholder="Rate" type="text" name="rate' + currentItem +'" id="rate' + currentItem +'" class="rate form-input-rate"/></td><td><input placeholder="Amount" type="text" name="amount' + currentItem +'" id="amount' + currentItem +'" class="cal form-input-rate"/></td></tr>'
);
});
function calculateSum() {
var sum = 0;
$(".cal").each(function () {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
}
function calculateRow() {
var cost = 0;
var $row = $(this).closest("tr");
var qty = parseFloat($row.find('.qty').val());
// changed the following line to only look within the current row
var rate = parseFloat($row.find('.rate').val());
cost = qty * rate;
if (isNaN(cost)) {
$row.find('.cal').val("0");
} else {
$row.find('.cal').val(cost);
}
calculateSum();
}
Polling for changes is a very inefficient and error–prone way to do form updates. Listening for change events is a better way to go as it uses fewer resources and waits until the user has finished updating the control before doing anything. There is also an input event that can be used, but it's not suitable here as it will update the form as the user enters values. Much better to wait for the user to finish entering values, then do the update.
I've re–factored your code below, it's not ready for production but it should give you some idea of how to go about it. Table rows are cloned as it's much faster than creating all the elements from scratch. Then names are modified, though this isn't really necessary. There is no need for ID attributes.
Cloning only works reliably here if inline listeners are used on the form controls. If the initial listeners are dynamically attached, you'll have to add them each time a row is added as listeners added using addEventListener are not cloned.
I haven't included any input validation, if the user puts in junk, they get junk back. You should validate input to check that appropriate values are being entered, and also format the displayed values for presentation.
<script type="text/javascript">
function addRow(element) {
var form = element.form;
var table = form.getElementsByTagName('table')[0];
var tbody = table.tBodies[0];
var num = tbody.rows.length - 1;
var row = table.rows[1].cloneNode(true);
var input, inputs = row.getElementsByTagName('input')
// Update input names
for (var i=0, iLen=inputs.length; i<iLen; i++) {
input = inputs[i];
input.name = input.name.replace(/\d+$/,num);
input.value = '';
}
tbody.insertBefore(row, tbody.rows[tbody.rows.length - 1]);
}
function updateRow(element) {
var form = element.form;
var num = element.name.replace(/^\D+/,'');
var value = form['quantity' + num].value * form['rate' + num].value;
form['amount' + num].value = (value == 0)? '' : value;
updateTotal(form);
}
function updateTotal(form) {
var elements = form.elements;
var name = /^amount/;
var total = 0;
var value;
for (var i=0, iLen=elements.length; i<iLen; i++) {
if (name.test(elements[i].name)) {
total += parseFloat(elements[i].value);
}
}
form.total.value = total;
}
</script>
<form action="submit.php" name="main" method="post">
<table style="border-collapse: collapse;" border="0" align="center"
width="50%" class="horiz" id="customersAdd">
<tr>
<td><br>
<input class="text" style="width:100%" type="button"
align="middle"value="Add Aditional Row" onclick="addRow(this)">
</td>
</tr>
<tr>
<td>
<input placeholder="Quantity" name="quantity1" onblur="updateRow(this);">
</td>
<td>
<input placeholder="Description" type="text" name="description1">
</td>
<td>
<input placeholder="Rate" name="rate1" onchange="updateRow(this);">
</td>
<td>
<input placeholder="Amount" name="amount1" readonly>
</td>
</tr>
<tr>
<td colspan="3" style="text-align: right">Total
<td><input name="total" readonly>
</tr>
</table>
<input type="reset">
</form>