0

I'm creating a shortcut for a blog theme where I want to generate a div container around elements after using a cue word. For example, my blog entry would like this:

<div class="entry">

<p>First Paragraph</p>

<p>[box]</p>

<p>Second Paragraph</p>

<p>Third Paragraph</p>

</div> <!-- .entry -->

I'm hoping with some jQuery magic it could turn into this:

<div class="entry">

<p>First Paragraph</p>

<div class="box">

<p>Second Paragraph</p>

<p>Third Paragraph</p>

</div> <!-- .box -->

</div> <!-- .entry -->

One more rule: When I create a container box, I know I will always generate it before the closing div.entry. I'm hoping this restriction will make it easier to write the rules for jQuery. For example, I will never want the markup to look like this where there is content proceeding the div.box container:

<!-- I will never mark it up this way -->

<div class="entry">

<p>First Paragraph</p>

<div class="box">

<p>Second Paragraph</p>

</div> <!-- .box -->

<p>Third paragraph</p>

</div> <!-- .entry -->
Eli
  • 14,779
  • 5
  • 59
  • 77
Marc P
  • 606
  • 1
  • 11
  • 26
  • 1
    And what have you tried so far? – David Thomas Feb 07 '11 at 19:10
  • I'm also currently trying to rewrite some of the markup to make the rules even easier than this: I'm figuring out .after() to completely rewrite the [box] string so that it closes a div container, and opens a new one. – Marc P Feb 07 '11 at 19:50

4 Answers4

0

I think your best bet is the jQuery :contains() selector. With it you could do things like this (note: it matches any paragraph that has [box] in its HTML and maybe you need to escape the brackets):

$("p:contains('[box]')").wrap($('<div>').addClass('box'));

And btw. accepting answers and proving that you already put effort in your problem will make it much more likely to get a helpful reply.

Daff
  • 43,734
  • 9
  • 106
  • 120
  • Noted and thanks for the :contains tip! I was really stuck with my first line of code, so thought it best to simply start fresh with defining the problem. – Marc P Feb 07 '11 at 19:48
0

It will be something like this:

$("div.entry").append(
  $("<div>").addClass("box").append("p:contains([box])+*");
);
$("p:contains([box])").remove();
kirilloid
  • 14,011
  • 6
  • 38
  • 52
0

See an example of the following here.

You can find the index() of the [box] paragraph and then wrapAll() the <p> after using :gt() to get all the parapgraphs following it:

var boxAt;

$('p').each(function(){
    var $t = $(this);
    if ($t.html() === '[box]') {
        boxAt = $t.index();
        $t.remove();
    }
});

$('p:gt(' + (boxAt - 1) + ')').wrapAll('<div class="box">');
mVChr
  • 49,587
  • 11
  • 107
  • 104
  • I just realized that I need to create a div container preceeding all HTML elements after all to get my floats to work properly. I'm saving this for future use! – Marc P Feb 07 '11 at 19:59
  • Glad you like, all the thanks I desire for a working solution to your problem is an up-vote if it's not too much trouble. The more you upvote and accept answers, the more likely people are to help you in the future. – mVChr Feb 07 '11 at 20:14
0

Thanks everyone for your help! It helped me also come up with another strategy that worked for me as well:

$('.entry p:contains([box])').each( function() {
    $(this).prevAll().wrapAll('<div class="lefty">');
});

$('.entry p:contains([box])').each( function() {
    $(this).nextAll().wrapAll('<div class="righty">');
});
$("p:contains([box])").remove();

What this does is create two separate boxes: 1. elements preceding [box], 2. elements proceeding [box]

Marc P
  • 606
  • 1
  • 11
  • 26
  • Darn, so close! When using prevAll(), the elements are reversed in the div.lefty container. All the elements in process with .nextAll() are appearing in the right forward order. I tried .reverse() like this, but it causes an error: `$('.entry p:contains([box])').each( function() { $(this).prevAll().reverse().wrapAll('
    '); });`
    – Marc P Feb 08 '11 at 00:19