Reputation: 343
I have the following output of WordPress content:
<a href="#">link1</a>
text1
<br>
<br>
<a href="#">link2</a>
text2
<br>
<br>
<a href="#">link3</a>
text
<br>
<br>
<a href="#">link4</a>
text4
<br>
<br>
I DO NOT have access to edit the content so I'm looking to edit this via jQuery. I need to wrap each link with the text and br before next link in a div and then split it in two columns. So the final result would be something like this:
<div class="col-left">
<div class="item">
<a href="#">link1</a>
text1
<br>
<br>
</div>
<div class="item">
<a href="#">link2</a>
text2
<br>
<br>
</div>
</div>
<div class="col-right">
<div class="item">
<a href="#">link3</a>
text3
<br>
<br>
</div>
<div class="item">
<a href="#">link4</a>
text4
<br>
<br>
</div>
</div>
Any idea how can I achieve this using jQuery?
I have tried using .wrap() like this:
$('a').wrap( "<div class='item'></div>" );
Upvotes: 1
Views: 1912
Reputation: 4676
This is the closest I could get. It gives the desired outcome, but I'm not sure that it's terribly flexible.
var textNodes = $('a').first().parent().contents().filter(function() {
return this.nodeType === 3 && $(this).text() !== "\n";
});
$(textNodes).each(function() {
$(this).wrap('<span></span>');
});
var groups = $('a');
$(groups).each(function(index, item) {
$(item).before('<div class="item"></div>');
var theDiv = $(item).prev();
var theItem = $(item).detach();
var theRest = theDiv.nextUntil('a').detach();
theDiv.append(theItem);
theDiv.append(theRest);
theDiv.find('span').contents().unwrap();
});
var theDivs = $('.item');
var half = theDivs.length / 2;
$(theDivs).first().before('<div class="col-left"></div><div class="col-right"></div>');
var i;
for (i = 0; i < half; i++)
{
var nextDiv = $(theDivs[i]).detach();
$('.col-left').append(nextDiv);
}
for (; i < theDivs.length; i++)
{
var nextDiv = $(theDivs[i]).detach();
$('.col-right').append(nextDiv);
}
And here's the JSFiddle. Cheers.
Upvotes: 0
Reputation: 3297
That's a pretty fun challenge.
A quick explanation...
jQuery appears to struggle when getting text elements which aren't wrapped in any tag, so we must fist wrap them. I've used a <span>
. I've used the code from this post to do that.
Now that they're all wrapped up nicely, we can select the elements we're interested in, and find the halfway point. If we have an odd number, let's call Math.ceil
, so that the extra one ends up in the Left column.
var a = $('a');
var i = Math.ceil(a.length/2);
Now let's just get the first column and second column elements by calling $.slice
.
var firstColEls = a.slice(0,i);
var secondColEls = a.slice(i);
We can now loop through the elements and add the <div>
with the item
class. I'm using itemC1 and itemC2 so we can quickly select all the grouped elements later on. The class can have the same styling.
$.each(firstColEls, function(idx,el){
$(el).nextUntil('a').addBack().wrapAll('<div class="itemC1"></div>');
});
$.each(secondColEls, function(idx,el){
$(el).nextUntil('a').addBack().wrapAll('<div class="itemC2"></div>');
});
Now let's select the items, and wrap all of them (together) in the left/right column divs!
$('.itemC1').wrapAll('<div class="l"></div>');
$('.itemC2').wrapAll('<div class="r"></div>';
Wasn't that fun? :). Working Fiddle.
Upvotes: 2
Reputation: 341
Have you tried setting a variable like so:
if (check how many links) {
var wrapLinkLeft = $('<div class="col-left"><div class="item"><a href="#">link1<br><br></a></div></div>');
var wrapLinkRight = $('<div class="col-right"><div class="item"><a href="#">link2<br><br></a></div></div>');
$(wrapLinkLeft).appendTo('body'); //for example append it to the body
}
to make the link dynamic leave it empty and just append it to the href, which means you will probably need to set a class or ID for this href or build a counter to keep track of where the scripts at.
Upvotes: 0