tags:

views:

33

answers:

2

Here is my markup, it's generated from a CMS and I can't do much with this at all.

<div id="wrapper">
<dl>
    <dt>
        <label>Awesomeness<span class="required"> *</span></label>
    </dt>
    <dd>Something here</dd>

    <dt>
        <label>Label Here</label>
    </dt>
    <dd>Something here</dd>
</dl>

<dl>
    <dt>
        <label>Awesomeness<span class="required"> *</span></label>
    </dt>
    <dd>Something here</dd>

    <dt>
        <label>Label Here</label>
    </dt>
    <dd>Something here</dd>

    <dt>
        <label>Here is another label<span class="required"> *</span></label>
    </dt>
    <dd>Something here</dd>
</dl>
</div>

I want to wrap a div around each dt and dd. I also want the div to have a class of the label, replacing spaces with a hyphen or underscore.

Looking at the first dl, here's how I'd like it to look.

    <dl>
    <div class="awesomness">
        <dt>
            <label>Awesomeness<span class="required"> *</span></label>
        </dt>
        <dd>Something here</dd>
    </div>

    <div class="label-here">
        <dt>
            <label>Label Here</label>
        </dt>
        <dd>Something here</dd>
    </div>
</dl>

Here's what I got. It wraps a div around every other dt/dd pair. I doesn't add a class name to the div yet either.

jQuery('#wrapper dl').each(function(){
    jQuery(this).addClass('testing');
});

var dts = jQuery("dt");
for(var i=0; i<dts.length;){
    i += dts.eq(i).nextUntil('dt').andSelf().wrapAll('<div />').length;
}
+3  A: 
$('dl').each(function() {
  $(this).children('dt').each(function() {
     var $dt = $(this),
         $dd = $dt.next('dd');

     if($dd.length) {
        $dt.add($dd).wrapAll('<div class="' + $dt.children('label').contents().first().text() + '">');
     }
  });
});

Doh it's untested, but I will right now. Should get close to it.

http://www.jsfiddle.net/AKpv2/

Looks good to me.

jAndy
That works great, except what about the class names for the divs?
wish_i_was_nerdy
@wish_i_was_nerdy: updated.
jAndy
`.children('label').contents().first()` is really awsome. need to update jquery api info :D
TheVillageIdiot
Thanks. I ended up using lonesomeday, but I appreciate it regardless.
wish_i_was_nerdy
+1 for $dt.children('label').contents().first(). Much nicer than my regex solution.
lonesomeday
+1  A: 

jAndy comes close, I think. He's missing the class names and a little sanitation:

$(document).ready(function() {
    $('dt').each(function() {
        var $dt = $(this),
            $selection = $dt.next('dd').andSelf();

        $selection.wrapAll('<div class="' + $dt.find('label').text().replace(/[^a-z]/gi,'').toLowerCase() + '">');
    });
});
lonesomeday
Works very well. I think the regex might be off though. I'm seeing <div class="Label Here">, rather than the space being replaced with a hyphen or underscore.Thanks as well!
wish_i_was_nerdy
Have changed the key line to fix this.
lonesomeday
That works great. My fault here, but I turned out I need all but letters being replaced. Since its a CMS it could have a variety of characters, ie. :();,./?\[]}{ etc. No hyphen or underscores needed, just class="labelhere" would be sufficient.
wish_i_was_nerdy
Again, I have update the code.
lonesomeday
After I murder regex, I want to have your babies. Thank you very much kind sir.
wish_i_was_nerdy