I have some HTML that looks like this:
<p>Some Text</p>
<div class="listBullet">Item 1</div>
<div class="listBullet">Item 2</div>
<div class="listBullet">Item 3</div>
<p>Some More Text</p>
<div class="listBullet">Item 1</div>
<div class="listBullet">Item 2</div>
<div class="listBullet">Item 3</div>
<p>Some Other Text</p>
I want to end up with the following output:
<p>Some Text</p>
<div class="wrapperDiv">
<div class="listBullet">Item 1</div>
<div class="listBullet">Item 2</div>
<div class="listBullet">Item 3</div>
</div>
<p>Some More Text</p>
<div class="wrapperDiv">
<div class="listBullet">Item 1</div>
<div class="listBullet">Item 2</div>
<div class="listBullet">Item 3</div>
</div>
<p>Some Other Text</p>
I tried $(".listBullet").wrapAll("<div class='wrapperDiv' />")
, but that ended up moving the two blocks to be contiguous with each other. It seems like what I need is a selector that separates the contiguous blocks into separate elements, which I would then call wrapAll on separately.
I have some HTML that looks like this:
<p>Some Text</p>
<div class="listBullet">Item 1</div>
<div class="listBullet">Item 2</div>
<div class="listBullet">Item 3</div>
<p>Some More Text</p>
<div class="listBullet">Item 1</div>
<div class="listBullet">Item 2</div>
<div class="listBullet">Item 3</div>
<p>Some Other Text</p>
I want to end up with the following output:
<p>Some Text</p>
<div class="wrapperDiv">
<div class="listBullet">Item 1</div>
<div class="listBullet">Item 2</div>
<div class="listBullet">Item 3</div>
</div>
<p>Some More Text</p>
<div class="wrapperDiv">
<div class="listBullet">Item 1</div>
<div class="listBullet">Item 2</div>
<div class="listBullet">Item 3</div>
</div>
<p>Some Other Text</p>
I tried $(".listBullet").wrapAll("<div class='wrapperDiv' />")
, but that ended up moving the two blocks to be contiguous with each other. It seems like what I need is a selector that separates the contiguous blocks into separate elements, which I would then call wrapAll on separately.
4 Answers
Reset to default 14This does the job:
$('p + .listBullet').each(function() {
$(this).nextUntil('p')
.addBack()
.wrapAll("<div class='wrapperDiv' />");
});
Fiddle 1
If your XHTML has a mix of elements, you can do this (assuming
container
is the class of the parent div
):
$('.container > :not(.listBullet) + .listBullet').each(function() {
$(this).nextUntil('.container > :not(.listBullet)')
.addBack()
.wrapAll("<div class='wrapperDiv' />");
});
Fiddle 2
Here's a more brute force approach:
var lb= [];
$('.container > *').each(function() {
if($(this).hasClass('listBullet')) {
lb.push(this);
}
else {
$(lb).wrapAll("<div class='wrapperDiv'/>");
lb= [];
}
});
$(lb).wrapAll("<div class='wrapperDiv'/>");
Fiddle 3
As a general approach you could:
Loop through all the elements on the page using .next()
, while the next element you find is has the correct class, (use .attr("class")
) add an extra class of currentList
(or simular) class wrapAll on currentList
then select all the items with the currentList
class and remove that class and then keep looping!
Well, you could also do something like this, although maybe just using jQuery methods is more straightforward (and a bit more flexible):
http://jsfiddle/ewj44a2L/1/
var listBullets = $('.listBullet'),
n = 3, // Number of bullets per group. All groups must be equal.
len = listBullets.length / n; // Number of groups to be encapsulated
for(var i = 0; i < len; i++) {
listBullets.slice( n * i, n * (i + 1) )
.wrapAll('<div class="wrapperDiv"></div>');
}
.wrapperDiv {
background: #000;
color: #fff;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Some Text</p>
<div class="listBullet">Item 1</div>
<div class="listBullet">Item 2</div>
<div class="listBullet">Item 3</div>
<p>Some More Text</p>
<div class="listBullet">Item 1</div>
<div class="listBullet">Item 2</div>
<div class="listBullet">Item 3</div>
<p>Some Other Text</p>
<div class="listBullet">Item 1</div>
<div class="listBullet">Item 2</div>
<div class="listBullet">Item 3</div>
Try
$("p").map(function(i, el) {
var el = $(el), list = ".listBullet";
if (el.next().is(list)) {
var wrap = el.after("<div class=wrapperDiv />").next();
do { wrap.next().appendTo(wrap); }
while (wrap.next().is(list));
};
});
<script src="https://ajax.googleapis./ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<p>Some Text</p>
<div class="listBullet">Item 1</div>
<div class="listBullet">Item 2</div>
<div class="listBullet">Item 3</div>
<p>Some More Text</p>
<div class="listBullet">Item 1</div>
<div class="listBullet">Item 2</div>
<div class="listBullet">Item 3</div>
<p>Some Other Text</p>