Validating checkboxes via multiple arrays? - javascript

I'm running into a bit of a problem on a site I'm trying to build. On one side of the site there is a 'filter' that allows users to check boxes in a list which will effect the results of their searches. I'm a newbie to jQuery but I've managed to piece together enough code to make this work... mostly
Here's the code I have so far:
/// Makes checkboxes in the filter add and remove the proper class based on whether they're checked or not
$('.filterlist input:checkbox').click(function checkboxes(){
$thislist = $(this).closest('.filterlist li > ul');
$checkboxes = $thislist.closest('li > input:checkbox').serializeArray();
if($checkboxes.length < 1) {
$(this).closest('ul.filterlist > li').removeClass('itemselected');
}
else if($checkboxes.length > 0) {
$(this).closest('ul.filterlist > li').addClass('itemselected');
}
});
In my css 'itemselected' is the class I'm trying to add. The problem is that I have more than one list of checkboxes under '.filterlist'. As I check the checkboxes in the first list it adds the class properly, and if I remove all of the ones in that list it removes the class properly - unless there are any checked in the second list.
This is because I'm only using one Array, but I can't figure out how to make it create a different array for each of the lists such that even if some are checked in the first list it will still remove the class from the li in the second list if none are checked there, or vice versa.
Sorry this is such a long question, I was trying to be specific.
Thanks ahead of time for any answers! =]

something like this??
$(document).ready(function(){
$('ul.filterlist input:checkbox').click(function () {
var ul = $(this).parent().parent();
if ( ul.find("input:checked").length == 0 ) {
ul.parent().removeClass('itemselected');
} else {
ul.parent().addClass('itemselected');
}
});
});

Related

Create a function to hide divs

I want to display tables when a selection is made in a form and a 'Generate Factsheet' button is clicked. I've got a working code where I individually hide other divs when displaying the one I am interested in. Since I have several options in the form (and hence several corresponding divs in which the respective tables are enclosed), the final code appears bulky. I want to write a function to hide other divs whiles displaying the one I am interested in. This is the code I currently have:
var tableDivs = ['tableOPVDiv','tablePneumoDiv','tableRotaDiv'];
var selectedVaccine;
var selectedTableDiv;
function generateFactsheetFunction(){
// Selecting the vaccine chosen from the dropdown
var e = document.getElementById("selectVaccine");
selectedVaccine = e.options[e.selectedIndex].text;
console.log("selectedVaccine: ", selectedVaccine);
if (selectedVaccine=="Rotavirus Vaccine"){
selectedTableDiv='tableRotaDiv';
console.log("rotavirus selected");
hideOtherTables();
} else if (selectedVaccine=="Polio Vaccine"){
console.log("polio selected");
selectedTableDiv='tableOPVDiv';
hideOtherTables();
} else if (selectedVaccine=="Pneumococcal Vaccine"){
console.log("pneumo selected");
selectedTableDiv='tablePneumoDiv';
hideOtherTables();
}
}
function hideOtherTables(){
var testa = tableDivs.indexOf(selectedTableDiv);
console.log("tableDivs[testa]: ", tableDivs[testa]);
console.log("testa: ", testa);
testb = tableDivs[testa];
console.log("testb: ", testb);
document.getElementById(tableDivs[testa]).style.display="block";
/*var newTableDivs=tableDivs.splice(testa);*/
/*for (y=0;y<newTableDivs.length;y++){
document.getElementById(newTableDivs[y]).style.display="none";
}*/
}
The uncommented part works fine. In the commented part, I want to say that for all array elements other than selectedVaccine, I want the display to be:
document.getElementById(tableDivs[testa]).style.display="none";
I cannot splice the data because the selections are repititive (the selections are from a form). What is the way to set the visibility of tableDivs associated with other selections to be none.
Why should you change the display property of each and every division seperately? give a common class name to all the divisions and hide them all at once and then display only the required table.
$(".yourClass").hide();
document.getElementById(tableDivs[testa]).style.display="block";
You will have to use the jQuery Library too.
If you are not familiar with jQuery then use the for loop to hide all the tables first and then display only the required table.
for (y=0;y<TableDivs.length;y++){//you need not create newTableDivs
document.getElementById(TableDivs[y]).style.display="none";
}
document.getElementById(tableDivs[testa]).style.display="block";
i.e you just have to interchange the order of execution. ;)
Cannot read property 'style' of null this means that document.getElementById(tableDivs[y]) return null and can not find this element
try to write
document.getElementById("ElementId")

Strange behavior to searchable JQuery Connected Sortable. Need fix

I am using a connected sortable that saves wonderfully via asp.net back-end on a button click. Additional features include the ability to search each of the lists. This works well until you do the drop and drag of an item from one list to another. When I do the search of the one list using JavaScript to search items in the one list, it still thinks that it is a part of the first list. Has anyone seen this behavior? and do you know of a possible fix to make item permanently part of the said dragged upon list within the DOM. This behavior is in FF, IE, Chrome, etc.
Now I do have buttons on this list that move items from one list to the other based on them being selected then button clicked, it is then a part of the second list using JQuery append();. This makes the item a permanent part of the second list's DOM and is able to be searched upon within that list.
So here is my "Ah-Ha" moment. It was doing what it was supposed to do looking for the item and showing it and if it was not the item it wouldn't show it. however when the item moved to the other column using sortable it still had the same class as the first column. I needed to make that switch.
The answer is here as follows...
http://jsfiddle.net/6jmLvysj/
$(input)
.change(function () {
var filter = $(this).val();
if (filter) {
//here is my DAH moment it is looking for this class so when the user was typing in the first search input it was looking for item it would be searching for it is the second column--give myself a Gib slap--
$(list).find(".ui-state-default:not(:Contains(" + filter + "))").hide();
$(list).find("ui-state-default:Contains(" + filter + ")").show();
} else {
$(list).find(".ui-state-default").show();
}
return false;
})
.keyup(function () {
$(this).change();
});
then this
//so here is where I changed this code when the user brings the item over then it changes it to the proper respected class depending where the user drops it so it can be searched.
stop: function (event, ui) {
if (ui.item.hasClass("ui-state-default")) {
ui.item.attr('class', 'ui-state-highlight');
}
else {
ui.item.attr('class', 'ui-state-default');
}

How do I count the number of select lists with selected values using JQuery?

I am creating the mobile version on a current Rails app with a "quiz" feature. There is currently a count of how many questions you have answered being generated by this function.
function updateGroupProgressCounter($group){
var count = $group.find('tr').has('input:checked').length;
$group.parents('.carousel').find('.checkedCount').text( count);
}
I am changing the inputs from radio buttons to select boxes for mobile and want to keep the count feature but can't quite make it work so far. I've tried
var count = $group.find('tr').has('select option:selected').length;
but gives me the total number of questions in that group. Any help is appreciated.
I would toggle a class on the row based on select change event, then count those rows.
$('tr select').change(function(){
$(this).closest('tr').toggleClass('answered', $(this).val()!='' );
});
Second argument of toggleClass determines whether to add/remove.
Then to get total rows:
$('tr.answered').length
toggleClass() API Docs
Another approach using filter() to count select that have value
var number_answered=$('tr select').filter(function(){
return $(this).val !='';
}).length
Probably you are looking for something like this:
$("#boxes").on("change","input", function(){
$("#total").val($("#boxes input:checked").length);
});
Play around with the fiddle
Considering the value of first element of your select list is empty(i.e "")
So the code will be
var count = 0;
$group.find('tr select').each(function(){
if(this.value.length)
count++;
});
I know this is not the best way to do it.
Adding and removing class on the basis of selection and finally finding the length of element that contains required class would be better approach as suggested by #charlietfl.

stuck building a 'cart management' system

I'm trying to build a database for video spots. The main page is a list of spots and you can check them and modify them. What i want to do is build a cart system, where the checked spots' id's are automatically added to the cart and stored as a cookie. That way the use can browse multiple pages while still having everything stay checked.
So far, I have a checkbox on every spot that when checked calls a function that adds the id of the checkbox to an array and stores it as a cookie.
I'm able to retrieve the cookie through jquery. What I need to do is while looping through the spots and printing them, is to check if that spot id is in the cookie, so I can set it as checked or not through php. Is this possible? Is there a better way to accomplish this?
Here is what i have so far.
$(document).ready(function(){
var checkedItems = [];
$('.spotCheck').click(function(){
var currentID = this.id;
checkedItems.push(currentID);
updateCookie();
});
function updateCookie(){
$.cookie('itemList',checkedItems);
}
$('#mainContainer').click(function(){
$('#textInCenter').html($.cookie('itemList') );
});
});
Clicking the checkbox adds the ID to the array checkedItems, and click the mainContainer makes it visible so I can see which items are currently in the array. I can browse through pages and the cookies stay in the array (there's no way to remove them now but I'm not worried about that right now).
So how can I check the array to see if an id is in there when I print the list of spots?
Based on what you're looking for I think that this would work for you:
for (var i = 0; i < checkedItems.length; i++)
{
var elm = $('#' + checkedItems[i]);
if (elm.length > 0)
{
//element with the id exists.
elm.attr('checked', true);
}
}

jQuery Custom Validators

I'm using the jQuery validation plugin and I'm looking to add some custom logic. I have a series of checkboxes which have children checkboxes associated with them. For certain (not all) of these parent checkboxes, I want to require that one of the children checkboxes is checked. I have no issue hardcoding for this so I was adding a field like this to my DOM:
<input type="hidden" id="child_required_1" class="child_required_1" />
And then adding a custom validator like this:
jQuery.validator.addMethod('child_required_1', function(val, element) {
if($('#product_responses_1').length > 0) {
if($('#product_responses_1').is(':checked')) {
var count = $("input:checkbox:checked[id^='children_tags_1_']").length;
if(count == 0) {
return false;
}
}
}
return true;
}, 'You must select at least one child.');
This works perfectly fine. But when I duplicate all of this and add "_2", only one of the validators seems to fire. So from what I can gather, custom validators are unique per form? If that's the case, how am I supposed to handle a situation like this where I may need 15-20 of these all showing in different places? I don't want to just show one error.
I could also create a class rule but that doesn't solve my problem of creating multiple error labels and placing them in the relevant positions.
Apparently having it on a hidden field didn't work, but when I removed the hidden fields and applied that class to the actual checkboxes themselves, it worked fine. Not entirely sure why.

Categories

Resources