views:

440

answers:

2

I have this HTML structure and want to convert it to an accordion.

<div class="accor">
    <div class="section">
        <h3>Sub section</h3>
        <p>Sub section text</p>
    </div>
    <div class="section">
        <h3>Sub section</h3>
        <p>Sub section text</p>
    </div>
    <div class="section">
        <h3>Sub section</h3>
        <p>Sub section text</p>
    </div>
</div>

Basically using the h3s as accordion headers, and the rest of the content in each div.section as the content for each accordion panel. (Also note: the headings could be anything between h2 and h6, depending on their nesting).

I figured that this would be easiest if the DOM tree were restructured so the h3s were outside each div since that's how the accordion works by default:

    <h3>Sub section</h3>
    <div class="section">
        <p>Sub section text</p>
    </div>

The only problem is: how to move the headings around? (I don't have access to change the HTML).

var $sections = $("div.accor > .section"),
    $headings = $sections.find("> :header")
;
// I figured that inserting each heading to be before its parent might
// be the answer:
$headings.insertBefore($headings.find(":parent"));

// ... but that doesn't do anything
+1  A: 

Ah, I found the solution.

Using $.each()

$headings.each(function(i, el) {
    var $this = $(el), $p = $this.parent();
    $this.insertBefore($p);
});

Is there a better solution than this, though? Perhaps just using the vanilla Accordion options?

nickf
A: 

How about this:

$('.accor .section').each(function() {
    $('h3', this).insertBefore($(this));
});
MDCore