im_benton
im_benton

Reputation: 2621

Count sibling elements that all have same unknown class name

I need help working with a large list of sibling elements with different class names.

  1. Getting the amount of elements with the same class name and putting them in an array
  2. Finding first element in that class group (this can be number or name).
  3. Statement that runs a function: if element = first element of group do console.log("first element");

Here's an example of the first 3 classes but this will go from groupA to Groupz

<div class = 'slider'>
    <div class = 'item1 groupA'> <!-- Start Group A -->
        <img  src='xyz'  />
    </div>
    <div class = 'item1 groupA'>
        <img  src='xyz'  />
    </div>                  
    <div class = 'item1 groupA'>
        <img  src='xyz'  />
    </div>                  
    <div class = 'item1 groupA'>
        <img  src='xyz'  />
    </div>
    <div class = 'item1 groupB'> <!-- Start Group B -->
        <img  src='xyz'  />
    </div>
    <div class = 'item1 groupB'>
        <img  src='xyz'  />
    </div>                  
    <div class = 'item1 groupB'>
        <img  src='xyz'  />
    </div>                  
    <div class = 'item1 groupC'> <!-- Start Group C -->
        <img  src='xyz'  />
    </div>          
    <div class = 'item1 groupC'>
        <img  src='xyz'  />
    </div> <!-- All the way to group Z -->
</div>

Upvotes: 2

Views: 1668

Answers (4)

Lix
Lix

Reputation: 47976

Ok, so this solution is quite sensitive. I'm making a few assumptions about your HTML.

In your example you gave each item a class of item1. I am assuming that this is just an issue of copying and pasting the element. Each "item" should have the same class so that you can retrieve all the items with one selector. For my example, I'm assuming a class of item.

There should be only this item class plus an additional "group" class. Any other class given to the item will render this solution invalid.

// fetch ALL items
var allItems = $(".item");

// initialize groups array
var groups = {};

$.each(allItems,function(index,elem){
  var item = $(this);
  var itemClass = item.attr('class');

  // remove the "item" class and any leftover whitespace
  itemClass = $.trim(itemClass.replace('item','')); // should now be groupA/groupB...

  // add item to array at the index of the group
  if (groups[itemClass] == undefined){
    groups[itemClass] = [];
  }

  groups[itemClass].push(item);
});

You should now be left with an array of arrays containing all the items. To see this in action, you can check out this jsFiddle.

Upvotes: 0

Bergi
Bergi

Reputation: 664548

var groups = {};
$(".slider").children().each(function(i, el) {
    var classes = el.className.split(/\s+/);
    for (var i=0; i<classes.length; i++)
        if (classes[i] in groups)
            groups[classes[i]].push(el);
        else
            groups[classes[i]] = [el];
});

Now, you can access all elements of a group via groups["groupA"] etc (jQuery collection: $(groups["groupB"])) and the first one via groups["groupC"][0]. The amount of elements in a group is just the length of the array.

Notice that this puts all elements in the group "item1" - I don't know what you need that class for.

Upvotes: 0

Selvakumar Arumugam
Selvakumar Arumugam

Reputation: 79830

Edit: Your requirement is very specific. Below is just a sample to just loop thru all childrens and store the count and first element in the matching count. Let me

$(function () {
    $.fn.benton = function () {
        //just the immediate childrens
        var $chds = $(this).children();

        var lc = {
            firstEl: {},
            classCount: {}
        };

        $.each ($chds, function (idx, el) {
            if (el.className) {
               var tokens = el.className.split(' ');
               for (var i = 0; i < tokens.length; i++) {
                   if (lc.classCount.hasOwnProperty(tokens[i])) {
                       lc.classCount[tokens[i]] += 1;
                   } else {
                       lc.classCount[tokens[i]] = 1;
                       lc.firstEl[tokens[i]] = $(el);
                   }
               }
            }
        });

        return lc;                   
    };

    var stats = $('.slider').benton();
    console.log(stats.classCount['groupA']);
    stats.firstEl['item1'].css({border: '1px solid red', width: 100, height: 10});
});

DEMO: http://jsfiddle.net/LhwQ4/1/


I think what you need is to use context of slider to get the child elements.. see below,

var $slider = $('.slider') 

Now using the $slider context,

$('.groupA', $slider)
//Returns Array of jQuery object with elements has class `groupA`

$('.groupA:first', $slider)
//Returns first element in collection of element with class `groupA`

Upvotes: 3

Lix
Lix

Reputation: 47976

To get all elements with the same class name, you would only have to use a simple jQuery selector. The returned value is an array containing all matching elements.

var groupA = $(".groupA");

To get the number of items you need only access the length parameter of the array.

var groupALength = groupA.length;

If you want to extract only the first element of any matched elements, you can use jQuery's :first selector.

var firstElement = $(".groupA:first");

Upvotes: 1

Related Questions