This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 2 years ago.
I have a function that changes a table in a list, so far so good, but when the function changes in js it stops working, if I reload the page it works but if I change the DOM nothing. Can you help me?
$(document).ready(function() {
$('#table-list tbody tr').click(function(event) {
if(event.target.type == 'checkbox'){
}else{
$(':checkbox', this).trigger('click');
}
});
$('#ul-list li').click(function(event) {
var checkbox_type = $(event.target).find("input[type='checkbox']").attr('name');
if(checkbox_type){
$(':checkbox', this).trigger('click');
}
});
});
These are the two events that should always be active. But if I change the table to ul not it works
So let me explain better, I have a table like this:
<table id="table-list">
<tbody>
<tr>
<td><input type="checkbox" name="1" /></td>
</tr>
<tr>
<td><input type="checkbox" name="3" /></td>
</tr>
</tbody>
</table>
Then by clicking on a button I convert it to a list by removing the table from the DOM and inserting this:
<ul id="ul-list">
<li>
<input type="checkbox" name="1" />
</li>
<li>
<input type="checkbox" name="3" />
</li>
</ul>
Now I want if I try to click on the list this function should start:
$('#ul-list li').click(function(event) {
var checkbox_type = $(event.target).find("input[type='checkbox']").attr('name');
if(checkbox_type){
$(':checkbox', this).trigger('click');
}
});
instead no.
If you rewrite the DOM, you need to DELEGATE
$('#ul-list').on("click","li",function(event) {
I though you might need this - see the stopPropagation when the target is one of the checkboxes itself:
function findCheck(e) {
const tgt = e.target;
if (tgt.type && tgt.type === "checkbox") {
e.stopPropagation()
} else {
const $row = $(e.currentTarget);
$row.find("[type=checkbox]").each(function() {
$(this).click();
//$(this).attr("checked", !$(this).attr("checked"))
});
}
}
$(function() {
let $ul = $("<ul/>", {
id: "ul-list"
});
const $tbl = $("#table-list");
$tbl.find("tr").each(function() {
let $li = $("<li/>")
$("td",this).each(function() {
$li.append($(this).html())
})
$ul.append($li);
})
$tbl.replaceWith($ul)
$('#ul-list').on("click", "li", findCheck)
})
tr {
background-color: red
}
li {
background-color: red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table-list">
<tbody>
<tr>
<td>1</td>
<td><input type="checkbox" name="1" /></td>
<td><input type="checkbox" name="2" /></td>
</tr>
<tr>
<td>2</td>
<td><input type="checkbox" name="3" /></td>
</tr>
</tbody>
</table>
Related
I have created a JQuery routine to check all the checkboxes on a page using a master checkbox.
I am generally happy with this function and it is serving me well but it is not very generic and I have now copy/pasted it into a number of pages in my solution.
I also have a couple of pages where I have copy/pasted it twice because I have two groups of checkboxes on one page that need to be controlled independently. This is not good!
I would really love to genericise this and stuff it away in my main .js script file but I do not know where to start! I would love to be able to use a system of classes to tell JQuery which set of checkboxes is controlled by which master checkbox.
Can you help please? I feel that a solution would boost my jquery ability massively!
(n.b. please excuse the classes in tags, that is down to the nasty way that asp.net renders checkboxes)
$(function () {
$(".checkAllLeft").click(function () {
if ($(".checkAllLeft").is(':checked')) {
$(".LeftCheckbox").each(function () {
var checkbox = $(this).find("input")
if (checkbox.prop("disabled") == false) { checkbox.prop("checked", true); }
});
} else {
$(".LeftCheckbox").each(function () {
var checkbox = $(this).find("input")
if (checkbox.prop("disabled") == false) { checkbox.prop("checked", false); }
});
}
});
});
$(function () {
$(".checkAllRight").click(function () {
if ($(".checkAllRight").is(':checked')) {
$(".RightCheckbox").each(function () {
var checkbox = $(this).find("input")
if (checkbox.prop("disabled") == false) { checkbox.prop("checked", true); }
});
} else {
$(".RightCheckbox").each(function () {
var checkbox = $(this).find("input")
if (checkbox.prop("disabled") == false) { checkbox.prop("checked", false); }
});
}
});
});
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<table border=1>
<tr>
<td>Check All Left<br /><input type="checkbox" class="checkAllLeft"></td>
<td>Check All Right<br /><input type="checkbox" class="checkAllRight"></td>
</tr>
<tr>
<td><span class="LeftCheckbox"><input type="checkbox" ></span></td>
<td><span class="RightCheckbox"><input type="checkbox" ></span></td>
</tr>
<tr>
<td><span class="LeftCheckbox"><input type="checkbox" ></span></td>
<td><span class="RightCheckbox"><input type="checkbox" ></span></td>
</tr>
<tr>
<td><span class="LeftCheckbox"><input type="checkbox" ></span></td>
<td><span class="RightCheckbox"><input type="checkbox" ></span></td>
</tr>
</table>
</body>
To achieve this you can use DOM traversal to find all the checkboxes within the same container (ie. the same column) as the 'check all' option, then set them to the same value. Something like this:
$(".check-all").change(function() {
var tdIndex = $(this).closest('td').index() + 1;
$('table tr td:nth-child(' + tdIndex + ') :checkbox').prop('checked', this.checked);
});
table,
th,
td {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<table>
<tr>
<td>Check All Left<br /><input type="checkbox" class="check-all" /></td>
<td>Check All Right<br /><input type="checkbox" class="check-all" /></td>
</tr>
<tr>
<td><span><input type="checkbox" /></span></td>
<td><span><input type="checkbox" /></span></td>
</tr>
<tr>
<td><span><input type="checkbox" /></span></td>
<td><span><input type="checkbox" /></span></td>
</tr>
<tr>
<td><span><input type="checkbox" /></span></td>
<td><span><input type="checkbox" /></span></td>
</tr>
</table>
There's a couple of other things to note. Firstly, you don't need to use a document.ready event per function call; you can place all logic within a single one. Secondly the border attribute on table elements is very outdated. Use CSS instead.
I have a simple table as following which has checkboxes in the first and last columns of each row.
<table style="width:100%">
<tr>
<td><input type="checkbox" /></td>
<td>Smith</td>
<td><input type="checkbox" /></td>
</tr>
<tr>
<td><input type="checkbox" /></td>
<td>Jackson</td>
<td><input type="checkbox" /></td>
</tr>
</table>
Problem:
When I check/uncheck the last column's checkbox in the first row, the first column's checkbox in the same row should be checked/unchecked. Similarly, if I check/uncheck the first column's checkbox, the corresponding last column checkbox should be checked/unchecked.
How can I achieve this in javascript? Any help or pointers would be really appreciated.
Here is the fiddle which I have created: Fiddle
Thank you.
Use :checkbox selector to select input type checkbox elements.
Try this:
$(':checkbox').on('change', function() {
$(this).closest('tr').find(':checkbox').prop('checked', this.checked);
});
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<table style="width:100%">
<tr>
<td>
<input type="checkbox" />
</td>
<td>Smith</td>
<td>
<input type="checkbox" />
</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Jackson</td>
<td>
<input type="checkbox" />
</td>
</tr>
</table>
Using JavaScript:
Use querySelectorAll('[type="checkbox"]') to find checkbox elements.
Try this:
var checkboxes = document.querySelectorAll('[type="checkbox"]');
[].forEach.call(checkboxes, function(checkbox) {
checkbox.onchange = function() {
var currentRow = this.parentNode.parentNode;
var cbElems = currentRow.querySelectorAll('[type="checkbox"]');
[].forEach.call(cbElems, function(cb) {
cb.checked = this.checked;
}.bind(this))
};
});
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
<table style="width:100%">
<tr>
<td>
<input type="checkbox" />
</td>
<td>Smith</td>
<td>
<input type="checkbox" />
</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Jackson</td>
<td>
<input type="checkbox" />
</td>
</tr>
</table>
One possible Javascript solution to toggle Checkboxes on Table Row click is shown below:
HTML
<table id = "Table1">
<tr>
<td><input type="checkbox" /></td>
<td>John Smith</td>
<td><input type="checkbox" /></td>
</tr>
<tr>
<td><input type="checkbox" /></td>
<td>Anna Warner</td>
<td><input type="checkbox" /></td>
</tr>
</table>
CSS
table, th, td{
border: 1px solid #c0c0c0;
border-collapse: collapse;
}
table{width:100%;}
Javascript
// row click will toggle checkboxes
row_OnClick("Table1")
function row_OnClick(tblId) {
try {
var rows = document.getElementById(tblId).rows;
for (i = 0; i < rows.length; i++) {
var _row = rows[i];
_row.onclick = null;
_row.onclick = function () {
return function () {selectRow(this);};
}(_row);
}
}
catch (err) { }
}
function selectRow(row) {
row.cells[0].firstChild.checked = !row.cells[0].firstChild.checked;
row.cells[2].firstChild.checked = row.cells[0].firstChild.checked;
}
Working jsfiddle demo at: https://jsfiddle.net/t6nsxgnz/
Practical implementation at: http://busny.net
You can further customize this solution pertinent to your task by modifying the selectRow(row) function:
function selectRow(row) {
row.cells[0].firstChild.checked = // add your code for the 1st CheckBox
row.cells[2].firstChild.checked = // add your code for the 2nd CheckBox
}
Another variation of this functionality coded in jQuery can be found in online pop-quiz engine (http://webinfocentral.com), implemented via the follwoing code snippet:
// toggle Checkboxes on row click
$(Table1 tr').click(function (event) {
// find the checkbox in the row
var _chk = $(this).find('input:checkbox');
if (!($(event.target).is("checkbox"))) {
$(_chk).prop('checked', !$(_chk).prop('checked'));
}
});
In this case, Row Click (at any place of the Row) or CheckBox Click events will toggle the state of that particular CheckBox. The state of other CheckBoxes can be synchronized with this one (by using "siblings" property, for example).
Hope this may help.
I have a table with some row colored as green.Each row have a checkbox.
When I click submit button i need to validate that only green colored row whose checkboxes are not checked should be checked.
No other colored rows and just the green one(#47A347).
Below is my html.Can anyone help me getting the solution.
<form method="post" action="test2.html">
<table>
<tr bgcolor="#47A347" class="rowb">
<td>Hello</td>
<td><input type="checkbox" id="chk" class="linebox"></td>
</tr>
<tr bgcolor="#47A347" class="rowb">
<td>Hello 1</td>
<td><input type="checkbox" id="chk1" class="linebox"></td>
</tr>
<tr class="rowb">
<td>Hello 2</td>
<td><input type="checkbox" id="chk1" class=""></td>
</tr>
<tr>
<td><input type="submit" id="btn" value="Submit"></td>
</tr>
</table>
</form>
I have tried below jquery code.Though it works it fails sometimes.
<script>
jQuery(document).on('click', '#btn', function (event)
{
var rv = true;
$(".rowb").each(function()
{
if($(this).css("background-color") == "rgb(71, 163, 71)")
{
var ischk = 0;
var row = $(this);
if (row.find('input[class="linebox"]').is(':checked') )
{
ischk++;
}
if(ischk==0)
{
rv=false;
}
}
});
if (!rv)
{
alert('Please check');
event.preventDefault();
}
});
</script>
Try this snippet. Should give you an alert for each green checkbox that has not been checked on click of the submit 'btn'. If there is a green row checkbox that has not been checked, the default submit action will be stopped.
$(document).ready(function(){
$('#btn').on('click', function(){
var i = 1;
var error = false;
$(".rowb").each(function() {
ischk = 0;
if($(this).attr("bgcolor") == "#47A347") {
if (!$(this).find('input.linebox').is(':checked') )
{
alert('Please check green checkbox #' + i);
error = true;
}
i++;
}
});
if (error){
event.preventDefault();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form method="post" action="test2.html">
<table>
<tr bgcolor="#47A347" class="rowb">
<td>Hello</td>
<td><input type="checkbox" id="chk" class="linebox"></td>
</tr>
<tr bgcolor="#47A347" class="rowb">
<td>Hello 1</td>
<td><input type="checkbox" id="chk1" class="linebox"></td>
</tr>
<tr class="rowb">
<td>Hello 2</td>
<td><input type="checkbox" id="chk1" class=""></td>
</tr>
<tr>
<td><input type="submit" id="btn" value="Submit"></td>
</tr>
</table>
</form>
Instead of asserting in background-color try checking for bgcolor attribute.
//if($(this).css("background-color") == "rgb(71, 163, 71)")
if( $(this).attr("bgcolor") == "#47A347" )
Here's the full refactored code:
jQuery(document).on('click', '#btn', function (event)
{
var rv = true;
$(".rowb").each(function()
{
if($(this).attr("bgcolor") == "#47A347")
{
if ( !$(this).find('.linebox').is(':checked') )
{
rv = false;
return false
}
}
});
if (!rv)
{
alert('Please check');
event.preventDefault();
}
});
$('#btn').on('click', function(){
var data = {};
var form = $(this).closest('form');
$('[bgcolor="#47A347"]', form).each(function(){
data[this.id] = $(this).find('input').val();
})
});
Note: you didn't provide name attribute for inputs. With name attribute provided you can use jQuery's serialize method to gather form data automatically. To filter out unneeded fields you can temporarily set them to disabled state.
I have table has 2 columns: checkbox and name.
<table id="data">
<tr class="header">
<th>
<input type="checkbox" class="download" />
</th>
<th>Name</th>
</tr>
<tr data-id="1">
<td>
<input type="checkbox" class="download" />
</td>
<td>One</td>
</tr>
<tr data-id="2">
<td>
<input type="checkbox" class="download" />
</td>
<td>Two</td>
</tr>
<tr data-id="3">
<td>
<input type="checkbox" class="download" />
</td>
<td>Something</td>
</tr>
</table>
I would like to select data attribute from those rows that have checkbox selected. Right now I'm doing it this way:
$(document).on('click', "#select", function (e) {
var mydata=[];
$.each($('#data tbody tr:not(.header)'), function(i, row) {
if($(row).find('input[type=checkbox]').is(":checked"))
mydata.push($(row).data('id'));
});
console.log(mydata);
});
This works fine, but can this be done better/faster?
Here is my working demo: http://jsfiddle.net/Misiu/yytR2/2/
Also how can I uncheck checkbox in header when one of more checkboxes in body are unchecked and check it when all will get checked?
EDIT: My final working code (thanks to #tymeJV):
$(document).on('change', "#data tr.header input.download", function (e) {
$('#data tbody tr:not(.header) input.download').prop('checked', $(this).is(":checked"));
});
$(document).on('change', "#data tr:not(.header) input.download", function (e) {
if ($(this).is(":checked") && $('#data tr:not(.header) input.download:not(:checked)').length == 0) {
$('#data tbody tr.header input.download').prop('checked', true);
} else {
$('#data tbody tr.header input.download').prop('checked', false);
}
});
$(document).on('click', "#select", function (e) {
var rows = $("#data tr:not(.header) td input:checked").map(function () {
return $(this).closest("tr").data("id");
}).get();
console.log(rows);
});
You can do:
var rows = $("#data tr:not(.header) td input:checked").map(function() {
return $(this).closest("tr").data("id");
}).get();
It iterates yet, but only checked rows.
You can use:
$(".download:checkbox").map(function() {
return $(this).parents('tr').data('id');
}).get()
I am trying to create a simple todo list in Javascript but for some reason when the check box is ticked, the styling text adjacent to it does not change rather the heading text style changes as per the fiddle
HTML:
<table border="1">
<tr>
<td>
<input type="checkbox" value="None" id="squaredTwo" name="check" />
</td>
<td>row 1, cell 2</td>
</tr>
<tr>
<td>
<input type="checkbox" value="None" id="squaredTwo" name="check" />
</td>
<td>row 2, cell 2</td>
</tr>
</table>
<h2> Heading 2</h2>
CSS:
.newclass {
text-decoration: line-through;
color: red;
}
JQuery:
$('input[type="checkbox"]').click(function () {
if ( this.checked ) {
//alert('Checked');
$("h2").addClass('newclass');
} else {
//alert('Unchecked');
$("h2").removeClass('newclass');
}
});
Please help
Change your Jquery like this
$('input[type="checkbox"]').click(function () {
if (this.checked) {
//alert('Checked');
$(this).closest("td").next().addClass('newclass');
} else {
//alert('Unchecked');
$(this).closest("td").next().removeClass('newclass');
}
});
Demo Fiddle
Even Simpler than that
$('input[type="checkbox"]').click(function () {
$(this).closest("td").next().toggleClass('newclass');
});
New Demo Fiddle
It is happening as you are targeting H2 element for styles on click of checkbox. Instead use the next TD element.
$('input[type="checkbox"]').click(function() {
if (this.checked) {
//alert('Checked');
$(this).parent().next().addClass('newclass');
} else {
//alert('Unchecked');
$(this).parent().next().removeClass('newclass');
}
});