rjdevereux
rjdevereux

Reputation: 1892

jQuery Loop with cumulative logic?

How do you loop through the results from a children() or each() call in jQuery when you want to work with some cumulative result? For example sum up numbers in checkboxes and change a class if they get over 100%. All the example seem to only perform logic that is independent for each iteration.

I'm looking for the javascript/jquery equiv of this c#

var x = new List<int> { 1, 2, 3 };
Console.WriteLine(x.All(y => y > 0));

This is what I have now, but it seems like there should be something cleaner.

var count = 0;
$(this).parent().children().each(
    function () {
        if ($(this).hasClass("selected")) {
            count++;
        }
    }
);

if ($(this).parent().children().length == count) {
    $(this).parent().parent().toggleClass("selected");
}
else {
    $(this).parent().parent().removeClass("selected");
}

Upvotes: 1

Views: 669

Answers (4)

Eric
Eric

Reputation: 97571

Aside from the obvious iterate and sum approach, you can use the newer javascript iteration functions. Assuming you want so sum some numbers:

var sum = objects
    //convert to jquery selection of numbers
    .map(function() {return +$(this).val(); })
    //convert to javascript array
    .get() 
    //add together
    .reduce(function(a, b) { return a + b; });

For your example:

var checkboxes = $(this).parent().children()
var allSelected = checkboxes.map(function () {
    return $(this).hasClass("selected");
}).get().every(function(x) { return x; });

You can go one stage better by extending jQuery

$.fn.every = function(f) {
    return [].every.call(this, function(x) {
        return f.call(x);
    });
}

Leaving you with:

var checkboxes = $(this).parent().children()
var allSelected = checkboxes.every(function() {
    return $(this).hasClass("selected");
});

Upvotes: 2

kojiro
kojiro

Reputation: 77089

Unlike the linear array operations map and filter, jQuery doesn't have a polyfill for it, but I think what you're looking for is Array.reduce. It is well-supported in newer browsers.

You can implement the javascript you have there using the boolean toggleClass syntax.

var count = $(this).parent().children(".selected").length;
$(this).parent().parent().toggleClass("selected",
    $(this).parent().children().length === count);

Upvotes: 1

Gareth Parker
Gareth Parker

Reputation: 5062

It's not that hard. I'm not sure if this will work 100%, but it'll show you how to do cumulative logic

var score = 0;
$("#checkboxDivId input[type=checkbox]:checked").each(function()
{
    score += $(this).val();
});
if(score >= 100)
{
    //Put your code here
}

Obviously this would only work if your score is the value property of the checkbox, and if the selector is correct (not 100% sure on whether or not the selector is correct)

Upvotes: 0

Cranio
Cranio

Reputation: 9847

Well, Javascript/Jquery are not SQL, there is no defined concept of "cumulative"/groupwise operations. Also, "cumulative logic" is a rather vague term, it really depends on the particular task you want to perform.

So, your sum example can be adapted for each() with the help of an external variable, for input/text tags it would be:

var sum = 0;
var objects = $("input.myclass");
objects.each(function() {sum+=Number($(this).val());});
if (sum>100) objects.addClass("anotherclass");

For checkboxes: I'm not sure what you mean by "sum numbers in checkboxes", do you mean the values?

Upvotes: 3

Related Questions