I have 3 checkboxes, and I want all combinations of those checkboxes to display a different result, but I cannot work out how to do so. It feels like there's a simple way of doing this that I'm missing.
Here's the Frankenstein monster-code I have so far, which doesn't do what I'd like it to. The aim is that the following code sees that a user has has checked both the "webcam" (#checkWebcam) and "chat" (#checkChat) boxes, and that a different download link is being displayed based on that selection combo...
jQuery('#checkWebcam, #checkChat').change(function() {
var isChecked = jQuery('#checkWebcam, #checkChat').is(':checked');
if(isChecked)
jQuery('div.strip.download').html('Download');
else
jQuery('div.strip.download').html('Download');
});
Could anyone help me with how to actually achieve this aim? Thank you in advance.
This will do an OR operation,
var isChecked = jQuery('#checkWebcam, #checkChat').is(':checked');
what you basically need is to perform an AND opereation here, so use
var isChecked = jQuery('#checkWebcam').is(':checked') && $('#checkChat').is(':checked');
You can try this code :
if ( $("#checkWebcam:checked, #checkChat:checked").length == 2 ) {
//your code
}
var isChecked = jQuery('#checkWebcam, #checkChat').is(':checked'); will return true if either one or both are selected.
Modify your code as
jQuery('#checkWebcam, #checkChat').change(function() {
var boxs = jQuery('#checkWebcam, #checkChat');
var checked = boxs.filter(':checked'); //Filter checked checkboxes
if(boxs.length == checked.length){ //if length are same
alert('both are checked')
}else{
alert('both are not checked')
}
});
DEMO
Related
I wrote a code, that make the button not disabled when you check at least one checkbox with class "sum".
I want to change the code, so I have to classes for and you can check only one checkbox (or two of them) to make the button not disabled.
This is what I have and it works with only one class:
var checkBoxes = $('.sum');
checkBoxes.change(function () {
$('#dashboardbuttonpay').prop('disabled', checkBoxes.filter(':checked').length < 1);
});
$('.sum').change();
});
This is what I tried to do, but OR op does not work:
var checkBoxes = $('.sum' || **'.checkAll'**);
checkBoxes.change(function () {
$('#dashboardbuttonpay').prop('disabled', checkBoxes.filter(':checked').length < 1);
});
$('.sum' || **'.checkAll'**).change();
});
The code works with && operator, but I do not need this.
Using the OR operation on strings this way does not make sense. If you do this with two non-empty strings, you always get the first operand:
console.log('a' || 'b')
In order to select multiple elements, you just separate them by comma:
var checkBoxes = $('.sum, .checkAll');
The code works with && operator, but I do not need this.
Not really. 'a' && 'b' always returns 'b'.
You could check for the amount of checked inputs then add/remove the disabled property in the change event handler.
var checkBoxes = $('.sum','.checkAll');
checkBoxes.change(function () {
if (checkBoxes.filter(':checked').length > 0) {
$('#dashboardbuttonpay').prop('disabled', null);
} else {
$('#dashboardbuttonpay').prop('disabled');
}
});
This way you capture if one or more checkboxes are checked before remove the disabled attribute of the button. Which lets you enable the button with either one or both checkboxes selected.
var checkBoxes = $('.sum','.checkAll');
checkBoxes.change(function () {
if(checkBoxes.filter(':checked').length > 1)
$('#dashboardbuttonpay').prop('disabled',true);
else
$('#dashboardbuttonpay').prop('disabled',false);
});
I was wondering if someone can help me please, I have a series of checkboxes that when clicked change the div background, activate 2 inputs and add a tick icon. My issue is that when one check box is checked the class .TickIco shows for all and so does the .disableToggle
How can i get it so that this only affects one .checkBG at a time and not all of them?
Hopefully this JSFiddle will help explain what I mean.
https://jsfiddle.net/jayjay89/xfg96we5/
thanks
$(".checkBG").click(function () {
var checked = $(this).is(':checked');
var location = $(this).parent().parent().parent();
if (checked) {
$(this).parent().parent().parent().addClass("activeformBlock");
$(".tickIco").show();
$(".disabletoggle").removeAttr("disabled");
} else {
$(this).parent().parent().parent().removeClass("activeformBlock");
$(".tickIco").hide();
$(".disabletoggle").attr('disabled', 'disabled');
}
});
thanks
you can use the context in which the selector will be looked.
You already have the location variable which is the parent context for one of your row
$(".checkBG").click(function () {
var checked = $(this).is(':checked');
var location = $(this).parent().parent().parent();
if (checked) {
$(this,location).parent().parent().parent().addClass("activeformBlock");
$(".tickIco",location).show();
$(".disabletoggle",location).removeAttr("disabled");
} else {
$(this,location).parent().parent().parent().removeClass("activeformBlock");
$(".tickIco",location).hide();
$(".disabletoggle",location).attr('disabled', 'disabled');
}
});
Your issue lies in the way you are selecting the .tickIco and .disabletoggle elements:
$(".tickIco").show();
$(".disabletoggle").removeAttr("disabled");
These jquery calls use selectors that match all classes of .tickIco and .disabletoggle.
Dirty solution (finds elements of the parent with matching classes using .find()):
$(this).parent().parent().parent().find(".tickIco").show();
$(this).parent().parent().parent().find('.disabletoggle').removeAttr("disabled")
Better solution:
jQuery selecter takes the context of your selection as a second argument so you can:
var context = $(this).parent().parent().parent();
$(".tickIco", context).show();
$('.disabletoggle', context).removeAttr("disabled")
Here's the JSFiddle of my work: https://jsfiddle.net/pb23Ljd8/5/
I use Bootstrap nav-pills to show all products and categorized too like this:
And I based my checkboxes from here: http://bootsnipp.com/snippets/featured/fancy-bootstrap-checkboxes
I count the number of products checked in between the tabs like this:
jQuery(document).ready(function($) {
jQuery(".select-product").change(function() {
jQuery(".counter").text(jQuery("[type='checkbox']:checked").length);
});
});
But the glyphicon check icons doesn't appear on the second and third tabs for some reason. But when I click the products on the second and third, it increases the counter and also when I view it on the first tab, it is checked.
I just need the products to also be visibly checked on the second and third tabs and not only on the first one so it's not confusing for the user.
Ideas, anyone?
Edit: I fetch the list of products from CMS so it's dynamic. I now understand that the duplication of IDs is causing the problem.
Before we try and resolve this issues, we should break it down and see what the actual problem is.
First, let's check if we remove the content from tab 1b is the issue still present?
Nope, if we remove the checkboxes from the first tab, the checkboxes function normally on the second and third.
Fiddle #1
What if we change the id of the checkboxes (remember ids should be unique).
Notice how Book #1 now works if we change the first checkbox's id to 1a.
Fiddle #2
So now we "know" the issue is likely due to the fact that we are using checkboxes with the same id value (ref). The "issue" is now:
How do we check multiple checkboxes if one is checked
(or something like that)
Here's what I would do:
assign all "like" checkboxes the same class (ex. Book #1 checkboxes will have class b1)
use jQuery/javascript to make sure all that all "like" checkboxes, check and uncheck in unison
Working Example
EDIT
Dynamic values for the classes can be achieved by putting the IDs as classes so the similar products would match. These can be passed to JS like this assuming that $products_id_array is a PHP array that contains all the classes needed.
var productIDs = <?php echo json_encode($products_id_array) ?>;
and then creating the snippet of jQuery code on the fiddle like this
productIDs.forEach(function(val, key) {
jQuery('.' + val).on('change', function(){
jQuery('.' + val).prop('checked',this.checked);
});
})
Try this JS, This will work
jQuery(".select-product").change(function() {
var checkValue = jQuery(this).prop('checked');
$('.select-product#' + jQuery(this)[0].id).each(function() {
if (checkValue == true) {
jQuery(this).prop('checked', true)
} else {
jQuery(this).prop('checked', false);
}
});
var uniqueId = [];
jQuery("[type='checkbox']:checked").each(function() {
uniqueId.push(jQuery(this)[0].id);
});
Array.prototype.getUnique = function() {
var u = {},
a = [];
for (var i = 0, l = this.length; i < l; ++i) {
if (u.hasOwnProperty(this[i])) {
continue;
}
a.push(this[i]);
u[this[i]] = 1;
}
return a;
}
jQuery(".counter").text(uniqueId.getUnique().length);
});
I am trying to clear a form and then repopulate it with new data. I have a page that has a list of search histories, along with a "search again" button, when clicked, it takes that search history string, split it, then match those again all the various form items; checkbox, radio, etc. The form has basically every kind of form element in it and everything is populating like I want it to except the checkboxes. The first time I click the populate form button, it works fine, but after the first click all the checkboxes start going haywire...some items populating like they should, some not, in a strange random pattern. I have not included the html because I don't think it is necessary but if anyone needs more info, please let me know.
This resets the form. I have tested this independently and it works.
function form_reset(){
$('#hosp_search_form')[0].reset();
$('#hosp_search_form').find("input[type=text], textarea").val("");
$('input[type=checkbox]').each(function(){
$('input[type=checkbox]').removeAttr('checked');
});
$('input[type=number]').val('');
$('input[type=radio]').each(function(){
$(this).removeAttr('checked');
});
On click, first clear the form of previous values, then grab the other needed values and format them...this part gets a little ugly in sections but I have consoled out all the values and everything is how it should be.
$('.search_again_btn').on('click', function(){
form_reset();
$('#hosp_search_form').find('input[type=checkbox]').removeAttr('checked');
var id = $(this).data('id');
var searchstring = $('#searchstring_' + id).text();
var patientcode = $('#patientcode_' + id).text();
var mrn = $('#mrn_' + id).text();
var first_name = patientcode.substr(0,2);
var last_name = patientcode.substr(2,2);
var age = patientcode.substr(4,3);
var gender = patientcode.substr(6,2);
var age = age.replace(/\D+/g, '');
gender = gender.replace(/[0-9]/g, '');
Populates some of the form, works fine
//populate fields in search form
$('input[name=fn]').val(first_name);
$('input[name=ln]').val(last_name);
$('input[name=patientage]').val(age);
$('input[name=mrn]').val(mrn);
Populate another part of the form, also always works as needed
//populate gender fields
if(gender == 'F'){
$('.female').attr('checked', 'checked');
}
if(gender == 'M'){
$('.male').attr('checked', 'checked');
}
Here is where I suspect the issue is. splitsearch is a long string (a previous search history) with items separated by a . and they get split into separate items. I console logged this, it correctly breaking it into the smaller values like I need, then iterate through those and iterate through all the checkboxes which each have a data attr holding values that can be in the splitsearch. If a value matches, it should make it checked. This works every time the first time, for any combo of splitsearch/search string values, but after the first time, I don't know what it is doing. I expect that each click, the form is cleared and it does the value matching again as I described.
//populate checkboxes
var splitsearch = searchstring.split('. ');
$.each(splitsearch, function(key, value){
$('input[type=checkbox').each(function(keyb, checkbox){
item = $(checkbox).data('services');
if(item == value){
$(this).attr('checked', 'checked');
console.log($(this));
}
});
This is doing the same as the above but works every time...probably because there is never multiple combinations like with checkboxes.
$('input[name=payor]').each(function(k, radio){
if(value == $(radio).data('payors')){
$(this).attr('checked', 'checked');
//console.log($(this));
}
});
Also like the above and works.
$('input[name=bedtype]').each(function(keyc, radio){
bed = $(radio).data('bed');
if(bed == value){
$(this).attr('checked', 'checked');
}
});
This part below is quite ugly but is populating the form like I need every time.
//if searchstring contains Needs Transportation, returns true, else returns false
if(value.indexOf("Needs Transportation") > -1 === true){
$('.transyes').attr('checked', 'checked');
}
if(value.indexOf("Near hospital") > -1 != true){
$('input[name=desiredzip]').val(searchstring.substr(5,5));
}
if(value.indexOf("5 mile radius") > -1 === true){
$('.miles_5').attr('checked', 'checked');
}
if(value.indexOf("10 mile radius") > -1 === true){
$('.miles_10').attr('checked', 'checked');
}
if(value.indexOf("15 mile radius") > -1 === true){
$('.miles_15').attr('checked', 'checked');
}
if(value.indexOf("20 mile radius") > -1 === true){
$('.miles_20').attr('checked', 'checked');
}
});
Scrolls the window up to the populated search form and show it.
window.scrollTo(0,100);
$('#search_show').show();
});
Just a thought but, it might help you to restructure your code a bit to keep it DRY.
// used to Hold search data in local or global
var data;
function form_reset() {
// clear form
}
function get_search_data() {
// populate data with search results
}
function form_populate() {
// use data to populate form
}
$('.search_again_btn').on('click', function(){
get_search_data();
form_reset();
form_populate();
});
// Initial Load of form
get_search_data();
form_populate();
that way you use the same population function initially as you do when you refresh and it forces you to put your data into a variable that can be seen in both the clear and populate functions removing your reliance on this and $(this).
also you need to bear in mind that the value of this inside a click function is going to be in the context of the click event itself and not the JavaScript object that the rest of your code belongs to.
I am developing a javascript filtering of some results and have some difficulties..
Here is the problem...
Suppose that we have some criteria
Manufacter (Trusardi, Calvin Kein, Armani...)
Color (red, blue, black...)
OtherFeatures (goretex, blah, blah...)
Each feature is displayed as a checkbox...
The problem is that i want to disable the checkboxes if its selection would lead to no results..For example Armani's products may have color blue only so checking armani should disable the black and red,but other manufactors shouldnt be disabled... as checking them should provide a result...
Here is the code so far
results = $("#products li");
results.hide();
var filtersGroup = $("#filters li.filtersGroup");
$("#filters li.filtersGroup a").removeClass("disabled");
filtersGroup.each(function(index) {
var classes = "";
$(this).find("a.checked").each(function(index) {
classes = classes + "." + $(this).attr("id") + ",";
});
if (classes == "") return true;
results = results.filter(classes.substr(0, classes.length - 1));
//periorismos
filtersGroup.not($(this)).each(function(index) {
$(this).find("a").each(function(index) {
if (results.filter("." + $(this).attr("id")).length <= 0) {
$(this).removeClass("checked").addClass("disabled");
}
});
});
});
Although it filters them successfully ,the disabling isnt always correct. for example to reproduce the problem ,if you choose all the manufactors and then choose a color manufactors would be disabled but colors not at the first time..
One solution i figured is to create multiple results which would simulate all the next possible check.(if 16 features and 4 checked means 12 possible other checked ..
But i think that this approach sucks... Any other idea?
You could add a class for each manufacturer, colour, etc. then simply disable by class. I assume here there's a results hash keyed off manufacturer:
results['Trusardi'] = 5
results['Armani' = 0
..then:
$("#filters li.filtersGroup a").addClass("disabled");
foreach (m in manufacturers) {
if (manufacturers[m] > 0) {
$("#filters li.filtersGroup a." + m).removeClass("disabled");
}
}
etc.
You have a faceted search problem - where many combinations produce no results. Instead of disabling, I suggest calculating and showing how many results results would appear if a given criterion is selected. Then with each click, executing that algorithm again. So your search would like very similar to newegg.com:
http://www.newegg.com/Store/SubCategory.aspx?SubCategory=10&name=Desktop-PCs
Depending on how much data you're dealing with you might want to consider using solr.
I think that i found the solution.. It was simpler than i thought... I was trying to find a solution all day long and it was simpler than i thought..
Here it is....
results=$("#products li");
results.hide();
var groupClasses=[];
var groupsChecked=0;
var filtersGroup=$("#filters li.filtersGroup");
$("#filters li.filtersGroup a").removeClass("disabled");
filtersGroup.each(function(index) {
var classes="";
$(this).find("a.checked").each(function(index) {
classes=classes+ "." + $(this).attr("id") +",";
});
groupClasses[groupClasses.length]=classes;
if(classes=="") return true;
groupsChecked++;
results=results.filter(classes.substr(0,classes.length-1));
});
//disable
var gi=0;
filtersGroup.each(function(index) {
if( ! (groupsChecked<=1 && groupClasses[gi]!=""))
{
$(this).find("a").not(".checked").each(function(){
if (results.filter("." + $(this).attr("id")).length <= 0) {
$(this).removeClass("checked").addClass("disabled");
}
});
}
gi++;
});
It seems to be correct. I amnot sure though but testing it seems ok..
Can't you just compute the results for every unchecked option and compare them to the current products that suffice. (I'm not very familiar with jQuery so I wouldn't know how...)