Match an element and wrap other content that comes before matched element

Viewed 43

I have a sample data given below:

<div class="dynamic-data">
    <span>1234 - some text here</span>
    <b>1234</b> - some text here
    <hr />
    <span>1234 - some text here</span>
    <span>1234 - some text here</span>
    <b>1234</b> - some text here
    <hr />
    <span>1234 - some text here</span>
    <b>1234</b> - some text here
    <hr />
    <span>1234 - some text here</span>
    <span>1234 - some text here</span>
    <span>1234 - some text here</span>
    <span>1234 - some text here</span>
    <b>1234</b> - some text here
    <hr />
</div>

I want to wrap <span> and <b> combination in another <div> element after matching <hr> element. Can anyone please suggest how can I achieve it by using jQuery .wrap()?

Expected Result:

<div class="dynamic-data">
    <div class="newdiv">
        <span>1234 - some text here</span>
        <b>1234</b> - some text here
    </div>
    <div class="newdiv">
        <span>1234 - some text here</span>
        <span>1234 - some text here</span>
        <b>1234</b> - some text here
    </div>
    <div class="newdiv">
        <span>1234 - some text here</span>
        <b>1234</b> - some text here
    </div>
    <div class="newdiv">
        <span>1234 - some text here</span>
        <span>1234 - some text here</span>
        <span>1234 - some text here</span>
        <span>1234 - some text here</span>
        <b>1234</b> - some text here
    </div>
</div>
2 Answers

I don't know how to do it with wrap() but I managed to do it using some html() and regex

css border:red is just added to display div in example

$(".dynamic-data").html(`<div class="newdiv">`+$(".dynamic-data").html());


$(".dynamic-data").html($(".dynamic-data").html().replace(/<hr\s*\/?>/g, `</div><div class="newdiv">`));

$(".dynamic-data").children("div[class=newdiv]:last").remove();
.newdiv{
  border:red 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dynamic-data">
    <span>1234 - some text here</span>
    <b>1234</b> - some text here
    <hr />
    <span>1234 - some text here</span>
    <span>1234 - some text here</span>
    <b>1234</b> - some text here
    <hr />
    <span>1234 - some text here</span>
    <b>1234</b> - some text here
    <hr />
    <span>1234 - some text here</span>
    <span>1234 - some text here</span>
    <span>1234 - some text here</span>
    <span>1234 - some text here</span>
    <b>1234</b> - some text here
    <hr />
</div>

Try splitting by <hr> to get the content of each <div>, including the text nodes:

$(".dynamic-data > hr").replaceWith("<hr>");
$(".dynamic-data").html("<div class=\"newdiv\">" + $(".dynamic-data").html().split("<hr>").join("</div><div class=\"newdiv\">") + "</div>");
$(".dynamic-data > .newdiv").each(function(index) {
  if ($(this).text().trim().length == 0) {
    $(this).remove();
  };
});
.newdiv {
  background-color: lightgreen;
  margin:2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dynamic-data">
  <span>1234 - some text here</span>
  <b>1234</b> - some text here
  <hr />
  <span>1234 - some text here</span>
  <span>1234 - some text here</span>
  <b>1234</b> - some text here
  <hr />
  <span>1234 - some text here</span>
  <b>1234</b> - some text here
  <hr />
  <span>1234 - some text here</span>
  <span>1234 - some text here</span>
  <span>1234 - some text here</span>
  <span>1234 - some text here</span>
  <b>1234</b> - some text here
  <hr />
</div>

Related