Search code examples
jqueryhtml-listsparagraphswrapall

Jquery wrapAll ul li after paragraphs


I need to transform this :

<div id="truc">
   <p>First</p>
      <li>Item one</li>
      <li>Item two</li>
      <li>Item three</li>

  <p>Second</p>
    <li>Item four</li>
    <li>Item five</li>
    <li>Item six</li>
</div>

into this :

<div id="truc">
   <p>First</p>
    <ul id="list1">
       <li>Item one</li>
       <li>Item two</li>
       <li>Item three</li>
    </ul>

   <p>Second</p>
    <ul id="list2">
       <li>Item four</li>
       <li>Item five</li>
       <li>Item six</li>
    </ul>
</div>

I tried to use wrapAll with jquery, something like that :

$('#truc p~li').each(function() {
   $(this).wrapAll('<ul>');
});

Any suggestions would be really appreciated :) Thank you very much !


Solution

  • For this specific structure, you can use the following:

    $('p', '#truc').each(function() {
        $(this).nextUntil('p').wrapAll('<ul>');
    });
    

    Output (demo):

    <div id="truc">
       <p>First</p>
       <ul>
          <li>Item one</li>
          <li>Item two</li>
          <li>Item three</li>
       </ul>
       <p>Second</p>
       <ul>
          <li>Item four</li>
          <li>Item five</li>
          <li>Item six</li>
       </ul>
    </div>
    

    As for the IDs, you can (demo):

    $('p', '#truc').each(function(i) {
        $(this).nextUntil('p').wrapAll($('<ul>', {id: 'list' + (1 + i)}));
    });
    

    The problem with your original approach:

    $('#truc p~li').each(function() {
       $(this).wrapAll('<ul>');
    });
    

    is that the selector #truc p~li mathces all <li> elements (not groupings for each <p> element) and thus wraps each item in the match (<li> element) with a <ul> element.