views:

6727

answers:

2

I have ASP.Net code similar to the following (this is inside a FIELDSET):

<ol>
    <li>
        <label>Some label</label>
        <one or more form controls, ASP.Net controls, labels, etc.>
    </li>
    <li>
        <label>Another label</label>
        <... more of the same...>
    </li>
    ...
</ol>

I'm trying to keep my markup as clean as I possibly can, but I've decided that for various reasons, I need to wrap a DIV around everything in the list item after the first label, like this:

<ol>
    <li>
        <label>Some label</label>
        <div class="GroupThese">
           <one or more form controls, ASP.Net controls, labels, etc.>
        </div>
    </li>
    <li>
        <label>Another label</label>
        <div class="GroupThese">
            <... more of the same...>
        </div>
    </li>
    ...
</ol>

I would rather do this with "unobtrusive Javascript" via jQuery instead of littering my page with extra markup so I can keep the form semantically "clean".

I know how to write a jQuery selector to get to the first label in each list item $("li+label") or use :first-child. I also know how to insert things after the selection.

What I can't figure out (at least this late at night) is how to find everything after the first label in the list item (or basically everything in the list item except for the first label would be another way to put it) and wrap a DIV around that in the document ready function.

UPDATE:

Owen's code worked once I removed the single quotes from around:

$('this')
and set the proper decendent selector:
$("li label:first-child")
in order to only select the first label that occurs after a list item.

Here is what I did:

$(document).ready(function() {

    $('li label:first-child').each(function() {
        $(this).siblings().wrapAll('<div class="GroupThese"></div>');
    });
});
+2  A: 

One approach would be to just wrap everything inside the <li> and then move the label out, e.g.

var $div = $('li').wrapInner('<div></div>').children('div');
$div.children('label').prependTo($div.parent());
Matt
+4  A: 

edit: corrected code (see old code in revision history and comments for more info)

ok this should work:

$('li label:first-child').each(function() {
    $(this).siblings().wrapAll('<div class="li-non-label-child-wrapper">');
});

from:

<li>
    <label>Some label</label>
    <div>stuff</div>
    <div>other stuff</div>
</li>
<li>
    <label>Another label</label>
    <div>stuff3</div>
</li>

produces:

<li>
    <label>Some label</label>
    <div class="li-non-label-child-wrapper">
      <div>stuff</div>
      <div>other stuff</div>
    </div>
</li>
<li>
    <label>Another label</label>
    <div class="li-non-label-child-wrapper">
      <div>stuff3</div>
    </div>
</li>
Owen
That's the kind of thing I was looking for. I'll try it tomorrow and accept the answer if it works for me... Thanks!
CMPalmer
Unfortunately your code will wrap every child element (<span> in this case) separately.
Alexander Prokofyev
oh good catch, i've updated the code, should work now
Owen
Thanks! Works like a charm (and even better, I learned some new stuff)!
CMPalmer