jQuery: Grouping Similar Items
Using jQuery, I'm trying to group similar items in a list. Here's what I'm trying to do. Given a list like the following开发者_运维技巧:
<ul>
<li class="foo">Item #1</li>
<li class="foo">Item #2</li>
<li class="foo">Item #3</li>
<li class="bar">Item #4</li>
<li class="bar">Item #5</li>
<li class="foo">Item #6</li>
<li class="foo">Item #7</li>
<li class="bar">Item #8</li>
</ul>
I'd like to end up with the following:
<ul>
<li class="foo">Item #1 <a>2 More Like This</a>
<ul>
<li class="foo">Item #2</li>
<li class="foo">Item #3</li>
</ul>
</li>
<li class="bar">Item #4</li>
<li class="bar">Item #5</li>
<li class="foo">Item #6 <a>1 More Like This</a>
<ul>
<li class="foo">Item #7</li>
</ul>
</li>
<li class="bar">Item #8</li>
</ul>
In short, anytime there's 2 or more items with class="foo", they should be grouped together up until reaching a non-class="foo" item. I can then use a link to show or hide the grouped items.
Here's one possibility:
Example: http://jsbin.com/ipiki3/3/
$('ul > li.foo')
.filter(function() {
var $th = $(this);
return $th.next('li.foo').length && !$th.prev('li.foo').length;
})
.each(function() {
var $th = $(this);
var len= $th.append('<a href="#"> more like this</a>')
.nextUntil(':not(li.foo)').wrapAll('<ul>').length;
$th.next('ul').appendTo(this);
$th.children('a').prepend(len);
});
EDIT: Fixed a mistake with the len
variable, and added an example.
Explanation: What's happening with the .filter()
is that it is narrowing the li.foo
elements down to the first in a group (has at least one li.foo
after it, and none before).
Then with the .each()
it appends the <a>
, get's the next elements until it reaches one that is not li.foo
, wraps those with a <ul>
and returns how many there were using the length
property.
Then we traverse over to that new <ul>
and append it to the first li.foo
in the group.
Finally we prepend the quantity we stored in the length
property to the <a>
element.
I come up with this:
$(document).ready(function() {
var groups = {}
$('ul li').each(function() {
var self = $(this);
var class_name = self.attr('class');
if (class_name) {
if (typeof groups[class_name] == 'undefined') {
groups[class_name] = [];
}
groups[class_name].push(self);
}
});
var ul = $('ul');
ul.empty();
for (var class_name in groups) {
var array = groups[class_name];
ul.append('<li class="' + class_name + '">' + $(array[0]).html() +
'<a>More Like this</a><ul></ul>');
$(array.splice(1)).each(function() {
ul.find('li.' + class_name + ' ul').append(this);
});
}
});
精彩评论