views:

50

answers:

2

Hi Have the following question:

Say we have a multi-level html list that looks like this:

    <ul class="catalog">    
       <li>
          <ul>
            <li>
                <ul>
                   <li>subcat subcat 1</li>
                   <li>subcat subcat 2</li>
                   <li>subcat subcat 3</li>
                </ul>
             </li>
            <li>subcat 2</li>
            <li>subcat 3</li>
          </ul>
       </li>
       <li>
          <ul>
            <li>subcat 4</li>
            <li>subcat 5</li>
            <li>subcat 6</li>
          </ul>
        </li> 

   </ul>

I need to wrap into one div only <li> tags (hamed "header 1", "header 2"... and all its children) which belong to first level of the list.

The result should be:

    <ul class="catalog">
    <div class="myWrapper"> <!-- Added by JQuery -->
       <li>
          <ul>
            <li>
                <ul>
                   <li>subcat subcat 1</li>
                   <li>subcat subcat 2</li>
                   <li>subcat subcat 3</li>
                </ul>
             </li>
            <li>subcat 2</li>
            <li>subcat 3</li>
          </ul>
       </li>
       <li>
          <ul>
            <li>subcat 4</li>
            <li>subcat 5</li>
            <li>subcat 6</li>
          </ul>
        </li> 

     </div>  <!-- Added by JQuery --> 

   </ul>

I tried wrap() function but it did not work as expected

Any ideas how to do this job?

Thanks!

+3  A: 

$('.catalog > li').wrapAll('<div class="wrapper"></div>');

But you're both starting and ending with seriously invalid HTML, so you should probably fix that then ask this question again.

grahamparks
A: 

First, let's start with valid HTML, like this:

<ul class="catalog">
   <li>header 1
      <ul>
        <li>subcat 1
            <ul>
               <li>subcat subcat 1</li>
               <li>subcat subcat 2</li>
               <li>subcat subcat 3</li>
            </ul>
        </li>
        <li>subcat 2</li>
        <li>subcat 3</li>
      </ul>
   </li>
   <li>header 2
      <ul>
        <li>subcat 4</li>
        <li>subcat 5</li>
        <li>subcat 6</li>
      </ul>
    </li>
</ul>​

Then you cap wrap them using .wrapAll(), like this:

$(".catalog > li").wrapAll("<li><div class='something'><ul></ul></div></li>");​

This results in valid HTML, like this:

<ul class="catalog">
  <li>
    <div class="something">
      <ul>
        <li>header 1
          <ul>
            <li>subcat 1
                <ul>
                   <li>subcat subcat 1</li>
                   <li>subcat subcat 2</li>
                   <li>subcat subcat 3</li>
                </ul>
            </li>
            <li>subcat 2</li>
            <li>subcat 3</li>
          </ul>
        </li><li>header 2
          <ul>
            <li>subcat 4</li>
            <li>subcat 5</li>
            <li>subcat 6</li>
          </ul>
        </li>
      </ul>
    </div>
  </li>  
</ul>

You can test it out here, though you can probably get the effect you want with styling on the original <ul>, display: block for example.

Nick Craver
http://jsfiddle.net/VrcSe/ - Great tool, thanks!
volocuga