I have a snippet of HTML which is the simple version of my site. The inputs name is related to the row index. So, I am wondering how to change the inputs' onchange event using the jQuery?
For each row, it has its own function related to the row index. For example, for tr index = 0, it has the function Test1(), for tr index = 1, it has the function Test2()...
Cannot simply using the input selector, because there are some other inputs in the page. Only the id and name for the input are unique.
<tr stampId = '1001' index = '0'>
<td>
<span>
<input type="text" name="QuickOrderQty#6#0#1" id="QuickOrderQty#6#0#1" ct="Field" onchange=" SaveControlState(event,'Text');">
</span>
</td>
</tr>
<tr stampId = '1001' index = '1'>
<td>
<span>
<input type="text" name="QuickOrderQty#6#1#1" id="QuickOrderQty#6#1#1" ct="Field" onchange=" SaveControlState(event,'Text');">
</span>
</td>
</tr>
<tr stampId = '1001' index = '2'>
<td>
<span>
<input type="text" name="QuickOrderQty#6#2#1" id="QuickOrderQty#6#2#1" ct="Field" onchange=" SaveControlState(event,'Text');">
</span>
</td>
</tr>
<tr stampId = '1001' index = '3'>
<td>
<span>
<input type="text" name="QuickOrderQty#6#3#1" id="QuickOrderQty#6#3#1" ct="Field" onchange=" SaveControlState(event,'Text');">
</span>
</td>
</tr>
Well, maybe I should put my desired result here.
<script>Do something here, then change the onchange events to below.</script>
<tr stampId = '1001' index = '0'>
<td>
<span>
<input type="text" name="QuickOrderQty#6#0#1" id="QuickOrderQty#6#0#1" ct="Field" onchange="Test1();">
</span>
</td>
</tr>
<tr stampId = '1001' index = '1'>
<td>
<span>
<input type="text" name="QuickOrderQty#6#1#1" id="QuickOrderQty#6#1#1" ct="Field" onchange="Test2();">
</span>
</td>
</tr>
<tr stampId = '1001' index = '2'>
<td>
<span>
<input type="text" name="QuickOrderQty#6#2#1" id="QuickOrderQty#6#2#1" ct="Field" onchange="Test3();">
</span>
</td>
</tr>
<tr stampId = '1001' index = '3'>
<td>
<span>
<input type="text" name="QuickOrderQty#6#3#1" id="QuickOrderQty#6#3#1" ct="Field" onchange="Test4();">
</span>
</td>
</tr>
Sorry if any mistakes occurred. This is my first time answering questions. I am not even that experienced.
if I understood you correctly, you want to know the element that caused the event to trigger. You can use the word this
$("input").change(function(event) {
var x = $(this).val();
// x = the value of the input element that triggered the event.
});
I hope this helps.
If you're using jQuery, you shouldnt be using inline onchange event handlers. Also, if you wish to target multiple elements with the same behaviour use a shared class. If you do both those things this becomes trivial using jQuery's index() method:
var functions = {
Test1: function(){ console.log("TextBox1 changed") },
Test2: function(){ console.log("TextBox2 changed") },
Test3: function(){ console.log("TextBox3 changed") },
Test4: function(){ console.log("TextBox4 changed") }
}
$(document).on('change','.myClass',function(){
var index = $(this).index();
functions["Test" + index]();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="myClass">
<input type="text" class="myClass">
<input type="text" class="myClass">
<input type="text" class="myClass">
Related
https://jsfiddle.net/en6jh7pa/1/
I am having issues grabbing the next element, it is returning null for the next element.
I am passing "this? as onclick and I assumed that you could use this to grab the next element but it seems that it instead returns null
Thanks for your help
function assignnames(checkboxelement){
checkboxelement.setAttribute("name", "checkbox");
var value1box = checkboxelement.nextSibling;
value1box.setAttribute("name", "notnull");
var value2box = checkboxelement.nextElementSibling;
value2box.setAttribute("name", "notnull");
alert("done");
}
<table border="1">
<tr>
<th>
Checkbox
</th>
<th>
value1
</th>
<th>
value2
</th>
</tr>
<tr>
<td>
<input type="checkbox" onclick="assignnames(this)" id="checkbox1"/>
</td>
<td>
<input type="text" name="" id="fname1">
</td>
<td>
<input type="text" name="" id="lname1">
</td>
</tr>
</table>
If you want to get the text inputs in the same row, you can go up to the row, then use a selector to get the inputs, e.g.
function getParent(node, tag) {
var tag = tag.toLowerCase();
do {
if (node.tagName.toLowerCase() == tag) {
return node;
}
node = node.parentNode;
} while (node && node.tagName && node.parentNode)
return null;
}
function getInputs(evt) {
var row = getParent(this, 'tr');
var inputs;
if (row) {
inputs = row.querySelectorAll('input[type="text"]');
}
console.log(`Found ${inputs.length} text inputs, node is ${this.checked? '':'not '}checked.`);
}
window.onload = function(){
document.getElementById('checkbox1').addEventListener('click', getInputs, false);
};
<table border="1">
<tr><th>Checkbox
<th>value1
<th>value2
<tr><td><input type="checkbox" id="checkbox1">
<td><input type="text" name="" id="fname1">
<td><input type="text" name="" id="lname1">
</table>
For the inputs to be siblings, they would all have to be within the same <td>, sharing a singular parent. With them spread out across multiple table cells, they would be considered cousins instead (keeping with the family tree metaphor), which doesn't have a similar shortcut property.
You can still use nextElementSibling along the way between inputs, but you'll also have to move up and back down between generations.
function assignnames(checkboxelement){
checkboxelement.setAttribute("name", "checkbox");
var value1box = checkboxelement
.parentElement // up a generation the checkbox' parent <td>
.nextElementSibling // then to the next <td> in the row
.firstElementChild; // and back down a generation to the next input
// the last step could also be: .querySelector('input')
value1box.setAttribute("name", "notnull");
var value2box = value1box
.parentElement
.nextElementSibling
.firstElementChild;
value2box.setAttribute("name", "notnull");
alert("done");
}
<table border="1">
<tr>
<th>
Checkbox
</th>
<th>
value1
</th>
<th>
value2
</th>
</tr>
<tr>
<td>
<input type="checkbox" onclick="assignnames(this)" id="checkbox1"/>
</td>
<td>
<input type="text" name="" id="fname1">
</td>
<td>
<input type="text" name="" id="lname1">
</td>
</tr>
</table>
I have this table with some dependents information and there is a add and delete button for each row to add/delete additional dependents. When I click "add" button, a new row gets added to the table, but when I click the "delete" button, it deletes the header row first and then on subsequent clicking, it deletes the corresponding row.
Here is what I have:
Javascript code
function deleteRow(row){
var d = row.parentNode.parentNode.rowIndex;
document.getElementById('dsTable').deleteRow(d);
}
HTML code
<table id = 'dsTable' >
<tr>
<td> Relationship Type </td>
<td> Date of Birth </td>
<td> Gender </td>
</tr>
<tr>
<td> Spouse </td>
<td> 1980-22-03 </td>
<td> female </td>
<td> <input type="button" id ="addDep" value="Add" onclick = "add()" </td>
<td> <input type="button" id ="deleteDep" value="Delete" onclick = "deleteRow(this)" </td>
</tr>
<tr>
<td> Child </td>
<td> 2008-23-06 </td>
<td> female </td>
<td> <input type="button" id ="addDep" value="Add" onclick = "add()"</td>
<td> <input type="button" id ="deleteDep" value="Delete" onclick = "deleteRow(this)" </td>
</tr>
</table>
JavaScript with a few modifications:
function deleteRow(btn) {
var row = btn.parentNode.parentNode;
row.parentNode.removeChild(row);
}
And the HTML with a little difference:
<table id="dsTable">
<tbody>
<tr>
<td>Relationship Type</td>
<td>Date of Birth</td>
<td>Gender</td>
</tr>
<tr>
<td>Spouse</td>
<td>1980-22-03</td>
<td>female</td>
<td><input type="button" value="Add" onclick="add()"/></td>
<td><input type="button" value="Delete" onclick="deleteRow(this)"/></td>
</tr>
<tr>
<td>Child</td>
<td>2008-23-06</td>
<td>female</td>
<td><input type="button" value="Add" onclick="add()"/></td>
<td><input type="button" value="Delete" onclick="deleteRow(this)"/></td>
</tr>
</tbody>
</table>
jQuery has a nice function for removing elements from the DOM.
The closest() function is cool because it will "get the first element that matches the selector by testing the element itself and traversing up through its ancestors."
$(this).closest("tr").remove();
Each delete button could run that very succinct code with a function call.
Lots of good answers, but here is one more ;)
You can add handler for the click to the table
<table id = 'dsTable' onclick="tableclick(event)">
And then just find out what the target of the event was
function tableclick(e) {
if(!e)
e = window.event;
if(e.target.value == "Delete")
deleteRow( e.target.parentNode.parentNode.rowIndex );
}
Then you don't have to add event handlers for each row and your html looks neater. If you don't want any javascript in your html you can even add the handler when page loads:
document.getElementById('dsTable').addEventListener('click',tableclick,false);
Here is working code: http://jsfiddle.net/hX4f4/2/
I would try formatting your table correctly first off like so:
I cannot help but thinking that formatting the table could at the very least not do any harm.
<table>
<thead>
<th>Header1</th>
......
</thead>
<tbody>
<tr><td>Content1</td>....</tr>
......
</tbody>
</table>
Here's the code JS Bin using jQuery. Tested on all the browsers. Here, we have to click the rows in order to delete it with beautiful effect. Hope it helps.
I suggest using jQuery. What you are doing right now is easy to achieve without jQuery, but as you will want new features and more functionality, jQuery will save you a lot of time. I would also like to mention that you shouldn't have multiple DOM elements with the same ID in one document. In such case use class attribute.
html:
<table id="dsTable">
<tr>
<td> Relationship Type </td>
<td> Date of Birth </td>
<td> Gender </td>
</tr>
<tr>
<td> Spouse </td>
<td> 1980-22-03 </td>
<td> female </td>
<td> <input type="button" class="addDep" value="Add"/></td>
<td> <input type="button" class="deleteDep" value="Delete"/></td>
</tr>
<tr>
<td> Child </td>
<td> 2008-23-06 </td>
<td> female </td>
<td> <input type="button" class="addDep" value="Add"/></td>
<td> <input type="button" class="deleteDep" value="Delete"/></td>
</tr>
</table>
javascript:
$('body').on('click', 'input.deleteDep', function() {
$(this).parents('tr').remove();
});
Remember that you need to reference jQuery:
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
Here a working jsfiddle example:
http://jsfiddle.net/p9dey/1/
Use the following code to delete the particular row of table
<td>
<asp:ImageButton ID="imgDeleteAction" runat="server" ImageUrl="~/Images/trash.png" OnClientClick="DeleteRow(this);return false;"/>
</td>
function DeleteRow(element) {
document.getElementById("tableID").deleteRow(element.parentNode.parentNode.rowIndex);
}
try this for insert
var table = document.getElementById("myTable");
var row = table.insertRow(0);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
cell1.innerHTML = "NEW CELL1";
cell2.innerHTML = "NEW CELL2";
and this for delete
document.getElementById("myTable").deleteRow(0);
Yeah It is working great
but i have to delete from localstorage too, when user click button , here is my code
function RemoveRow(id) {
// event.target will be the input element.
// console.log(id)
let td1 = event.target.parentNode;
let tr1 = td1.parentNode;
tr1.parentNode.removeChild(tr1);// the row to be removed
// const books = JSON.parse(localStorage.getItem("books"));
// const newBooks= books.filter(book=> book.id !== books.id);
// console.log(books, newBooks)
// localStorage.setItem("books", JSON.stringify(newBooks));
}
// function RemoveRow(btn) {
// var row = btn.parentNode.parentNode;
// row.parentNode.removeChild(row);
// }
button tag
class Display {
add(book) {
console.log('Adding to UI');
let tableBody = document.getElementById('tableBody')
let uiString = `<tr class="tableBody" id="tableBody" data-id="${book.id}">
<td id="search">${book.name}</td>
<td>${book.author}</td>
<td>${book.type}</td>
<td><input type="button" value="Delete Row" class="btn btn-outline-danger" onclick="RemoveRow(this)"></td>
</tr>`;
tableBody.innerHTML += uiString;
// save the data to the browser's local storage -----
const books = JSON.parse(localStorage.getItem("books"));
// console.log(books);
if (!books.some((oldBook) => oldBook.id === book.id)) books.push(book);
localStorage.setItem("books", JSON.stringify(books));
}
Hi I would do something like this:
var id = 4; // inital number of rows plus one
function addRow(){
// add a new tr with id
// increment id;
}
function deleteRow(id){
$("#" + id).remove();
}
and i would have a table like this:
<table id = 'dsTable' >
<tr id=1>
<td> Relationship Type </td>
<td> Date of Birth </td>
<td> Gender </td>
</tr>
<tr id=2>
<td> Spouse </td>
<td> 1980-22-03 </td>
<td> female </td>
<td> <input type="button" id ="addDep" value="Add" onclick = "add()" </td>
<td> <input type="button" id ="deleteDep" value="Delete" onclick = "deleteRow(2)" </td>
</tr>
<tr id=3>
<td> Child </td>
<td> 2008-23-06 </td>
<td> female </td>
<td> <input type="button" id ="addDep" value="Add" onclick = "add()"</td>
<td> <input type="button" id ="deleteDep" value="Delete" onclick = "deleteRow(3)" </td>
</tr>
</table>
Also if you want you can make a loop to build up the table. So it will be easy to build the table. The same you can do with edit:)
Ive been searching for idea on how to get value of checkbox group but i need to the x and y for this so far what i have seen is only with one so i havent really found any relevant answer or idea to my problem so i will explain what i want to happend. In my X i have a number of columns namely first quarter,second quester,third quarter and fourth quarter in my Y i have names of students. And i also have an extra checkbox option to add additional student. I want to Check the check corresponding to names and quarter. I will used this to track down student who has taken the exam and who has not yet taken the exam. I am wondering how to group the the checkboxes in a way that when i check on it will automatically get the student name and corresponding quarter.
HTML:
<tr>
<td width="25%">
<hr/>
</td>
<td width="15%">
<center><span>1st Quarter</span>
</center>
</td>
<td width="15%">
<center><span>2nd Quarter</span>
</center>
</td>
<td width="15%">
<center><span>3rd Quarter</span>
</center>
</td>
<td width="20%">
<center><span>4th Quarter</span>
</center>
</td>
</tr>
<tr>
<td><span>Joe Smith</span>
</td>
<td>
<center>
<input type="checkbox" name="studentrecord[]" />
</center>
</td>
<td>
<center>
<input type="checkbox" name="studentrecord[]" />
</center>
</td>
<td>
<center>
<input type="checkbox" name="studentrecord[]" />
</center>
</td>
<td>
<center>
<input type="checkbox" name="studentrecord[]" />
</center>
</td>
</tr>
<tr>
<td><span>John Smith</span>
</td>
<td>
<center>
<input type="checkbox" name="studentrecord[]" />
</center>
</td>
<td>
<center>
<input type="checkbox" name="studentrecord[]" />
</center>
</td>
<td>
<center>
<input type="checkbox" name="studentrecord[]" />
</center>
</td>
<td>
<center>
<input type="checkbox" name="studentrecord[]" />
</center>
</td>
</tr>
Check fiddle
Update
$("input[name='student[]']:checked").map(function() {
var $td = $(this).closest('td'),
index = $td.index();
valueToPush.push({
Quarter: quarter.eq($td.index()).find('span').text().trim(),
Student: $td.parent().find('td:first-child span').text().trim()
});
});
In that case, 1 approach is to create an array of objects where each object represent a checkbox like
$(document).on('click', '#check', function() {
var $quarters = $('table tr:first-child td');
var values = $("input[name='studentrecord[]']:checked").map(function(){
var $td = $(this).closest('td'), index = $td.index();
return {
quarter: $quarters.eq($td.index()).find('span').text().trim(),
student: $td.parent().find('td:first-child span').text().trim()
}
}).get();
console.log(values);
});
Demo: Fiddle
Note: No need to use event delegation if the button is present when script $(document).on('click', '#check', function() { }) is executed.
Another option is to store an array of quarters against each student like
$('#check').on('click', function () {
var $quaters = $('table tr:first-child td'),
students = {};
$("input[name='studentrecord[]']:checked").each(function () {
var $td = $(this).closest('td'),
student = $td.parent().find('td:first-child span').text().trim();
if (!students[student]) {
students[student] = [];
}
students[student].push($quaters.eq($td.index()).find('span').text().trim())
}).get();
console.log(students);
});
Demo: Fiddle
You can initially track each checkbox click and store them in an array. Later, while clicking the button you can retrieve the Student names and the quarters they appeared in directly. Check this Fiddle
var arrObj = {};
$("input[type='checkbox']").click(function(){
if($(this).is(':checked')) {
var studentName = $(this).closest('tr').find('td:first span').html();
var quarterIndex = $(this).closest('td').index();
var quarterName = $(this).closest('table').find('tr:first td:eq('+parseInt(quarterIndex)+')').find('span').html();
if(arrObj[studentName]) {
arrObj[studentName].push(quarterName);
} else {
arrObj[studentName] = [];
arrObj[studentName].push(quarterName);
}
}
});
$(document).on('click', '#check', function() {
for( var key in arrObj) {
alert(key+" appeard in: "+arrObj[key]);
}
});
I have a jquery / javascript function that totals the number of cubes in my order. this works 100% and is below.
function calculateTotalVolume() {
var grandTotalCubes = 0;
$("table.authors-list").find('input[name^="cubicvolume"]').each(function () {
grandTotalCubes += +$(this).val();
});
$("#grandtotalcubes").text(grandTotalCubes.toFixed(2));
}
as mentioned the above works great. I need a second function to total the same field but only if an checkbox named treated is checked. each row has the checkbox named treated but as the table is dynamically generated, a counter is appended to the name each time hence my use of name^="treated"
I am after something like below but this doesn't work:
function calculateTotalTreatedVolume() {
var grandTotaltreatedCubes = 0;
$("table.authors-list").find('input[name^="cubicvolume"]').each(function () {
if($("table.authors-list").find('checkbox[name^="treated"]').checked){
alert('10');
grandTotaltreatedCubes += +$(this).val();
}
});
$("#grandtotaltreatedcubes").text(grandTotaltreatedCubes.toFixed(2));
}
help appreciated as always.
UPDATE
Rendered HTML output [1 dynamic row added]: (Still in development so very rough, please excuse it)
<table class="authors-list" border=1>
<thead>
<tr>
<td></td><td>Product</td><td>Price/Cube</td><td>Qty</td><td>line total cost</td><td>Discount</td><td>Cubes per bundle</td><td>pcs per bundle</td><td>cubic vol</td><td>Bundles</td><td><input type="checkbox" class="checkall"> Treated</td>
</tr>
</thead>
<tbody>
<tr>
<td><a class="deleteRow"> <img src="http://devryan.tekwani.co.za/application/assets/images/delete2.png" /></a></td>
<td><input type="text" id="product" name="product" />
<input type="hidden" id="price" name="price" readonly="readonly"/></td>
<td><input type="text" id="adjustedprice" name="adjustedprice" /></td>
<td><input type="text" id="qty" name="qty" /></td>
<td><input type="text" id="linetotal" name="linetotal" readonly="readonly"/></td>
<td><input type="text" id="discount" name="discount" /></td>
<td>
<input type="text" id="cubesperbundle" name="cubesperbundle" >
</td>
<td>
<input type="text" id="pcsperbundle" name="pcsperbundle" >
</td>
<td>
<input type="text" id="cubicvolume" name="cubicvolume" size='5' disabled>
</td>
<td><input type="text" id="totalbundles" name="totalbundles" size='5' disabled ></td>
<td valign="top" ><input type="checkbox" id="treated" name="treated" ></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="15"><input type="button" id="addrow" value="Add Product" /></td>
</tr>
<tr>
<td colspan="3">Grand Total: R<span id="grandtotal"></span></td>
<td colspan="2">Ave Discount: <span id="avediscount"></span>%</td>
<td colspan="1">Total Cubes: <span id="grandtotalcubes"></span></td>
<td colspan="15">Treated Cubes: <span id="grandtotaltreatedcubes"></span></td>
</tr>
<tr>
<td colspan="15"><textarea rows="1" cols="50" placeholder="Specific Comments"></textarea><textarea rows="1" cols="20" placeholder="Customer Reference"></textarea>
</td>
</tr>
</tfoot>
</table>
First go the parent tr and then using find to find the checkbox in current row and also use checked with DOM object not jQuery object, you can use indexer to convert jQuery object to DOM object.
Change
if($("table.authors-list").find('checkbox[name^="treated"]').checked){
To
if($(this).closest('tr').find('checkbox[name^="treated"]')[0].checked){
checked is a property of the actual DOM element, and what you have is a jQuery element. You need to change this:
$("table.authors-list").find('checkbox[name^="treated"]').checked
To this:
$("table.authors-list").find('checkbox[name^="treated"]')[0].checked
-^- // get DOM element
Or more jQuery-ish:
$("table.authors-list").find('checkbox[name^="treated"]').is(':checked')
You can iterate through the "checked" checkboxes using $("table.authors-list").find('checkbox[name^="treated"]:checked') and use the value of the input nearest to it (assumed to be in the same row).
Assuming your table has many rows each having a checkbox and an input, you can use:
function calculateTotalTreatedVolume() {
var grandTotaltreatedCubes = 0;
// iterate through the "checked" checkboxes
$("table.authors-list").find('input[type="checkbox"][name^="treated"]:checked').each(function () {
// use the value of the input in the same row
grandTotaltreatedCubes += +$(this).closest('tr').find('input[name^="cubicvolume"]').val();
});
$("#grandtotaltreatedcubes").text(grandTotaltreatedCubes.toFixed(2));
}
Try this:
var grandTotaltreatedCubes = 0;
// Cache the table object here for faster processing of your code..
var $table = $("table.authors-list");
$table.find('input[name^="cubicvolume"]').each(function () {
// Check if checkbox is checked or not here using is(':checked')
if ($table.find('checkbox[name^="treated"]').is(':checked')) {
grandTotaltreatedCubes += $(this).val();
}
});
$("#grandtotaltreatedcubes").text(grandTotaltreatedCubes.toFixed(2));
Change the following line
if($("table.authors-list").find('input[name^="treated"]').checked){
To this
if($("table.authors-list").find('input[name^="treated"]').is(':checked')){
I've got a page with a handful of input fields.
I need to find the fields with an array of values, and if so, .remove() the closest('tr')
The markup is similar to this
<table>
<tr>
<td>
<input type="text" value="this">
</td>
</tr>
<tr>
<td>
<input type="text" value="that">
</td>
</tr>
<tr>
<td>
<input type="text" value="them">
</td>
</tr>
</table>
I need to find "this" and "that", and if they are there, remove their <tr> container (and themselves) so I'd end up with:
<table>
<tr>
<td>
<input type="text" value="them">
</td>
</tr>
</table>
I've tried this:
jQuery(document).ready(function($){
var badfields = ['this', 'that'];
var fieldvalue = $('input[type="text"]').val();
if($.inArray(fieldvalue, badfields) > -1){
$(this).closest('tr').remove();
}
});
but it doesn't seem to want to work?
You need to iterate over all the fields using .each, so something like this:
$('input[type="text"]').each(function() {
var fieldvalue = $(this).val();
if ($.inArray(fieldvalue, badfields) > -1) {
$(this).closest('tr').remove();
}
});
Example: jsfiddle
You can be very concise sometimes with jQuery. jQuery has content selectors you can use for this type of purpose:
$("input[type=text][value=this], [value=that]").parents("tr").remove();
since you don't necessarily know this or that beforehand, you can do something like this:
var badfields = ['this', 'that'];
$(badfields).each(function(i) {
$("input[type=text][value=" + this + "]").parents("tr").remove();
});
You can use each to iterate through the selector. this in your inArray scope is not the element you were looking for.
DEMO: http://jsfiddle.net/
html:
<table>
<tr>
<td>
<input type="text" value="this">
</td>
</tr>
<tr>
<td>
<input type="text" value="that">
</td>
</tr>
<tr>
<td>
<input type="text" value="them">
</td>
</tr>
</table>
js:
jQuery(document).ready(function($){
var badfields = ['this', 'that'];
$('input[type="text"]').each(function(){
if( $.inArray(this.value, badfields) > -1 ){
$(this).closest('tr').remove();
}
});
});