Keeping the previous highlighting with jquery - javascript

I created a simple table to show the problem I'm having. When a value is highlighted with a checkbox, and if the value exists in the second checkbox it is still highlighted. That's ok. but when I unclick the first or second checkbox, the highlight is gone although it's still in the first checkbox and still clicked.
Is there a way to keep the highlight on when the second checkbox is unselected?
I hope I made it clear. here is my jsfiddle if you prefer: https://jsfiddle.net/6k5caw8h/19/
Thank you.
Html:
$(document).ready(function() {
$('.selector').each(function() {
$(this).on('click', function(e) {
check($(this).prop("checked") ? $("#nextColor").val() : '#fff', $(this).attr("name"));
});
});
$('.all').each(function() {
$(this).on('click', all);
});
function all(event) {
if ($(this).is(':checked')) {
let checked = $("input:checkbox:not(:checked)", $(this).parents('form')).not(this);
checked.prop("checked", true);
check($("#nextColor").val(), ...checked.map((i, e) => e.name).get());
} else {
let checked = $("input:checkbox(:checked)", $(this).parents('form')).not(this);
checked.prop("checked", false);
check('#fff', ...checked.map((i, e) => e.name).get());
}
}
function check(color, ...elements) {
$('td').each((i, td) => {
if (elements.includes($(td).text())) $(td).css('background', color);
});
}
});
table.tb {
border: 1px solid #CCC;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
border-collapse: collapse;
table-layout: fixed;
margin-left: 200px;
}
.tb td {
padding: 5px;
margin: 5px;
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<input id="nextColor" type="color" value="#9ac99d">
<form id="form1" name="form1" method="post" action="">
<label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
<label><input type="checkbox" name="x" class="selector" />x</label>
<label><input type="checkbox" name="y" class="selector" />y</label>
</form>
<form id="form1" name="form1" method="post" action="">
<label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
<label><input type="checkbox" name="x" class="selector" />x</label>
<label><input type="checkbox" name="z" class="selector" />z</label>
</form>
<table class="tb">
<tbody>
<tr>
<td>x</td>
<td>y</td>
</tr>
<tr>
<td>z</td>
<td>x</td>
</tr>
<tr>
<td>q</td>
<td>a</td>
</tr>
</tbody>
</table>

Your problem, where unchecking checkboxes that target the same alphabet seems to ignore the state of the others, comes from this problematic line:
check($(this).prop("checked") ? $("#nextColor").val() : '#fff', $(this).attr("name"));
In this line, you are simply checking if the specific checkbox that is being clicked is checked, while you should actually check through all your checkboxes with the same name attribute and see if any of them are checked.
So what you can do is to simply loop through all .selectors and filter them by (1) the value of their name attribute which matches the current checkbox, and (2) if they are checked. If any of them are checked, the first argument passed into check() should be true:
const $sameNameSelector = $('.selector[name="'+$(this).attr('name')+'"]');
const isAnySameNameSelectorChecked = $sameNameSelector.filter(function() { return this.checked }).length;
check(isAnySameNameSelectorChecked ? $("#nextColor").val() : '#fff', $(this).attr("name"));
Update: this does not seem to fix your issue because all() is also calling some convoluted logic. All you need is to:
Check the click event listener on .selector to .change
Simply use the .all checkbox to trigger changes to the .selector checkboxes and manually fire the change event. This causes then individual logic on all the single checkboxes to fire, without needing to duplicate any logic:
function all(event) {
$(this).closest('form').find('.selector').prop('checked', this.checked).trigger('change');
}
Pro-tip: you don't need to do $('.selector').each({ $(this).on('...'); }) and then bind the event handler. jQuery can handle that intelligently, so you can just do `$('.selector').on(...);'.
$(document).ready(function() {
$('.selector').on('change', function(e) {
const $sameNameSelector = $('.selector[name="' + $(this).attr('name') + '"]');
const isAnySameNameSelectorChecked = $sameNameSelector.filter(function() {
return this.checked
}).length;
check(isAnySameNameSelectorChecked ? $("#nextColor").val() : '#fff', $(this).attr("name"));
});
$('.all').each(function() {
$(this).on('click', all);
});
function all(event) {
$(this).closest('form').find('.selector').prop('checked', this.checked).trigger('change');
}
function check(color, ...elements) {
$('td').each((i, td) => {
if (elements.includes($(td).text())) $(td).css('background', color);
});
}
});
table.tb {
border: 1px solid #CCC;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
border-collapse: collapse;
table-layout: fixed;
margin-left: 200px;
}
.tb td {
padding: 5px;
margin: 5px;
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="nextColor" type="color" value="#9ac99d">
<form id="form1" name="form1" method="post" action="">
<label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
<label><input type="checkbox" name="x" class="selector" />x</label>
<label><input type="checkbox" name="y" class="selector" />y</label>
</form>
<form id="form1" name="form1" method="post" action="">
<label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
<label><input type="checkbox" name="x" class="selector" />x</label>
<label><input type="checkbox" name="z" class="selector" />z</label>
</form>
<table class="tb">
<tbody>
<tr>
<td>x</td>
<td>y</td>
</tr>
<tr>
<td>z</td>
<td>x</td>
</tr>
<tr>
<td>q</td>
<td>a</td>
</tr>
</tbody>
</table>

To keep the previous highlighting you need to keep a history of the checks someplace and the color that was selected when it was checked. A simple way to do this would be to assign the color data and the timestamp directly to the checkbox. The following javascript solves the actual problem of maintaining a history so that when checks are removed the color from previous checks are restored.
I refactored the code to do a rendering loop renderChecks() which is a more maintainable design pattern.
See: https://jsfiddle.net/c6pt0eb5/1/
$(document).ready(function() {
$('.selector').each(function() {
$(this).on('click', function(e) {
if ($(this).is(':checked')) {
$(this).data("color",[$("#nextColor").val(),Date.now()]);
}
renderChecks();
});
});
$('.all').each(function() {
$(this).on('click', all);
});
function all(event) {
if ($(this).is(':checked')) {
let checked = $("input:checkbox", $(this).parents('form')).not(this);
checked.prop("checked", true);
checked.data("color",[$("#nextColor").val(),Date.now()]);
} else {
let checked = $("input:checkbox(:checked)", $(this).parents('form')).not(this);
checked.prop("checked", false);
}
renderChecks();
}
function renderChecks() {
const checks = {};
const names = [];
$(".selector:checked").each((i,val) => {
if (checks[$(val).attr('name')]) {
checks[$(val).attr('name')].push($(val).data('color'));
checks[$(val).attr('name')].sort((a,b) => a - b);
} else {
checks[$(val).attr('name')] = [$(val).data('color')];
names.push($(val).attr('name'));
}});
$('td').each((i, td) => {
$(td).css('background','#fff');
const text = $(td).text();
let t = null;
names.forEach((name) => {
if (text.includes(name)) {
if (t == null || t < checks[name][0][1]) {
t = checks[name][0][1];
$(td).css('background', checks[name][0][0]);
}
}
});
});
}
});
table.tb {
border: 1px solid #CCC;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
border-collapse: collapse;
table-layout: fixed;
margin-left: 200px;
}
.tb td {
padding: 5px;
margin: 5px;
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<input id="nextColor" type="color" value="#9ac99d">
<form id="form1" name="form1" method="post" action="">
<label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
<label><input type="checkbox" name="x" class="selector" />x</label>
<label><input type="checkbox" name="y" class="selector" />y</label>
</form>
<form id="form1" name="form1" method="post" action="">
<label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
<label><input type="checkbox" name="x" class="selector" />x</label>
<label><input type="checkbox" name="z" class="selector" />z</label>
</form>
<table class="tb">
<tbody>
<tr>
<td>x</td>
<td>y</td>
</tr>
<tr>
<td>z</td>
<td>x</td>
</tr>
<tr>
<td>q</td>
<td>a</td>
</tr>
</tbody>
</table>
Note: The accepted answer doesn't keep the previous highlighting, it simply keeps the current highlighting.

I note that the "SelectAll" does not become checked when all the children are checked - I make the assumption that you DO wish to make it "checked" when all the children are checked (a common requirement) so that to uncheck all the children you do not have to check and uncheck the SelectAll.
The other thing is do you wish to keep the related checks checked i.e. when you check "x" do you wish the OTHER "x" to become checked? IF you do, uncomment this line in the code I present here and the like named will check and uncheck in sync:
// allChecksNotMe.prop("checked", isChecked);
OK, now that we are past the checkbox management, lets look at keeping the highlight. Now that requirement is slightly unclear - you turn them white #fff when you uncheck. Do you wish that or only when ALL are unchecked? Or never turn white; i.e. once with a color they keep it even if unchecked? My second example has ways to keep the color highlighted when unchecked and to reset to the current color choice as well.
$(function() {
let cbx = "[type='checkbox']";
let cbxSel = ".selector" + cbx;
$(cbxSel) //.add('.all[type="checkbox"]')
.on('change', function(e) {
let me = $(this);
let myname = $(this).attr("name");
let namesel = "[name='" + myname + "']";
let allpeer = $(".all" + cbx);
let allChecksNotMe = $(cbxSel + namesel).not(me);
let isChecked = this.checked;
// uncomment to keep like checks in sync
// allChecksNotMe.prop("checked", isChecked);
allpeer.trigger('checkcolor');
let color = $("#nextColor").val();
let newColor = isChecked ? color : '#fff';
check(newColor, myname);
});
$('form').on('checkcolor', '.all', function(event) {
let myForm = $(event.delegateTarget);
// checks on form
let formChecks = myForm.find(cbxSel);
let formChecksChecked = formChecks.filter(':checked');
let areAllChecked = (formChecks.length == formChecksChecked.length);
$(this).prop("checked", areAllChecked);
})
$('.all' + cbx).on('change', function() {
let isChecked = this.checked;
let myForm = $(this).closest('form');
// checks on form
myForm.find(cbxSel)
.prop('checked', isChecked).trigger("change");
});
function check(color, ...elements) {
let newColor = {
'background-color': color
};
$('.tb tbody').find('td').filter(function(index) {
return elements.includes($(this).text());
}).css(newColor);
}
});
table.tb {
border: 1px solid #CCC;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
border-collapse: collapse;
table-layout: fixed;
margin-left: 200px;
}
.tb td {
padding: 5px;
margin: 5px;
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<input id="nextColor" type="color" value="#9ac99d">
<form id="form1" name="form1" method="post" action="">
<label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
<label><input type="checkbox" name="x" class="selector" />x</label>
<label><input type="checkbox" name="y" class="selector" />y</label>
</form>
<form id="form2" name="form2" method="post" action="">
<label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
<label><input type="checkbox" name="x" class="selector" />x</label>
<label><input type="checkbox" name="z" class="selector" />z</label>
</form>
<table class="tb">
<tbody>
<tr>
<td>x</td>
<td>y</td>
</tr>
<tr>
<td>z</td>
<td>x</td>
</tr>
<tr>
<td>q</td>
<td>a</td>
</tr>
</tbody>
</table>
Alternate with highlight differences:
$(function() {
let cbx = "[type='checkbox']";
let cbxSel = ".selector" + cbx;
$(cbxSel) //.add('.all[type="checkbox"]')
.on('change', function(e) {
let me = $(this);
let myname = $(this).attr("name");
let namesel = "[name='" + myname + "']";
let allpeer = $(".all" + cbx);
let namedPeers = $(cbxSel + namesel);
let allChecksNotMe = namedPeers.not(me);
let isChecked = this.checked;
// uncomment to keep like checks in sync
// allChecksNotMe.prop("checked", isChecked);
allpeer.trigger('allchecked');
let anyNamedChecked = !!namedPeers.filter(":checked").length;
let keep = $('#keepcolor')[0].checked;
let reset = $('#resetcolor')[0].checked;
check(anyNamedChecked, myname, keep, reset);
});
$('form').on('allchecked', '.all', function(event) {
let myForm = $(event.delegateTarget);
// checks on form
let formChecks = myForm.find(cbxSel);
let formChecksChecked = formChecks.filter(':checked');
let areAllChecked = (formChecks.length == formChecksChecked.length);
$(this).prop("checked", areAllChecked);
})
$('.all' + cbx).on('change', function() {
let isChecked = this.checked;
let myForm = $(this).closest('form');
// checks on form
myForm.find(cbxSel)
.prop('checked', isChecked).trigger("change");
});
function check(anyNamedChecked, myname, keepColor = false, reset = true) {
let color = $("#nextColor").val();
let newColor = anyNamedChecked ? color : '#fff';
let colorCSS = {
'background-color': newColor
};
$('.tb tbody').find('td').filter(function(index) {
return myname.includes($(this).text());
}).each(function(index, element) {
let me = $(element);
if (keepColor) {
let scolor = reset ? color : me.data("savecolor");
if (!!scolor) {
colorCSS = {
'background-color': scolor
};
}
me.data("savecolor", !!scolor ? scolor : color);
}
$(element).css(colorCSS);
});
}
});
table.tb {
border: 1px solid #CCC;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
border-collapse: collapse;
table-layout: fixed;
margin-left: 200px;
}
.tb td {
padding: 5px;
margin: 5px;
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<input id="nextColor" type="color" value="#9ac99d">
<label><input id="keepcolor" type="checkbox" name="keepcolor" />Keep Color</label>
<label><input id="resetcolor" type="checkbox" name="resetcolor" />Reset Color</label>
<form id="form1" name="form1" method="post" action="">
<label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
<label><input type="checkbox" name="x" class="selector" />x</label>
<label><input type="checkbox" name="y" class="selector" />y</label>
</form>
<form id="form2" name="form2" method="post" action="">
<label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
<label><input type="checkbox" name="x" class="selector" />x</label>
<label><input type="checkbox" name="z" class="selector" />z</label>
</form>
<table class="tb">
<tbody>
<tr>
<td>x</td>
<td>y</td>
</tr>
<tr>
<td>z</td>
<td>x</td>
</tr>
<tr>
<td>q</td>
<td>a</td>
</tr>
</tbody>
</table>

Related

When TR is clicked, then check the checkbox

When I click it for the first time, it click, but doesn't turn off...
I've tried this one, it checked and uncheck but only once.
This one doesn't work for me either.
$(document).ready(function() {
$("tr").click(function() {
var checkbox = $(this).find("input[type=checkbox]");
if (!checkbox.prop("checked", "")) {
checkbox.prop("checked", "false");
} else {
checkbox.prop("checked", "true");
}
});
});
td{
background:red;
padding:10px 40px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>
<input type="checkbox" />
</td>
<td>test</td>
</tr>
</table>
Here is a toggle
$(document).ready(function() {
$("tr").on("click", function(e) {
const $target = $(e.target)
const $checkbox = $(this).find("input[type=checkbox]");
// only run code when NOT clicking checkbox
if (!$checkbox.is($target)) {
let checked = $checkbox.is(":checked")
$checkbox.prop("checked", !checked)
}
});
});
td {
background: red;
padding: 10px 40px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>
<input type="checkbox" />
</td>
<td>test</td>
</tr>
</table>

JQuery validations not working empty data is inserted into table rows

I've a text field in table with id name .
I have added a validation on it.
But its not working
<td>Name:</td>
<td>
<input type="text" id="name" class="required"/>(required)
</td>
$("#name").focusout(function(){
if (!$(this).val()) {
alert("This field is required");
$(this).focus();
}
});
I have complete code on jsfiddle .
Please check link
Just make sure to put it inside document ready and it'll work just fine:
$(function () {
$("#name").focusout(function () {
if (!$(this).val()) {
alert("This field is required");
$(this).focus();
}
});
});
jsfiddle DEMO
Edit: full page requested by OP:
<!DOCTYPE html>
<html>
<head>
<title>Dynamic Book Library</title>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
text-align: left;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script>
var count = 1;
var rating;
function addRow() {
var myName = document.getElementById("name");
var auther = document.getElementById("auther");
var publish = document.getElementById("publish");
var ratings = document.getElementsByName("rating");
for (var i = 0; i < ratings.length; i++) {
if (ratings[i].checked) {
rating = ratings[i];
}
}
var table = document.getElementById("myTableData");
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
row.insertCell(0).innerHTML = count;
row.insertCell(1).innerHTML = myName.value;
row.insertCell(2).innerHTML = auther.value;
row.insertCell(3).innerHTML = publish.value;
row.insertCell(4).innerHTML = rating.value;
count = count + 1;
}
function load() {
console.log("Page load finished");
}
$(function() {
$("#name").focusout(function () {
console.log('bla');
if (!$(this).val()) {
alert("This field is required");
$(this).focus();
}
});
});
</script>
</head><body onload="load()">
<div id="mydata">
<b>Current data in the system ...</b>
<table id="myTableData" border="1" style="width:100%">
<tr id="templateRow">
<th>ID</th>
<th>Name</th>
<th>Authers</th>
<th>Published</th>
<th>Ratings</th>
</tr>
</table>
<br/>
</div>
<div id="myform">
<b>Simple form with name and age ...</b>
<table style="width:100%">
<tr>
<td>Name:</td>
<td>
<input type="text" id="name">
</td>
</tr>
<tr>
<td>Auther:</td>
<td>
<input type="text" id="auther">
</td>
</tr>
<tr>
<td>Published:</td>
<td>
<input type="date" id="publish">
</td>
</tr>
<tr>
<td>Rating:</td>
<td>
<input type="radio" value="1" id="rating" name="rating">1
<input type="radio" value="2" id="rating2" name="rating">2
<input type="radio" value="3" id="rating3" name="rating">3
<input type="radio" value="4" id="rating4" name="rating">4
<input type="radio" value="5" id="rating5" name="rating">5</td>
</tr>
</table>
<br>
<input type="button" id="add" value="Add" onclick="Javascript:addRow()">
</div>
</body>
</html>

Multiple checkboxes with same id and one needs to be selected - jquery

There are multiple checkboxes with same id, in asp.net repeater control. User can select either email or phone against each record in repeater rows.
In following example; there are two rows, if you select the email icon in first row then it ticks relavent checkbox which is fine but if you tick the email icon on the next row then it will untick the first row checkbox instead of ticking the one next to it.
$(function() {
$("[id*=divchkemail]").click(function() {
$(this).toggleClass("image-email");
if ($('#chkemail').prop('checked')) {
$("#chkemail").prop('checked', false);
} else {
if ($('#chkphone').prop('checked')) {
$("#chkphone").prop('checked', false);
$("#divchkphone").toggleClass("image-phone");
}
$("#chkemail").prop('checked', true);
}
});
$("[id*=divchkphone]").click(function() {
$(this).toggleClass("image-phone");
if ($('#chkphone').prop('checked')) {
$("#chkphone").prop('checked', false);
} else {
if ($('#chkemail').prop('checked')) {
$("#chkemail").prop('checked', false);
$("#divchkemail").toggleClass("image-email");
}
$("#chkphone").prop('checked', true);
}
});
});
.image-phone-disabled {
background-image: url('http://i.imgur.com/74FcgdS.png');
background-repeat: no-repeat;
width: 34px;
height: 34px;
}
.image-phone {
background-image: url(http://i.imgur.com/LwsHkOt.png);
background-repeat: no-repeat;
width: 34px;
height: 34px;
}
.image-email-disabled {
background-image: url('http://i.imgur.com/khd2NG8.png');
background-repeat: no-repeat;
width: 34px;
height: 34px;
}
.image-email {
background-image: url(http://i.imgur.com/y5KE9jx.png);
background-repeat: no-repeat;
width: 34px;
height: 34px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<table border=0>
<tr>
<td>
<div id="divchkemail" class="image-email-disabled" />
</td>
<td>
<input id="chkemail" type="checkbox" name="ctl00$ContentPlaceHolder1$tabContainer$tabRequests$Requests$cndt1$FindInspector$rptSearch$ctl01$chkemail"></input>
</td>
</tr>
<tr>
<td>
<div id="divchkphone" class="image-phone-disabled" />
</td>
<td>
<input id="chkphone" type="checkbox" name="ctl00$ContentPlaceHolder1$tabContainer$tabRequests$Requests$cndt1$FindInspector$rptSearch$ctl01$chkphone"></input>
</td>
</tr>
</table>
<br/>
<br/>
<br/>
<span>
</span>
<table border=0>
<tr>
<td>
<div id="divchkemail" class="image-email-disabled" />
</td>
<td>
<input id="chkemail" type="checkbox" name="ctl00$ContentPlaceHolder1$tabContainer$tabRequests$Requests$cndt1$FindInspector$rptSearch$ctl02$chkemail"></input>
</td>
</tr>
<tr>
<td>
<div id="divchkphone" class="image-phone-disabled" />
</td>
<td>
<input id="chkphone" type="checkbox" name="ctl00$ContentPlaceHolder1$tabContainer$tabRequests$Requests$cndt1$FindInspector$rptSearch$ctl02$chkphone"></input>
</td>
</tr>
</table>
<span>
</span>
JSFiddle
http://jsfiddle.net/g8Xuz/48/
although you must use unique id's for elements, given your scenario I've written down this fiddle.
i've used this $(this).parent().next('td').find('input:checkbox'); to find the checkboxes
please try this http://jsfiddle.net/g8Xuz/50/
This works.
I gave the rows a class of contact. It can also work without the class on the rows by using $("table > tr") instead. No need to know the exact class names and can handle any number of sets allowing the correct unique IDs for the fields.
FIDDLE
$(function () {
$(".contact").on("click", function (e) {
var $div = $(this).find("div"); // the div on the clicked row
var divClass = $div.prop("class"); // its class
var $checkbox = $(this).find("input"); // the checkbox
var check = $checkbox.is(":checked"); // whether or not it is checked
if (e.target.type != "checkbox") { // we clicked somewhere else
check = !check; // toggle
$checkbox.prop("checked", check); // set the check
}
if (check) { // are we enabling?
if (divClass.indexOf("disabled") != -1) { // disabled?
$div.removeClass(divClass).addClass(divClass.replace("-disabled", ""));
}
}
else { // disable it
$div.removeClass(divClass).addClass(divClass + "-disabled");
}
var $otherContact=$(this).siblings("tr"); // the sibling row
if (check) {
$div = $otherContact.find("div");
divClass=$div.prop("class");
if (divClass.indexOf("disabled") == -1) {
$div.removeClass(divClass).addClass(divClass+"-disabled");
}
$checkbox=$otherContact.find("input"); // the checkbox
if ($checkbox.is(":checked")) $checkbox.prop("checked",false);
}
});
});
It's happening because you are selecting element by id and which is duplicate. You have to find your required element traversing up through its ancestors in the DOM tree so that selector only select elements within current row by setting a area of elements. Here is working code.
$(function () {
$("[id*=divchkemail]").click(function (e) {
var currentRow = $(e.target).parents().closest('table');
$(this).toggleClass("image-email");
if ($(currentRow).find('#chkemail').prop('checked')) {
$(currentRow).find('#chkemail').prop('checked', false);
}
else {
var chkPhoneInCurrentRow = $(currentRow).find('#chkphone')
var divchkInCurrentRow = $(currentRow).find('#divchkphone')
if ($(chkPhoneInCurrentRow).prop('checked')) {
$(chkPhoneInCurrentRow).prop('checked', false);
$(divchkInCurrentRow).toggleClass("image-phone");
}
$(currentRow).find('#chkemail').prop('checked', true);
}
});
$("[id*=divchkphone]").click(function (e) {
var currentRow = $(e.target).parents().closest('table');
$(this).toggleClass("image-phone");
if ($(currentRow).find('#chkphone').prop('checked')) {
$(currentRow).find('#chkphone').prop('checked', false);
}
else {
var chkEmailInCurrentRow = $(currentRow).find('#chkemail')
var divchkInCurrentRow = $(currentRow).find('#divchkemail')
if ($(chkEmailInCurrentRow).prop('checked')) {
$(chkEmailInCurrentRow).prop('checked', false);
$(divchkInCurrentRow).toggleClass("image-email");
}
$(currentRow).find('#chkphone').prop('checked', true);
}
});
});
.image-phone-disabled {
background-image:url('http://i.imgur.com/74FcgdS.png');
background-repeat:no-repeat ;
width:34px;
height:34px;
}
.image-phone {
background-image:url(http://i.imgur.com/LwsHkOt.png);
background-repeat:no-repeat ;
width:34px;
height:34px;
}
.image-email-disabled {
background-image:url('http://i.imgur.com/khd2NG8.png');
background-repeat:no-repeat ;
width:34px;
height:34px;
}
.image-email {
background-image:url(http://i.imgur.com/y5KE9jx.png);
background-repeat:no-repeat ;
width:34px;
height:34px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table border=0>
<tr>
<td>
<div id="divchkemail" class="image-email-disabled" /> </td>
<td> <input id="chkemail" type="checkbox" name="ctl00$ContentPlaceHolder1$tabContainer$tabRequests$Requests$cndt1$FindInspector$rptSearch$ctl01$chkemail"></input>
</td>
</tr>
<tr>
<td>
<div id="divchkphone" class="image-phone-disabled" />
</td>
<td>
<input id="chkphone" type="checkbox" name="ctl00$ContentPlaceHolder1$tabContainer$tabRequests$Requests$cndt1$FindInspector$rptSearch$ctl01$chkphone"></input>
</td>
</tr>
</table>
<br/>
<br/>
<br/>
<span>
</span>
<table border=0>
<tr>
<td><div id="divchkemail" class="image-email-disabled" /></td>
<td>
<input id="chkemail" type="checkbox" name="ctl00$ContentPlaceHolder1$tabContainer$tabRequests$Requests$cndt1$FindInspector$rptSearch$ctl02$chkemail"></input>
</td>
</tr>
<tr>
<td><div id="divchkphone" class="image-phone-disabled" /></td>
<td>
<input id="chkphone" type="checkbox" name="ctl00$ContentPlaceHolder1$tabContainer$tabRequests$Requests$cndt1$FindInspector$rptSearch$ctl02$chkphone"></input>
</td>
</tr>
</table>
<span>
</span>
Here is working fiddle.
http://jsfiddle.net/hannnan/noukkjsq/
This is happening because you are using the same IDs for everything - the JS cannot differentiate between the two rows. So you click the second row's icon, the first element it finds with your ID (#divchkemail) it performs the action on, which is in the first row.

Regular Expression not working - Online form validation and submission

So Im having trouble with my form. There are numurous validation techniques set up.
Two of my most obvious problems are an alert that pops upen at the start of the program but should only pop up if an onblur() is activated and my update() function returns a false value.
And aswell, my regular Expressions insist on providing me with false condition when I test them against my strings.
The finished form should validate various information and update values placed in the expenses inputs.
Really stuck on this...
window.onload = initPage;
/*initPage()
Initializes the contents of the Web page */
function initPage() {
//declare array variable dataFields points to input elements from the expenseEntry class
var dataFields = new Array();
var allElems = document.getElementsByTagName("*");
for( var i = 0; i < allElems.length; i ++) {
if(allElems[i].className == "expenseEntry") dataFields.push(allElems[i]);
}
//add onblur event that runs update() function whenever focus leaves a datafield.
for(var i = 0; i < dataFields.length; i++) {
dataFields[i].onblur = update();
}
//event handler that runs validateForm() upon submitting the form.
document.forms[0].onsubmit = validateForm;
}
/* testLength()
Tests a field for its length. */
function testLength(field) {
if (field.value.length == 0) {
// Change the background color to white or yellow depending on the lenght.
field.style.backgroundColor = "yellow";
return false;
}
else field.style.backgroundColor = "white";
return true;
}
/* testPattern()
Tests a field for its pattern. */
function testPattern(field, regx) {
if (regx.test(field)) {
field.style.backgroundColor = "white";
field.style.color = "black";
return true;
}
else field.style.backgroundColor = "yellow";
field.style.color = "red";
return false;
}
/* validateForm()
Validates a Web form */
function validateForm() {
var isValid = true;
//testLength function with lname field also for fname, address, and summary to make sure an entry has been made.
if (testLength(document.forms[0].lname) == false) {
isValid = false;}
if (testLength(document.forms[0].fname) == false) {
isValid = false;}
if (testLength(document.forms[0].address) == false) {
isValid = false;}
if (testLength(document.forms[0].summary) == false) {
isValid = false;}
//must match ACT followed by six digits
if (testPattern(document.forms[0].account,/^ACT\d{6}$/) == false)
{isValid = false;}
//dept field. regx should match DEPT followed by three digits
if (testPattern(document.forms[0].department.value,/^DEPT\d{3}$/) == false)
{isValid = false;}
//Project field with regx should match PROJ followed by five digits
if (testPattern(document.forms[0].project,/^PROJ\d{5}$/) == false)
{isValid = false;}
//call testPattern function to test SSN. match 9 digits or text string
if (testPattern(document.forms[0].ssn,/^\d{3}-\d{2}-\d{4}$/) == false)
{isValid = false;}
if (isValid == false)
{alert("Please fill out all required fields in the proper format.");}
return isValid;
}
/* calcRow
Calculates the costs within one row of the travel report */
function calcRow(row) {
var travel = parseFloat(document.forms[0].elements["travel"+row].value);
var lodge = parseFloat(document.forms[0].elements["lodge"+row].value);
var meal = parseFloat(document.forms[0].elements["meal"+row].value);
return travel+lodge+meal;
}
/* calcTotal()
Calculates the total cost of the travel */
function calcTotal() {
//create a variable totalEXP
var totalExp = 0;
//create a for loop that runs 1 t0 4
for (var i = 1; i <= 4; i++)
// increase the value of totalExp by value returned for calcRow
{ totalExp += calcRow(i);}
return totalExp;
}
/* upDate()
Updates the total travel cost */
function update() {
//create a variable numRegExp
var numRegExp = /^\d*(\.\d{0,2})?$/;
// Test weather the currently selected object matches the numRegExp pattern
if (numRegExp.test(this.value)){
// Display the value of the current object to 2 decimal places.
parseInt(this.value).toFixed(2);
//insert a for loop that runs 1 to 4 for all the expense rows in the form
for (var i = 1; i < 4; i++) {
//Set the value of sub[i] field to the value returned by calcRow()
document.forms[0].elements["sub" + i].value = calcRow(i).toFixed(2);
//set the value of the total field equal to the value returned by the calTotal() function
document.forms[0].total.value = calcTotal().toFixed(2);
}
}
//if the condition is not met display alert and change value.
else if (numRegExp.test(this.value) == false) {
alert("Invalid currency value");
(this.value = "0.00");
this.focus();
}
}
body {background: white url(back.jpg) repeat-y scroll 0px 0px}
#links {position: absolute; top: 10px; left: 0px}
#main {border: 1px solid black; width: 640px; padding: 5px;
background-color: white; margin-left: 100px; margin-top: 0px}
span {color: red; font-family: Arial, Helvetica, sans-serif; font-size: 9pt}
table {font-size: 8pt; width: 630px; margin-top: 5px; margin-bottom: 0px}
th {background-color: rgb(153,204,255); text-align: left; font-weight: normal;
font-family: Arial, Helvetica, sans-serif}
#reporttitle {background-color: white; text-align: center; font-family: Arial, Helvetica, sans-serif;
font-size: 18pt; color: rgb(153,204,255); font-weight: bold}
input {width: 100%; font-size: 8pt}
select {width: 100%; font-size: 8pt}
#lname, #fname {width: 150px}
#account, #department, #project {width: 150px}
#traveltable th {text-align: center}
#subhead {width: 100px}
#travelexphead, #lodgeexphead, #mealexphead {width: 80px}
#date1, #date2, #date3, #date4 {text-align: center}
#travel1, #travel2, #travel3, #travel4 {text-align: right}
#lodge1, #lodge2, #lodge3, #lodge4 {text-align: right}
#meal1, #meal2, #meal3, #meal4 {text-align: right}
#sub1, #sub2, #sub3, #sub4,#total {text-align: right}
#traveltable #totalhead {text-align: right}
textarea {height: 100px; width: 100%}
#main #psub {text-align: center}
#main p input {width: 190px; background-color: rgb(153,204,255); color: black;
letter-spacing: 5}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!--
New Perspectives on JavaScript, 2nd Edition
Tutorial 5
Case Problem 2
Expense Report Form
Author: Gavin Macken
Date: 8 March `15
Filename: exp.htm
Supporting files: back.jpg, exp.css, links.jpg, logo.jpg, report.js
-->
<title>Expense Report</title>
<link href="exp.css" rel="stylesheet" type="text/css" />
<script src = "report.js" type = "text/javascript"></script>
</head>
<body>
<form id="expform" method="post" action="done.htm">
<div id="links"><img src="links.jpg" alt="" /></div>
<div id="main">
<p><img src="logo.jpg" alt="DeLong Enterprises" /></p>
<table cellspacing="2">
<tr>
<th colspan="5" id="reporttitle">Travel Expense Report</th>
</tr>
<tr>
<th>Name (Last)<span>*</span></th>
<th>(First)<span>*</span></th>
<th>(Initial)</th>
<th>Account<span>*</span></th>
<td><input name="account" id="account" /></td>
</tr>
<tr>
<td><input name="lname" id="lname"/></td>
<td><input name="fname" id="fname"/></td>
<td><input name="init" id="init"/></td>
<th>Department<span>*</span></th>
<td><input name="department" id="department" /></td>
</tr>
<tr>
<th>Social Security Number<span>*</span></th>
<td colspan="2"><input name="ssn" id="ssn" /></td>
<th>Project<span>*</span></th>
<td><input name="project" id="project" /></td>
</tr>
</table>
<table cellspacing="2">
<tr>
<th>Send Check to:<span>*</span></th>
<th>Trip Summary<span>*</span></th>
</tr>
<tr>
<td>
<textarea id="address" name="address" rows="" cols=""></textarea>
</td>
<td>
<textarea id="summary" name="summary" rows="" cols=""></textarea>
</td>
</tr>
</table>
<table id="traveltable" cellspacing="2">
<tr>
<th id="datehead">Travel Date</th>
<th id="travelexphead">Travel Cost</th>
<th id="traveltypehead">Type</th>
<th id="lodgeexphead">Lodging</th>
<th id="mealexphead">Meals</th>
<th id="subhead">Total</th>
</tr>
<tr>
<td><input name="date1" id="date1" /></td>
<td><input name="travel1" id="travel1" value="0.00" class="expenseEntry" /></td>
<td><select name="traveltype1" id="traveltype1">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td><input name="lodge1" id="lodge1" value="0.00" class="expenseEntry" /></td>
<td><input name="meal1" id="meal1" value="0.00" class="expenseEntry" /></td>
<td><input name="sub1" id="sub1" value="0.00" readonly="readonly" /></td>
</tr>
<tr>
<td><input name="date2" id="date2" /></td>
<td><input name="travel2" id="travel2" value="0.00" class="expenseEntry" /></td>
<td><select name="traveltype2" id="traveltype2">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td><input name="lodge2" id="lodge2" value="0.00" class="expenseEntry" /></td>
<td><input name="meal2" id="meal2" value="0.00" class="expenseEntry" /></td>
<td><input name="sub2" id="sub2" value="0.00" readonly="readonly" /></td>
</tr>
<tr>
<td><input name="date3" id="date3" /></td>
<td><input name="travel3" id="travel3" value="0.00" class="expenseEntry" /></td>
<td><select name="traveltype3" id="traveltype3">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td><input name="lodge3" id="lodge3" value="0.00" class="expenseEntry" /></td>
<td><input name="meal3" id="meal3" value="0.00" class="expenseEntry" /></td>
<td><input name="sub3" id="sub3" value="0.00" readonly="readonly" /></td>
</tr>
<tr>
<td><input name="date4" id="date4" /></td>
<td><input name="travel4" id="travel4" value="0.00" class="expenseEntry" /></td>
<td><select name="traveltype4" id="traveltype4">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td><input name="lodge4" id="lodge4" value="0.00" class="expenseEntry" /></td>
<td><input name="meal4" id="meal4" value="0.00" class="expenseEntry" /></td>
<td><input name="sub4" id="sub4" value="0.00" readonly="readonly" /></td>
</tr>
<tr>
<th colspan="5" id="totalhead">TOTAL</th>
<td><input id="total" name="total" readonly="readonly" value="0.00" /></td>
</tr>
<tr>
<td colspan="6"><span>* - Indicates a required field</span></td>
</tr>
</table>
<p id="psub">
<input type="submit" value="Submit Report" />
</p>
</div>
</form>
</body>
</html>
You're testing the DOM element against the regexp, which doesn't make sense. The argument to regx.test() must be a string. You need to use the value of the field:
if (regx.test(field.value)) {
You're setting the onblur property wrong. It should be set to the update function, but you're calling the function at that time. It should be:
dataFields[i].onblur = update;
And you were using the .value property when you called testPattern for the department field. But testPattern expects the argument to be the element, not the value. It should be:
if (testPattern(document.forms[0].department, /^DEPT\d{3}$/) == false)
window.onload = initPage;
/*initPage()
Initializes the contents of the Web page */
function initPage() {
//declare array variable dataFields points to input elements from the expenseEntry class
var dataFields = new Array();
var allElems = document.getElementsByTagName("*");
for (var i = 0; i < allElems.length; i++) {
if (allElems[i].className == "expenseEntry") dataFields.push(allElems[i]);
}
//add onblur event that runs update() function whenever focus leaves a datafield.
for (var i = 0; i < dataFields.length; i++) {
dataFields[i].onblur = update;
}
//event handler that runs validateForm() upon submitting the form.
document.forms[0].onsubmit = validateForm;
}
/* testLength()
Tests a field for its length. */
function testLength(field) {
if (field.value.length == 0) {
// Change the background color to white or yellow depending on the lenght.
field.style.backgroundColor = "yellow";
return false;
} else field.style.backgroundColor = "white";
return true;
}
/* testPattern()
Tests a field for its pattern. */
function testPattern(field, regx) {
if (regx.test(field.value)) {
field.style.backgroundColor = "white";
field.style.color = "black";
return true;
} else field.style.backgroundColor = "yellow";
field.style.color = "red";
return false;
}
/* validateForm()
Validates a Web form */
function validateForm() {
var isValid = true;
//testLength function with lname field also for fname, address, and summary to make sure an entry has been made.
if (testLength(document.forms[0].lname) == false) {
isValid = false;
}
if (testLength(document.forms[0].fname) == false) {
isValid = false;
}
if (testLength(document.forms[0].address) == false) {
isValid = false;
}
if (testLength(document.forms[0].summary) == false) {
isValid = false;
}
//must match ACT followed by six digits
if (testPattern(document.forms[0].account, /^ACT\d{6}$/) == false)
{
isValid = false;
}
//dept field. regx should match DEPT followed by three digits
if (testPattern(document.forms[0].department, /^DEPT\d{3}$/) == false)
{
isValid = false;
}
//Project field with regx should match PROJ followed by five digits
if (testPattern(document.forms[0].project, /^PROJ\d{5}$/) == false)
{
isValid = false;
}
//call testPattern function to test SSN. match 9 digits or text string
if (testPattern(document.forms[0].ssn, /^\d{3}-\d{2}-\d{4}$/) == false) {
isValid = false;
}
if (isValid == false)
{
alert("Please fill out all required fields in the proper format.");
}
return isValid;
}
/* calcRow
Calculates the costs within one row of the travel report */
function calcRow(row) {
var travel = parseFloat(document.forms[0].elements["travel" + row].value);
var lodge = parseFloat(document.forms[0].elements["lodge" + row].value);
var meal = parseFloat(document.forms[0].elements["meal" + row].value);
return travel + lodge + meal;
}
/* calcTotal()
Calculates the total cost of the travel */
function calcTotal() {
//create a variable totalEXP
var totalExp = 0;
//create a for loop that runs 1 t0 4
for (var i = 1; i <= 4; i++)
// increase the value of totalExp by value returned for calcRow
{
totalExp += calcRow(i);
}
return totalExp;
}
/* upDate()
Updates the total travel cost */
function update() {
//create a variable numRegExp
var numRegExp = /^\d*(\.\d{0,2})?$/;
// Test weather the currently selected object matches the numRegExp pattern
if (numRegExp.test(this.value)) {
// Display the value of the current object to 2 decimal places.
parseInt(this.value).toFixed(2);
//insert a for loop that runs 1 to 4 for all the expense rows in the form
for (var i = 1; i < 4; i++) {
//Set the value of sub[i] field to the value returned by calcRow()
document.forms[0].elements["sub" + i].value = calcRow(i).toFixed(2);
//set the value of the total field equal to the value returned by the calTotal() function
document.forms[0].total.value = calcTotal().toFixed(2);
}
}
//if the condition is not met display alert and change value.
else if (numRegExp.test(this.value) == false) {
alert("Invalid currency value");
(this.value = "0.00");
this.focus();
}
}
body {
background: white url(back.jpg) repeat-y scroll 0px 0px
}
#links {
position: absolute;
top: 10px;
left: 0px
}
#main {
border: 1px solid black;
width: 640px;
padding: 5px;
background-color: white;
margin-left: 100px;
margin-top: 0px
}
span {
color: red;
font-family: Arial, Helvetica, sans-serif;
font-size: 9pt
}
table {
font-size: 8pt;
width: 630px;
margin-top: 5px;
margin-bottom: 0px
}
th {
background-color: rgb(153, 204, 255);
text-align: left;
font-weight: normal;
font-family: Arial, Helvetica, sans-serif
}
#reporttitle {
background-color: white;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
font-size: 18pt;
color: rgb(153, 204, 255);
font-weight: bold
}
input {
width: 100%;
font-size: 8pt
}
select {
width: 100%;
font-size: 8pt
}
#lname,
#fname {
width: 150px
}
#account,
#department,
#project {
width: 150px
}
#traveltable th {
text-align: center
}
#subhead {
width: 100px
}
#travelexphead,
#lodgeexphead,
#mealexphead {
width: 80px
}
#date1,
#date2,
#date3,
#date4 {
text-align: center
}
#travel1,
#travel2,
#travel3,
#travel4 {
text-align: right
}
#lodge1,
#lodge2,
#lodge3,
#lodge4 {
text-align: right
}
#meal1,
#meal2,
#meal3,
#meal4 {
text-align: right
}
#sub1,
#sub2,
#sub3,
#sub4,
#total {
text-align: right
}
#traveltable #totalhead {
text-align: right
}
textarea {
height: 100px;
width: 100%
}
#main #psub {
text-align: center
}
#main p input {
width: 190px;
background-color: rgb(153, 204, 255);
color: black;
letter-spacing: 5
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!--
New Perspectives on JavaScript, 2nd Edition
Tutorial 5
Case Problem 2
Expense Report Form
Author: Gavin Macken
Date: 8 March `15
Filename: exp.htm
Supporting files: back.jpg, exp.css, links.jpg, logo.jpg, report.js
-->
<title>Expense Report</title>
<link href="exp.css" rel="stylesheet" type="text/css" />
<script src="report.js" type="text/javascript"></script>
</head>
<body>
<form id="expform" method="post" action="done.htm">
<div id="links">
<img src="links.jpg" alt="" />
</div>
<div id="main">
<p>
<img src="logo.jpg" alt="DeLong Enterprises" />
</p>
<table cellspacing="2">
<tr>
<th colspan="5" id="reporttitle">Travel Expense Report</th>
</tr>
<tr>
<th>Name (Last)<span>*</span>
</th>
<th>(First)<span>*</span>
</th>
<th>(Initial)</th>
<th>Account<span>*</span>
</th>
<td>
<input name="account" id="account" />
</td>
</tr>
<tr>
<td>
<input name="lname" id="lname" />
</td>
<td>
<input name="fname" id="fname" />
</td>
<td>
<input name="init" id="init" />
</td>
<th>Department<span>*</span>
</th>
<td>
<input name="department" id="department" />
</td>
</tr>
<tr>
<th>Social Security Number<span>*</span>
</th>
<td colspan="2">
<input name="ssn" id="ssn" />
</td>
<th>Project<span>*</span>
</th>
<td>
<input name="project" id="project" />
</td>
</tr>
</table>
<table cellspacing="2">
<tr>
<th>Send Check to:<span>*</span>
</th>
<th>Trip Summary<span>*</span>
</th>
</tr>
<tr>
<td>
<textarea id="address" name="address" rows="" cols=""></textarea>
</td>
<td>
<textarea id="summary" name="summary" rows="" cols=""></textarea>
</td>
</tr>
</table>
<table id="traveltable" cellspacing="2">
<tr>
<th id="datehead">Travel Date</th>
<th id="travelexphead">Travel Cost</th>
<th id="traveltypehead">Type</th>
<th id="lodgeexphead">Lodging</th>
<th id="mealexphead">Meals</th>
<th id="subhead">Total</th>
</tr>
<tr>
<td>
<input name="date1" id="date1" />
</td>
<td>
<input name="travel1" id="travel1" value="0.00" class="expenseEntry" />
</td>
<td>
<select name="traveltype1" id="traveltype1">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td>
<input name="lodge1" id="lodge1" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="meal1" id="meal1" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="sub1" id="sub1" value="0.00" readonly="readonly" />
</td>
</tr>
<tr>
<td>
<input name="date2" id="date2" />
</td>
<td>
<input name="travel2" id="travel2" value="0.00" class="expenseEntry" />
</td>
<td>
<select name="traveltype2" id="traveltype2">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td>
<input name="lodge2" id="lodge2" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="meal2" id="meal2" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="sub2" id="sub2" value="0.00" readonly="readonly" />
</td>
</tr>
<tr>
<td>
<input name="date3" id="date3" />
</td>
<td>
<input name="travel3" id="travel3" value="0.00" class="expenseEntry" />
</td>
<td>
<select name="traveltype3" id="traveltype3">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td>
<input name="lodge3" id="lodge3" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="meal3" id="meal3" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="sub3" id="sub3" value="0.00" readonly="readonly" />
</td>
</tr>
<tr>
<td>
<input name="date4" id="date4" />
</td>
<td>
<input name="travel4" id="travel4" value="0.00" class="expenseEntry" />
</td>
<td>
<select name="traveltype4" id="traveltype4">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td>
<input name="lodge4" id="lodge4" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="meal4" id="meal4" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="sub4" id="sub4" value="0.00" readonly="readonly" />
</td>
</tr>
<tr>
<th colspan="5" id="totalhead">TOTAL</th>
<td>
<input id="total" name="total" readonly="readonly" value="0.00" />
</td>
</tr>
<tr>
<td colspan="6"><span>* - Indicates a required field</span>
</td>
</tr>
</table>
<p id="psub">
<input type="submit" value="Submit Report" />
</p>
</div>
</form>
</body>
</html>

Gmail like Checkbox functionality

I want to implement gmail like checkbox functionality:
In which If CheckAll checkbox is clicked, all listed checkbox will be selected/unselected, if all listed checkbox are selected, CheckAll checkbox will be checked. and if only some checkbox are checked, - sign checkbox will be appear.
I have implement logic using div.
Here is the logic:
HTML:
<table id="ViewTable" class="tableEffectfull">
<thead>
<tr>
<th class="selectCol"><div class="unCheckedCheckBoxAll"></div></th>
<th class="nosCol">Products</th>
</tr>
</thead>
<tr>
<td><div class="unCheckedCheckBox"></div></td>
<td>ABCD</td>
</tr>
<tr>
<td><div class="unCheckedCheckBox"></div></td>
<td>PQRS</td>
</tr>
</table>
CSS:
.unCheckedCheckBox{
width: 25px;
height: 25px;
margin-top: -4px;
background: transparent url(images/prettyCheckable-green.png) top left no-repeat;
}
.CheckedCheckBox{
background: transparent url(images/prettyCheckable-green.png) 0 -60px;
}
.unCheckedCheckBoxAll{
width: 25px;
height: 25px;
margin-top: -4px;
background: transparent url(images/Checkable-green.png) top left no-repeat;
}
.CheckedCheckBoxAll{
background: transparent url(images/Checkable-green.png) 0 -60px;
}
Script:
//updated scripts:
$(".unCheckedCheckBox").click(function () {
$(this).toggleClass('CheckedCheckBox');
$('.unCheckedCheckBoxAll').toggleClass('CheckedCheckBoxAll', $('.CheckedCheckBox').length == $(".unCheckedCheckBox").length)
});
$(".unCheckedCheckBoxAll").click(function () {
$(this).toggleClass('CheckedCheckBoxAll');
$('.unCheckedCheckBox').toggleClass('CheckedCheckBox')
});
Now the problem is I am not getting what to do if all listed checkbox are selected, make checkedAll checkbox to be checked and if some are checked only highlighted checkbox will be display in checkedAll.
Below is the Image I am using:
$(".unCheckedCheckBox").click(function () {
$(this).toggleClass('CheckedCheckBox');
$('.unCheckedCheckBoxAll').toggleClass('CheckedCheckBoxAll', $('.CheckedCheckBox').length == $(".unCheckedCheckBox").length)
});
$(".unCheckedCheckBoxAll").click(function () {
$(this).toggleClass('CheckedCheckBoxAll');
$('.unCheckedCheckBox').toggleClass('CheckedCheckBox', $(this).is('.CheckedCheckBoxAll'))
});
demo
Try this and get an idea about how to do it.
http://jsfiddle.net/FdEhf/
<input type="checkbox" class="all" value="all">Check all
<br/>
<input type="checkbox" value="1">
<br/>
<input type="checkbox" value="2">
<br/>
<input type="checkbox" value="3">
<br/>
<input type="checkbox" value="4">
<br/>
<input type="checkbox" value="5">
<br/>
<input type="checkbox" value="6">
<br/>
<input type="checkbox" value="7">
<br/>
<input type="checkbox" value="8">
Script,
$("input.all").on("change", function (e) {
$(':checkbox').prop("checked",$(this).is(":checked"))
});
Update
http://jsfiddle.net/FdEhf/2/
$(document).on("change", ".all:not('.minus')", function (e) {
$(':checkbox').prop("checked", $(this).is(":checked"));
});
$(document).on("change", ".all.minus", function (e) {
$(':checkbox').prop("checked", false);
$(".all").removeClass("minus");
});
$(document).on("change", ":checkbox:not('.all')", function (e) {
if ($(':checkbox').not(".all").length == $(':checkbox:checked').not(".all").length) {
$(".all").prop("checked", true).removeClass("minus");
} else {
$(".all").prop("checked", false).addClass("minus");
if ($(':checkbox:checked').not(".all").length == 0) {
$(".all").removeClass("minus");
}
}
});
UPDATE2
Updated to your approch based on your request.http://jsfiddle.net/FdEhf/4/
<table id="ViewTable" class="tableEffectfull">
<thead>
<tr>
<th class="selectCol">
<div class="unCheckedCheckBoxAll"></div>
</th>
<th class="nosCol">Products</th>
</tr>
</thead>
<tr>
<td>
<div class="unCheckedCheckBox"></div>
</td>
<td>ABCD</td>
</tr>
<tr>
<td>
<div class="unCheckedCheckBox"></div>
</td>
<td>PQRS</td>
</tr>
</table>
Script,
$(document).on("click", ".unCheckedCheckBoxAll:not('.minus')", function (e) {
$(this).toggleClass('CheckedCheckBoxAll');
$('.unCheckedCheckBox').toggleClass('CheckedCheckBox');
});
$(document).on("click", ".unCheckedCheckBoxAll.minus", function (e) {
$('.unCheckedCheckBox').removeClass('CheckedCheckBox');
$(this).removeClass("minus");
});
$(document).on("click", ".unCheckedCheckBox", function (e) {
$(this).toggleClass("CheckedCheckBox");
if ($('.unCheckedCheckBox').length == $('.CheckedCheckBox').length) {
$(".unCheckedCheckBoxAll").removeClass("minus");
} else {
$(".unCheckedCheckBoxAll").removeClass("CheckedCheckBoxAll").addClass("minus");
if ($('.CheckedCheckBox').length == 0) {
$(".unCheckedCheckBoxAll").removeClass("minus");
}
}
});
Try this
http://jsfiddle.net/VrkA3/1/
I have changed the script :
$(".unCheckedCheckBox").click(function () {
$(this).toggleClass('CheckedCheckBox');
if ($('.CheckedCheckBox').length == 2) {
$('.CheckBoxAll').addClass('CheckedCheckBoxAll').removeClass('minusCheckBoxAll')
} else {
$('.CheckBoxAll').removeClass('CheckedCheckBoxAll')
if ($('.CheckedCheckBox').length == 0)
$('.CheckBoxAll').removeClass('minusCheckBoxAll')
else $('.CheckBoxAll').addClass('minusCheckBoxAll')
}
});
$(".CheckBoxAll").click(function () {
$(this).removeClass('minusCheckBoxAll')
$(this).toggleClass('CheckedCheckBoxAll');
$('.unCheckedCheckBox').toggleClass('CheckedCheckBox', $(this).is('.CheckedCheckBoxAll'))
});
added a two new css classes too...
.unCheckedCheckBox {
width: 25px;
height: 25px;
margin-top: -4px;
background: red top left no-repeat;
}
.CheckedCheckBox {
background: pink 0 -60px;
}
.CheckBoxAll {
background: white;
}
.unCheckedCheckBoxAll {
width: 25px;
height: 25px;
margin-top: -4px;
background: blue top left no-repeat;
}
.CheckedCheckBoxAll {
background: black 0 -60px;
}
.minusCheckBoxAll {
background: green 0 -60px;
}

Categories