restricting user to check checkboxes based on my requirement - javascript

This is in addition to previous question
I've got a bunch of checkboxes in a table, I would like to restrict the user to check the checkboxes based on following rules.
If user is clicking any one of the checkbox in a particular row, the we have to make next two checkboxes checked programatically (jquery) and as well as uncheck (toggle).
There will be Block button/checkbox, if user is clicking block button then we have to disable all checkboxes in that row, except already checked.
We have restrict user to check checkbox, if there is no next two checkboxes available(i.e, unchecked). This is rule exception for last checkbox in a row (User can able to check last checkbox in a row).
Here i have managed with 1 and 2 rules, but for third rule i'm not getting any idea.
Jquery
$('.grp:checkbox').change(function () {
var obj = $(this).parent().nextAll("td").slice(0, 2);
if ($(this).is(":checked")) {
//$(this).removeClass('grp');
obj.find(":checkbox").prop('checked', true);
obj.find(":checkbox").prop('disabled', true);
} else {
obj.find(":checkbox").prop('checked', false);
obj.find(":checkbox").prop('disabled', false);
}
});
$('.block').change(function (e) {
var obj = $(this).parent().nextAll("td");
if ($(this).is(":checked")) {
obj.find(":checkbox").prop('checked', true).prop('disabled', true);
} else {
obj.find(":checkbox").prop('checked', false).prop('disabled', false);
}
});
Demo Fiddle
if anyone giving me any suggestions, it may help full for me.
Thanks in advance.

Finally i got my answer,
here i'm posting my answer, it my helpfull to someone.
Jquery
$('.adj :checkbox').change(function () {
//alert('1');
var obj = $(this).parent().nextAll("td").slice(0, 2);
if ($(this).is(":checked") && $(this).hasClass("grp")) {
//alert('2');
if (obj.find(".grp:checkbox").hasClass("grp")) {
var i = $(this).attr("id");
//alert(i);
$(this).addClass(i);
$(this).toggleClass('grp bkd');
obj.find(".grp:checkbox").prop('checked', true).addClass(i);
obj.find(".grp:checkbox").prop('disabled', true).toggleClass('grp bkd');
} else {
$(this).prop('checked', false);
}
} else {
var id = $(this).attr("id");
$(this).removeClass(id);
$(this).toggleClass('grp bkd');
obj.find("." + id + ":checkbox").prop('checked', false);
obj.find("." + id + ":checkbox").prop('disabled', false).toggleClass('grp bkd').removeClass(id);
}
});
$('.block').change(function (e) {
var obj = $(this).parent().nextAll("td");
if ($(this).is(":checked")) {
obj.find(".grp:checkbox").prop('checked', true).prop('disabled', true);
} else {
obj.find(".grp:checkbox").prop('checked', false).prop('disabled', false);
}
});
Working Fiddle

1) Create an empty array chked.
2) Iterate the obj to check whether it is checked or not using $.each()
$.each(obj, function (i, j) {
});
3) Push the value returned by each iteration.
chked.push($(j).find('input')[0].checked);
4) Using $.inArray(), check for any unchecked available
var isAvailable = $.inArray(false, chked);
this returns -1 is any of the 2 checkbox has value true otherwise 0
finally,
$('.grp:checkbox').change(function () {
var obj = $(this).parent().nextAll("td").slice(0, 2);
var chked = [];
$.each(obj, function (i, j) {
chked.push($(j).find('input')[0].checked);
});
var isAvailable = $.inArray(false, chked);
console.log(isAvailable);
if (chked.length != 0 && isAvailable == -1) {
return false;
} else {
if ($(this).is(":checked")) {
//$(this).removeClass('grp');
obj.find(":checkbox").prop('checked', true);
obj.find(":checkbox").prop('disabled', true);
} else {
obj.find(":checkbox").prop('checked', false);
obj.find(":checkbox").prop('disabled', false);
}
}
});
JSFiddle

Related

jQuery checkbox trigger change not working

I have the following JS function:
const bindSwitches = function() {
$(document).on("click", ".lever", function() {
var checkbox = $(this).siblings("input[type=checkbox]");
var hiddenField = $(this).siblings("input[type=hidden]");
if (checkbox.prop("checked") === true) {
checkbox.prop("value", 0);
hiddenField.prop("value", 0);
} else if (checkbox.prop("checked") === false) {
checkbox.prop("value", 1);
hiddenField.prop("value", 1);
}
$(checkbox).trigger("change");
});
};
It interacts with a switch component provided by the Materialize library. I have just added the final line, as there is some behaviour that needs to occur whenever a checkbox is triggered. But that change event never fires. I also have this function in my app:
const bindAllChecks = function() {
$(document).on("change", ".select-all-check", function() {
var checks = $(this).closest(".table, table").find(".multiple-check:visible");
if (this.checked) {
$.each( checks, function( index, checkbox ){
if ($(checkbox).prop("checked") === false) {
$(checkbox).prop("checked", true);
$(checkbox).trigger("change");
}
});
} else {
$.each( checks, function( index, checkbox ){
if ($(checkbox).prop("checked") === true) {
$(checkbox).prop("checked", false);
$(checkbox).trigger("change");
}
});
}
});
};
Notice how I use the exact same $(checkbox).trigger("change"). In this function it works perfectly.
I've tried changing the order in which I bind the events, to make sure the change event is definitely defined beforehand. I've made sure that the rest of the function is being triggered correctly and that there are no issues in that regard. I've also tried different variations of alternative syntax, nothing has worked.
Here is the code it is supposed to trigger:
const bindCheckboxOverride = function() {
$(document).on("change", ".checkbox-collection input[type=checkbox]:not(.select-all-check)", function() {
var hiddenField = $(this).prev();
if(hiddenField.attr("disabled") === "disabled") {
hiddenField.removeAttr("disabled");
} else {
hiddenField.attr("disabled", "disabled");
}
});
};
I still don't have an exact solution to the question I asked, but I have come up with an alternate method. Instead of trying the trigger a change, I have pulled out the functionality I want from the change even into its own function:
const bindCheckboxOverride = function() {
$(document).on("change", ".checkbox-collection input[type=checkbox]:not(.select-all-check)", function() {
handleCheckboxDisable(this);
});
};
const handleCheckboxDisable = function(checkbox) {
var hiddenField = $(checkbox).prev();
if(hiddenField.attr("disabled") === "disabled") {
hiddenField.removeAttr("disabled");
} else {
hiddenField.attr("disabled", "disabled");
}
};
So now I'm able to call this function directly from my other function:
const bindSwitches = function() {
$(document).on("click", ".lever", function() {
var checkbox = $(this).siblings("input[type=checkbox]");
var hiddenField = $(this).siblings("input[type=hidden]");
if (checkbox.prop("checked") === true) {
checkbox.prop("value", 0);
hiddenField.prop("value", 0);
} else if (checkbox.prop("checked") === false) {
checkbox.prop("value", 1);
hiddenField.prop("value", 1);
}
handleCheckboxDisable(checkbox);
});
};
It doesn't answer the question but I thought that may be of help to somebody. Would still like to know why the original code doesn't work if anybody has any insights.

disable anchor link '<a>' if one of my six checkboxes are not checked

How can I disable a anchor link if one(1) of my six(6) checkbox is not check?
var first_option = $('#pid-1590083, #pid-1590090, #pid-1590091, #pid-1590092, #pid-1590093, #pid-1590094');
$("a").click(function(e) {
if($("first_option").prop("checked") === false) {
e.preventDefault(); return false;
} else {return true;};
});
Your current logic doesn't work as you're only looking at the checked property of the first element you select, not all of them.
To achieve what you require, you can use the :checked selector to get all the checked elements within the selectors you provide, then check the length property of the result to see if there aren't any. Try this:
var $first_option = $('#pid-1590083, #pid-1590090, #pid-1590091, #pid-1590092, #pid-1590093, #pid-1590094');
$("#tmp_button-99035").click(function(e) {
if ($first_option.filter(':checked').length === 0) {
e.preventDefault();
alert('Please Choose Collar Colour To Continue');
};
});
first_option.prop("checked") will always check for first element. What you have to do is loop over all elements to check
Like this
$("#tmp_button-99035").click(function(e) {
var isChecked = false;
for (var i = 0; i < first_option.length; i++) {
if (first_option.eq(i).prop("checked")) {
isChecked = true;
break;
}
}
if (!isChecked) {
alert('Please Choose Collar Colour To Continue');
e.preventDefault();
}
return isChecked;
});
Well, the js snippet of yours is only checking the first element. So, you have to track other checkboxes as well for correct result.
var first_option = $('#pid-1590083, #pid-1590090, #pid-1590091, #pid-1590092, #pid-1590093, #pid-1590094')
$(document).on('click', '#tmp_button-99035', function (e) {
if ($(first_option).filter(":checked").length == 0) {
e.preventDefault();
}
});

How to make a function with multi-condition if-function work?

I have a form which consists of some elements such as a select-input and a checkbox.
The submit-button is disabled and I want to enable the button only if two conditions are fulfilled. An initial version works well, but only if clicking on the checkbox is the last step. But it should be a function that reacts on both, clicks/changes in the select and the checkbox.
The following code is working but with the problem explained above.
$('#toscheck').click(function() {
if ($(this).is(':checked') && $("#ctry").val().length > 0) {
$('#pjo').removeAttr('disabled');
$('#sjo').removeAttr('disabled');
} else {
$('#pjo').attr('disabled', 'disabled');
$('#sjo').attr('disabled', 'disabled');
}
});
The following solution doesn't work:
$('document').ready(function() {
if ($('#toscheck').is(':checked') && $("#ctry").val().length > 0) {
$('#pjo').removeAttr('disabled');
$('#sjo').removeAttr('disabled');
} else {
$('#pjo').attr('disabled', 'disabled');
$('#sjo').attr('disabled', 'disabled');
}
});
But how can I solve this? What I have found on SO wasn't really helpful.
Again: it should work as following; if the checkbox is selected AND the selected option has a value, the button would be enabled.
Thanks in advance.
First, store you element in variables:
let $toscheck = $('#toscheck'),
$ctry = $("#ctry"),
$pjo = $('#pjo'),
$sjo = $('#sjo');
Then, create your validation function with the stored variables. Note that I replace attr and removeAttr with .prop, it is better:
function checkThings(){
if ($toscheck.is(':checked') && $ctry.val().length > 0) {
$pjo.prop('disabled', false);
$sjo.prop('disabled', false);
} else {
$pjo.prop('disabled', true);
$sjo.prop('disabled', true);
}
}
Then, bind the events:
$toscheck.add($ctry).on( 'change', checkThings );
Note that I used change on both elements since it does work with inputs and checkboxes.
Final code :
let $toscheck = $('#toscheck'),
$ctry = $("#ctry"),
$pjo = $('#pjo'),
$sjo = $('#sjo');
function checkThings(){
if ($toscheck.is(':checked') && $ctry.val().length > 0) {
$pjo.prop('disabled', false);
$sjo.prop('disabled', false);
} else {
$pjo.prop('disabled', true);
$sjo.prop('disabled', true);
}
}
$toscheck.add($ctry).on( 'change', checkThings );
$(document).ready(function() {
$('#toscheck,#ctry').change(function() {
if ($('#toscheck').is(':checked') && $("#ctry").val().length > 0) {
$('#pjo').removeAttr('disabled');
$('#sjo').removeAttr('disabled');
} else {
$('#pjo').attr('disabled', 'disabled');
$('#sjo').attr('disabled', 'disabled');
}
});
});
use this code
.change function detects change and then on call check whether your AND condition is met or not
and add #toscheck in quotes i.e. '#toscheck'
$('#toscheck,#xyz,#abc').change()
for detecting change for multiple elements

jquery clone not working if user select other from the drop down the current text field disabled false

Working on jquery clone with my current code everthing works fine.
first scenario if user select other from the drop down the text
field gets enabled
Second scenario if user click addmore button div gets clone
perfectly with id when user select other both Original and clone
textfield gets enabled actually it should be only the cloned should
get enabled not the enabled
Here is the current Jquery code
var i=1;
$(document).on("click", ".edu_add_button", function () {
var i=$('.cloned-row1').length;
$(".cloned-row1:last").clone(true).insertAfter(".cloned-row1:last").attr({
'id': function(_, id) { return id + i },
'name': function(_, name) { return name + i }
}).end().find('[id]').val('').attr({ 'id': function(_, id) { return id + i }
});
$(".cloned-row1:last").find(".school_Name").attr('disabled', true).val('');
if(i < $('.cloned-row1').length){
$(this).closest(".edu_add_button").removeClass('btn_more edu_add_button').addClass('btn_less btn_less1');
}
i++;
return false;
});
$(document).on('click', ".btn_less1", function (){
var len = $('.cloned-row1').length;
if(len>1){
$(this).closest(".cloned-row1").remove();
}
});
$(document).on('change', '.txt_schName', function (){
var cur = $('.txt_schName').index($(this));
$('.school_Name').eq(cur).val($(this).val())
if ($(this).val() == "other") {
$(".school_Name").prop('disabled', false);
$(".school_Name").val('');
}else{
$(".school_Name").prop('disabled', true);
}
});
$(document).on('change', '.txt_degreName', function (){
var cur = $('.txt_degreName').index($(this));
$('.degree_Description').eq(cur).val($(this).val())
if ($(this).val() == "other") {
$("#degree_Description").prop('disabled', false);
$("#degree_Description").val('');
}else{
$("#degree_Description").prop('disabled', true);
}
});
Here is the fiddle link
Kindly suggest me
thanks & regards
Mahadevan
DEMO
The issue comes be cause you are using class selector directly. You need apply value only to the text box which belongs in the same container. Use closest() to find the parent.
$(document).on('change', '.txt_schName', function (){
var cur = $('.txt_schName').index($(this));
var container = $(this).closest('.container-fluid');
$('.school_Name').eq(cur).val($(this).val())
if ($(this).val() == "other") {
$(".school_Name", container).prop('disabled', false);
$(".school_Name", container).val('');
}else{
$(".school_Name", container).prop('disabled', true);
}
});
DEMO HERE
You need to refer proper element that has to be disabled and enabled.
Take the sibling of select's parent and find the input element to be disabled as below:
$(document).on('change', '.txt_schName', function (){
var cur = $('.txt_schName').index($(this));
$(this).closest('.col-xs-6').next('.col-xs-6').find('.school_Name').eq(cur).val($(this).val())
if ($(this).val() == "other") {
$(this).closest('.col-xs-6').next('.col-xs-6').find(".school_Name").prop('disabled', false);
$(this).closest('.col-xs-6').next('.col-xs-6').find(".school_Name").val('');
}else{
$(this).closest('.col-xs-6').next('.col-xs-6').find(".school_Name").prop('disabled', true);
}
});
From what you did, you actually change every fields with class .school_Name, to achieve what you want you can add $(this).parents(".row").find(".class_name") so it only change the current div.
$(document).on('change', '.txt_schName', function (){
var cur = $('.txt_schName').index($(this));
$('.school_Name').eq(cur).val($(this).val())
if ($(this).val() == "other") {
$(this).parents(".row").find(".school_Name").prop('disabled', false);
$(this).parents(".row").find(".school_Name").val('');
}else{
$(this).parents(".row").find(".school_Name").prop('disabled', true);
}
});
DEMO HERE
You can do it this way with targeting specific item using parent() and next() selector and also i prefer to access specific field instead of index(such as eq) for input.
var schoolObj = $(this).parent().next().find(".school_Name");
schoolObj.val($(this).val());
if ($(this).val() == "other") {
schoolObj.prop('disabled', false);
schoolObj.val('');
} else {
schoolObj.prop('disabled', true);
}
Here is the Fiddle
You can have a look for jquery traversing:
parent: https://api.jquery.com/parent/
Next: https://api.jquery.com/next/
Find: https://api.jquery.com/find/
and for full traversing: https://api.jquery.com/category/traversing/

Keeping a checkbox checked with local storage but also filter a list on load

Alright, this is/was a 2 part question, I originally posted this function:
$(function () {
var data = localStorage.getItem("filter-by");
if (data !== null) {
$("input[name='filters']").attr("checked", "checked");
}
});
$("input[name='filters']").click(function () {
if ($(this).is(":checked")) {
localStorage.setItem("filter-by", $(this).val());
} else {
localStorage.removeItem("filters");
}
});
As the start to my re-checking a checkbox after load using local storage. After some trial and error someone was able to help me write this new function:
$("input[name='filters']").click(function () {
var items = localStorage.getItem("filter-by") || [];
var data = this.data('filter-by');
if ($(this).is(":checked")) {
items.push(data);
} else if (items.indexOf(data) >= 0) {
items.splice(items.indexOf(data), 1);
}
if (items.length > 0) {
localStorage.setItem("filter-by", items);
} else {
localStorage.removeItem("filter-by");
}
});
$(function () {
var items = localStorage.getItem("filter-by") || [];
$("input[name='filters']").each(function(index, input) {
var data = $(input).data('filter-by');
if (items.indexOf(data) >= 0) {
$(input).attr('checked', 'checked');
}
});
});
With this function, I'm able to store which checkboxes were checked, but the list does not filter. How can I go about making the list filter on refresh as well, using either of my functions?
I am using an input that looks like this:
<input type="checkbox" name="filters" data-filter-by="Brand A" ng-click="includeBrand('Brand A')" />Brand A
Thanks for the help guys!
Either you have to trigger the click event or you need to call includeBrand(filterString) function for each of the checked items on page load.

Categories

Resources