Gmail like Checkbox functionality - javascript

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;
}

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>

How to create a fully functional contact form within an HTML form

I have a small HTML form. Basically my goal is to have the first tab to display a contact form that will unlock the rest of the form and give the user the ability to edit the contact form after submit (incase of an error) without refreshing the page and deleting the form values that display in the form. After the contact portion is submitted the values entered will display throughout the form.
https://jsfiddle.net/yq7hon4u/
// Contact Form
function submitButton() {
document.getElementById('submitButton').style.display = "none";
document.getElementById('contactBar').style.display = "block";
return false;
}
function contact() {
var firstName = document.getElementById("firstName").value;
var lastName = document.getElementById("lastName").value;
var email = document.getElementById("email").value;
document.getElementById("firstName1").textContent = firstName;
document.getElementById("lastName1").textContent = lastName;
document.getElementById("email1").textContent = email;
}
//Form Tabs
var currentTab = 0; // Current tab is set to be the first tab (0)
showTab(currentTab); // Display the current tab
function showTab(n) {
// This function will display the specified tab of the form ...
var x = document.getElementsByClassName("tab");
x[n].style.display = "block";
if (n == 0) {
document.getElementById("prevBtnBottom").style.display = "none";
document.getElementById("prevBtnTop").style.display = "none";
} else {
document.getElementById("prevBtnBottom").style.display = "inline";
document.getElementById("prevBtnTop").style.display = "inline";
}
//Form 5 displays only Previous button, Next button is disabled.
if (n == 3) {
document.getElementById("nextBtnBottom").style.display = "none";
document.getElementById("nextBtnTop").style.display = "none";
} else {
document.getElementById("nextBtnBottom").style.display = "inline";
document.getElementById("nextBtnTop").style.display = "inline";
}
fixStepIndicator(n)
}
function nextPrev(n) {
// This function will figure out which tab to display
var x = document.getElementsByClassName("tab");
// Exit the function if any field in the current tab is invalid:
if (n == 1 && !validateForm()) return false;
// Hide the current tab:
x[currentTab].style.display = "none";
// Increase or decrease the current tab by 1:
currentTab = currentTab + n;
// if you have reached the end of the form... :
if (currentTab >= x.length) {
//...the form gets submitted:
document.getElementById("regForm").submit();
return false;
}
// Otherwise, display the correct tab:
showTab(currentTab);
}
function validateForm() {
// This function deals with validation of the form fields
var x, y, i, valid = true;
x = document.getElementsByClassName("tab");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i++) {
// If a field is empty...
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].className += " invalid";
// and set the current valid status to false:
valid = false;
}
}
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("step")[currentTab].className += " finish";
}
return valid; // return the valid status
}
function fixStepIndicator(n) {
// This function removes the "active" class of all steps...
var i, x = document.getElementsByClassName("step");
for (i = 0; i < x.length; i++) {
x[i].className = x[i].className.replace(" active", "");
}
//... and adds the "active" class to the current step:
x[n].className += " active";
}
/* Style the form */
#regForm {
margin: 20px auto;
width: 70%;
min-width: 300px;
}
/* Style for Select */
select.select {
font-size: 15px;
width: 55%;
Border: none;
background-color: #e9e9e9;
}
/* Style for buttons */
button {
background-color: #faa51a;
font-size: 16px;
}
/* Hidden */
.hide {
display: none;
}
/* Hide all steps by default: */
.tab {
display: none;
}
/* Make circles that indicate the steps of the form: */
.step {
height: 24px;
width: 20px;
margin: 0 2px;
background-color: #b8cce4;
border: none;
border-radius: 50%;
display: inline-block;
opacity: 0.5;
}
/* Mark the active step: */
.step.active {
opacity: 1;
}
/* Mark the steps that are finished and valid: */
.step.finish {
background-color: #b8cce4;
}
/* Used for blue background headings */
tr.blueHead {
background-color: #b8cce4;
}
/* Resposive table */
table {
border-collapse: collapse;
box-shadow: 0px 0px 25px 15px rgba(0, 0, 0, 0.20);
background-color: #e9e9e9;
}
table.center {
margin-left: auto;
margin-right: auto;
}
table.summary {
background-color: e9e9e9 border-collapse: collapse;
border-spacing: 0;
width: 100%;
border: 1px solid #ddd;
}
/* Sets padding around the table cells */
th,
td {
padding: 3px;
/* text-align: left;*/
}
/* Subtotal */
td.subtotal {
text-align: right;
font-weight: bold;
}
/* Indents table cells */
td.indent {
text-indent: 2%;
}
img.center {
text-align: center;
display: block;
margin: 0 auto;
}
td,
th {
border: 1px solid #ddd;
}
.center {
text-align: center;
}
<!-- Start of RegForm -->
<div id="tab">
<div id="regForm">
<br>
<div style="float:right;">
<button type="button" id="prevBtnTop" onclick="nextPrev(-1)">🢀</button>
<button type="button" id="nextBtnTop" onclick="nextPrev(1)">🢂</button>
</div>
<br>
<br>
</head>
<body>
<div class="tab">
<center>
</center>
<h4><u>Fill out the folowing required fields</u></h4>
<center>
<form action="" onsubmit="return submitButton()">
<div id="submitButton" style="margin-bottom: -20px">
<input id="firstName" type="text" class="feedback-input" placeholder="First Name" required/>
<input id="lastName" type="text" class="feedback-input" placeholder="Last Name" required/>
<input id="email" type="text" class="feedback-input" placeholder="Email" required/>
<button onclick="contact(); nextPrev(1);" value="submit">Submit</button>
<br>
</center>
</div>
<div id="contactBar" style="display:none; margin-bottom: -30px">
<table id="contact" class="noDecor">
<tr class="noDecor">
<td class="noDecor"><b><span id="firstName1"></span></b></td>
<td class="noDecor"><b><span id="lastName1"></span></b></td>
<td class="noDecor"><b><span id="email1"></span></b></td>
</tr>
</table>
</div>
<br><br>
</form>
<!-- A.-->
<div class="tab">
<table id="sectionA">
<tr class="blueHead">
<th colspan="3"><b>Section A </b></th>
</tr>
<tr>
<td></td>
</tr>
</table>
<table id="table1">
<tr>
<td>Question 1:</td>
<td>
<select>
<option value="0">0</option>
<option value="1">1</option>
</select>
</td>
</tr>
<tr>
<td>Question 2:</td>
<td>
<select>
<option value="0">0</option>
<option value="1">1</option>
</select>
</td>
</tr>
</table>
<br>
</div>
<!-- B. -->
<div class="tab">
<table id="sectionB">
<tr class="blueHead">
<th colspan="3"><b>Section B </b></th>
</tr>
</table>
<table id="table2">
<tr>
<td>Question 3:</td>
<td>
<select>
<option value="0">0</option>
<option value="1">1</option>
</select>
</td>
</tr>
<tr>
<td>Question 4:</td>
<td>
<select>
<option value="0">0</option>
<option value="1">1</option>
</select>
</td>
</tr>
</table>
<br>
</div>
<!-- C. -->
<div class="tab">
<table id="sectionC">
<tr class="blueHead">
<th colspan="3"><b>Section C </b></th>
</tr>
</table>
<table id="table3">
<tr>
<td>Question 5:</td>
<td>
<select>
<option value="0">0</option>
<option value="1">1</option>
</select>
</td>
</tr>
<tr>
<td>Question 6:</td>
<td>
<select>
<option value="0">0</option>
<option value="1">1</option>
</select>
</td>
</tr>
</table>
<br>
</div>
<!-- Next and Previous buttons -->
<div style="float:right;">
<button type="button" id="prevBtnBottom" onclick="nextPrev(-1)">🢀</button>
<button type="button" id="nextBtnBottom" onclick="nextPrev(1)">🢂</button>
</div>
</div>
<div style="text-align:center;margin-top:40px;">
<span class="step"><b>S</a></span>
<span class="step">A</span>
<span class="step">B</span>
<span class="step">C</span>
</span>
</div>
<br>
</div>
</div>

Keeping the previous highlighting with jquery

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>

Fieldset Top Border breaks after changing the background color of Input field present in it: Only in IE 11

Update
I am facing an issue with fieldset top border in IE 11.
Description:
I am having a fieldset in my web page. Its legend tag contains a checkbox. And its sub elements are input text fields. I have a JS which changes background color of input fields on checking/Unchecking checkbox present in legend.
Problem:
When background color of input field changes, Fieldset's top border breaks
Can anyone tell me why this is happening?
Sample Code:
function changeBackground() {
document.getElementById("changeit").style.backgroundColor = "red";
}
table .td-left {
width: 60%;
text-align: left;
}
table .td-right {
width: 40%;
text-align: right;
}
<fieldset>
<legend>
<input type="checkbox" onclick="changeBackground()">
<label>Hello</label>
</legend>
<table>
<tr>
<td class="td-right">
<label>Enter Text Here:</label>
</td>
<td class="td-left">
<input type="text" id="changeit">
</td>
</tr>
</table>
</fieldset>
The problem is caused by the checkbox in the legend, obviously. Simply removing the checkbox from the legend makes it work fine.
function changeBackground() {
document.getElementById("changeit").style.backgroundColor = "red";
}
table .td-left {
width: 60%;
text-align: left;
}
table .td-right {
width: 40%;
text-align: right;
}
<fieldset>
<legend>
</legend>
<div style="color:green; height:0; overflow:visible">Booh Booh Booh Booh Booh Booh Booh</div>
<input type="checkbox" onclick="changeBackground()">
<label>Hello</label>
<table>
<tr>
<td class="td-right">
<label>Enter Text Here:</label>
</td>
<td class="td-left">
<input type="text" id="changeit">
</td>
</tr>
</table>
</fieldset>
So what we need to do is make it look like the checkbox is in the legend, without it actually being in there. How about this:
function changeBackground() {
document.getElementById("changeit").style.backgroundColor = "red";
}
table .td-left {
width: 60%;
text-align: left;
}
table .td-right {
width: 40%;
text-align: right;
}
fieldset label[for='flip']::before {
content: ' ☐ ';
}
#flip {
display: none;
}
#flip:checked+fieldset label[for='flip']::before {
content: ' ☑ ';
}
<input type="checkbox" id="flip" onclick="changeBackground()">
<fieldset>
<legend>
<label for="flip">Hello</label>
</legend>
<table>
<tr>
<td class="td-right">
<label>Enter Text Here:</label>
</td>
<td class="td-left">
<input type="text" id="changeit">
</td>
</tr>
</table>
</fieldset>

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.

Categories