1

I have a input checkbox that act as a category filter. I want to store only those values of input checkboxes in an array that are checked in a var checkedAttr. Then do a test if any of the already existing values match any in the array and if it does delete it. The problem I'm having is that... when an input checkbox is clicked, it will store it as many times as the $each loop goes or input checkboxes there are, in this case (three times). I also noticed when unchecking more than one, then rechecking the same one, it will add the values as many times as the $each loop goes and will somehow bypass deleting from the array. I just want to simply add (checked values) / delete (unchecked values) from the array every time the user checks or unchecks.

Here's a jsfiddle.

HTML:

<div id="category-list">
     <h1>Categories</h1>
     <input class="categories" type="checkbox" name="filter" value="Math" checked>Math<br/>
     <input class="categories" type="checkbox" name="filter" value="Science" checked>Science<br/>
     <input class="categories" type="checkbox" name="filter" value="Reading" checked>Reading
</div>

jQuery:

var checkedAttr = []; // array for checked attributes
// change event listener for whenever one or more of the following checkboxes have been checked/unchecked
$('#category-list :checkbox').change(function() 
{
    var value = $(this).val();
    if($(this).is(':checked')) // checked
    {
        console.log(value + ' is now checked!!!!!!!!!!!!!!!!!!!!!!!!');

        $('#category-list :checkbox').each(function(i, item){ // loop thru the input checkboxes
            if(!(value === $(item).val())) // check if the current value does NOT match that already stored in array
            {
                checkedAttr.push(value); // add value to array
                console.log("checkedAttr:", checkedAttr);
            }
            else // if it does match...
            {
                checkedAttr.splice(i, 1);// remove it from array  
                console.log("checkedAttr:", checkedAttr);
            }
        });

        // check which attributes are checked and store in 'checkedAttr' array
        //$('input[name=filter]').each(function(i, item){

        //});
    } 
    else // unchecked
    {
        console.log(value + ' is now unchecked!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
    }
});

5 Answers 5

1

Check it Brother its working as you want

var checkedAttr = [];

$('#category-list :checkbox').change(function() 
{
    checkedAttr = [];
    $('#category-list :checkbox').each(function(i, item){
        if($(item).is(':checked'))
        {
            checkedAttr.push($(item).val()); 
        }
    });
   console.log("checkedAttr:", checkedAttr);
});

You can also check it in JSFiddle

https://jsfiddle.net/xdrLra77/

Sign up to request clarification or add additional context in comments.

2 Comments

Works Perfectly! Thank you!
Redundance of loop each time the checkbox change. Just make one on the beginning and continue just with validations
1

You can do it simply with a mapcall

var checkedAttr = [];
    
$('#category-list :checkbox').change(function() {
    checkedAttr = $('#category-list :checked').map(function(){
        return $(this).val();
    }).get();
    
    console.log(checkedAttr);
});

(Updated jFiddle)

(Edit: better yet, put the condition in the jQuery selector)

7 Comments

Actually, don't use a conditional return, you should always return a value, true or false.
@Mottie by returning false won't the false value end up in the resulting array?
Yes, but what good is the resulting array if you can't tell what the second true is in regard to?
@Mottie which second true? I did a jFiddle with what I understand is OP's intended functionality.
@TheAmazingKnight Sure. First, map is not a jQuery thing, it's commonly implemented in most languages, and is typical within the functional programming paradigm. In its typical form, it takes as arguments an array (or some iterable) and a function. It then applies the function to each element of the array, generating a new array with the result of the operation on each element. Here, the operation is just extracting the val(), and the collection on which we operate is the selection of checked checkboxes.
|
1

Edited

var checkedAttr = []; // array for checked attributes

//first load, see what is checked
$('#category-list :checkbox').each(function(){
 if($(this).is(':checked')) // checked
 checkedAttr.push($(this).val())
})


// change event listener for whenever one or more of the following     checkboxes have been checked/unchecked
$('#category-list :checkbox').change(function() 
{
var value = $(this).val();
var position = checkedAttr.indexOf($(this).val());

if($(this).is(':checked')) // checked
{
    if(position == -1){ // dnot exist in array, add
        checkedAttr.push($(this).val());
      console.log("checkedAttr:", checkedAttr);
    }else{ // exist in array, do nothing
        //do nothing
   }
   console.log(value + ' is now checked!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
} 
else // unchecked
{
    if(position == -1){ // dont exist in array, do nothing
        //do nothing
    }else{ // exist in array, remove
        checkedAttr.splice(position,1);
        console.log("checkedAttr:", checkedAttr);
    }

    console.log(value + ' is now unchecked!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
}
});

2 Comments

This works, but on initial load, checkedAttr is empty then stores values after checking them all.
@TheAmazingKnight edited, only one extra loop in the beginning
0

You can get the checked elements by using $('.categories:checked'). Then you may iterate through those values to get the actual values

var checkedValues= $('.categories:checked');

var valuesArray=[];
$.each(checkedValues, function(checkedValue){
valuesArray.push(checkedValue.value)
}

2 Comments

Why give an answer that uses underscore when the question isn't tagged with it?
My bad. Its very similar to jQuery anyways. Updated my answer
0

Use $.inArray:

if (index === -1  && $(this).is(':checked')) {

    checkedAttr.push(value); // add value to array
    console.log("added:", checkedAttr);

 } else if (index !== -1 && ! $(this).is(':checked')) {

    checkedAttr.splice(index, 1);// remove it from array                
    console.log("removed:", checkedAttr);

}

Amended fiddle: https://jsfiddle.net/o1rmz1o1/4/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.