3
<p class="bodytext">
    <span class="datum">19.11.2015:</span>Some text <a href="path/to/link" title="some title" class="download">Some text</a>. Again some text!
</p>
<p class="bodytext">
    <span class="datum">19.11.2015:</span>Maybe also only some text.
</p>
<p class="bodytext">
    <span class="datum">19.11.2015:</span><a href="path/to/link" title="some title" class="download">Only with link</a>
</p>

Should be after jQuery:

<p class="bodytext">
    <span class="datum">19.11.2015:</span>
    <div class="someClass">Some text <a href="path/to/link" title="some title" class="download">Some text</a>. Again some text!</div>
</p>
<p class="bodytext">
    <span class="datum">19.11.2015:</span>
    <div class="someClass">Maybe also only some text.</div>
</p>
<p class="bodytext">
    <span class="datum">19.11.2015:</span>
    <div class="someClass"><a href="path/to/link" title="some title" class="download">Only with link</a></div>
</p>

So all HTML-Code after the </span> should be wrapped in a div until the next occurence of </p>

What I tried:

$(".datum").each(function (index) {
        $(this).nextUntil("p").andSelf().wrapAll("<div class='someClass' />");
    });

Or:

$(".datum").nextUntil("p").wrap('<div class="someClass" />');

Didn't work either.

double-beep
  • 5,031
  • 17
  • 33
  • 41
user3532637
  • 333
  • 3
  • 16

4 Answers4

3

Try this: You can make use of wrapInner to wrap div around content of bodytext div and then take out datum span from wrapped div.

$(function(){
    $('p.bodytext').each(function(){
    
      $(this).wrapInner( "<div class='someClass'></div>");
      $(this).prepend($(this).find('div.someClass').find('span.datum'));
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<p class="bodytext">
    <span class="datum">19.11.2015:</span>Some text <a href="path/to/link" title="some title" class="download">Some text</a>. Again some text!
</p>
<p class="bodytext">
    <span class="datum">19.11.2015:</span>Maybe also only some text.
</p>
<p class="bodytext">
    <span class="datum">19.11.2015:</span><a href="path/to/link" title="some title" class="download">Only with link</a>
</p>

EDIT: - As OP wants to put filter on bodytextcontaining child datum span. Here you can use :has selector for bodytext. Also you can use :contains or .has() jQuery methods.

$(function(){
    $('p.bodytext:has(span.datum)').each(function(){
    
      $(this).wrapInner( "<div class='someClass'></div>");
      $(this).prepend($(this).find('div.someClass').find('span.datum'));
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<p class="bodytext">
    <span>19.11.2015:</span>Some text <a href="path/to/link" title="some title" class="download">Some text</a>. Again some text!
</p>
<p class="bodytext">
    <span class="datum">19.11.2015:</span>Maybe also only some text.
</p>
<p class="bodytext">
    <span class="datum">19.11.2015:</span><a href="path/to/link" title="some title" class="download">Only with link</a>
</p>
Bhushan Kawadkar
  • 28,279
  • 5
  • 35
  • 57
  • Works perfect, thanks! Just one thing might be optimized: It now changes all p.bodytext, even on other pages. But I only want it to change p.bodytext with preceeding span.datum. I solved it by assigning an ID to the main div on that page, but would be nice without. – user3532637 Dec 10 '15 at 14:13
  • Yes, you can definitely filter the bodytext on the basis of child element datum span. See my edit in answer. – Bhushan Kawadkar Dec 11 '15 at 04:15
0

try:

$('.bodytext').find('*').not('span').wrap('<div class="someClass" />')
madalinivascu
  • 32,064
  • 4
  • 39
  • 55
0

Your logic is wrong, because, the code append div element after the element that has class "datum" until <p> element is start. But in div with class="bodytext" you have no <p> element.

Try this;

$(".bodytext").each(){
    $(this).after($(".datum")).wrapAll("<div class='someClass'>Some text <a href='path/to/link' title='some title' class='download'>Some text</a>. Again some text!</div>");
}

I'm not sure about wrapAll, but the order is true for the append operation.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Vecihi Baltacı
  • 352
  • 4
  • 20
0

Here is an aproach that is faster than any full jQuery solution.

It fecthes the first element, removes it and re-creates the content with the remaining content left.

Here's what I mean:

$(function(){
  
 $('.bodytext').each(function(){
  var first = this.children[0];
  this.removeChild(first);
  this.innerHTML = first.outerHTML + '<div class="someclass">' + this.innerHTML + '</div>';
 });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<p class="bodytext">
    <span class="datum">19.11.2015:</span>Some text <a href="path/to/link" title="some title" class="download">Some text</a>. Again some text!
</p>
<p class="bodytext">
    <span class="datum">19.11.2015:</span>Maybe also only some text.
</p>
<p class="bodytext">
    <span class="datum">19.11.2015:</span><a href="path/to/link" title="some title" class="download">Only with link</a>
</p>

The outerHTML property contains the whole HTML of the input, including:

  • name
  • id
  • class
  • data-*
  • on<event>
  • ... any attribute directly set into the HTML

    Hope this works for you.

Ismael Miguel
  • 4,185
  • 1
  • 31
  • 42
  • Thanks very much! But doesn't seem to work exactly in the way, that I need it. It changes only the first of all occurences of p.bodytext. – user3532637 Dec 10 '15 at 14:17
  • @user3532637 That's impossible. If you check the final source code on my stack snippet, using an element inspector, you will see that the output is the one you want – Ismael Miguel Dec 10 '15 at 23:05
  • Yes, works in a sandbox, but in my environment it's as I described (maybe because there are some further `

    ` tags in between), so it might be a solution for future visitors. So thank you very much for your input!

    – user3532637 Dec 11 '15 at 11:15