Gary
Gary

Reputation: 41

jQuery programmatically find AND count css classes on results?

I have a page of database results as list items, each result having between none and several possible css classes dynamically assigned (but not known), for filtering purposes.

Using jQuery how do I programatically find what classes are assigned to each li, AND count the frequency of each class appearance on the page?

I need to be able to access them by the name of the css class, to update html on the page.

Ex html

    <ul class="results">
      <li class="a b c d>...</li>
      <li class="a c>...</li>
      <li class="b c f>...</li>
      <!— many more li —>
    </ul>

The target output is: option a 2 option b 2 option c 3 option d 1 option e 0 option f 1 ...

Where 'option a' is a filter already on the page, and the count would appear beside it. I have the filter ready to accept the html update:

echo ' <span class="' . $row_rsCategories['category'] . '"></span>';

Where the category is the name of the filter.

Upvotes: 0

Views: 208

Answers (4)

David Thomas
David Thomas

Reputation: 253506

A simple approach:

function classCount(el, prefix){
    // define the prefix, with a default in case a prefix is not supplied:
    prefix = prefix || '';

    /* use the passed-in selector to find the relevant element(s) (with a class)
       to search within:
    */
    var els = $(el).find('[class]'),
        // initialise variables to avoid declaring them within a loop:
        results = {},
        classes = [];

    // iterate over the elements found earlier
    els.each(function(){
        // find the classes of the element:
        classes = this.className.split(/\s+/);

        iterate over those classes:
        for (var i = 0, len = classes.length; i < len; i++){
            /* if there isn't a current property in the results object
               for the current class-name, create and initialise it:
            */
            if (!results[classes[i]]) {
                results[prefix + classes[i]] = 1;
            }
            // if it already exists, increment it:
            else {
                results[prefix + classes[i]]++;
            }
        }
    });

    // return the resulting object to the calling context:
    return results;
}

console.log(classCount('.results', 'option '));

JS Fiddle demo.

Upvotes: 0

codingrose
codingrose

Reputation: 15709

Try this:

var li = [];
var cnt = [];
$(".results").find("li").each(function () {
    var cls = $(this).attr("class").split(" ");

    var len = cls.length;
    for (var i = 0; i < len; i++) {
        if (li.indexOf(cls[i]) < 0) {
            li.push(cls[i]);
            cnt.push(1);
        } else {
            cnt[li.indexOf(cls[i])] = cnt[li.indexOf(cls[i])] + 1;
        }
    }
});

Fiddle here.

Upvotes: 1

megawac
megawac

Reputation: 11383

This will create an object, classes, that contains a count of all classes applied to each list item.

var classes = {}; //{a: 2, b: 2, c: 3, d: 1, : 1, f: 1} 
$(".results li").each(function() {
   $.each(this.className.split(" "), function(i, cls) {
       classes[cls] = classes[cls] + 1 || 1;
   });
});

JSFiddle example

Upvotes: 1

tymeJV
tymeJV

Reputation: 104795

Something like:

var classObject = {}
$("ul.results li").each(function() {
    var classes = this.className.split(" ");
    for (var i = 0; i < classes.length; i++) {
        if (classObject.hasOwnProperty(classes[i]))
            classObject[classes[i]]++;
        else
            classObject[classes[i]] = 1;
    }
});

Demo: http://jsfiddle.net/3FN7U/

Upvotes: 0

Related Questions