scripter78
scripter78

Reputation: 1177

JSon and Jquery Accordion

This is driving me freaking BATTY as hell. This is essentially what I am trying to accomplish. You'll see the Json there are a 2 different departments "Office" and "Stockroom" What I am trying to accomplish is to arrange everyone by the department they are in. The problem with this is that the HTML needs to look something like this

    <h3><a href="#">Section 1</a></h3>
    <div>
        <p>
        First Paragraph
        </p>

        <p>
        Second Paragraph
        </p>

        <p>
        Third Paragraph
        </p>
    </div>

But unfortunately I cannot seem to get the </div> tag in the right spot at the end of the last paragraph of each section

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
        <link rel="stylesheet" type="text/css" href="http://jqueryui.com/themes/base/jquery.ui.all.css" />
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>


    <script type="text/javascript" src="http://jqueryui.com/ui/jquery.ui.core.js"></script>
    <script type="text/javascript" src="http://jqueryui.com/ui/jquery.ui.widget.js"></script>
    <script type="text/javascript" src="http://jqueryui.com/ui/jquery.ui.accordion.js"></script>

    <script type="text/javascript">

    $(document).ready(function () {
        var contacts = [{"displayname":"Bruce Lee","email":"[email protected]","department":"stockroom"},
{"displayname":"Your Momma","email":"[email protected]  ","department":"stockroom"},
{"displayname":"Bob","email":"[email protected]  ","department":"Office"},
{"displayname":"Cathy","email":"[email protected]  ","department":"Office"},
{"displayname":"mike","email":"[email protected]  ","department":"Office"},
{"displayname":"scott","email":"[email protected]  ","department":"Office"}
];          
var contacts2 = contacts;
            var r = 1;

            var lastvalue = 'blah';
            for(var i=0; i <=contacts.length; i++)
            {
                if(contacts[i].department != null)
                {
                    if(lastvalue != contacts[i].department)
                    {
                        if(i<1)
                        {
                        $('#accordion').append('</div><h3><a href="#">' + contacts[i].department + '</a></h3>');
                        $('#accordion').append('<div><p><a href="mailto:'+ contacts[i].email +'">' + contacts[i].displayname + '</a></p>');
                        }else{
                        $('#accordion').append('<h3><a href="#">' + contacts[i].department + '</a></h3>');
                        $('#accordion').append('<div><p><a href="mailto:'+ contacts[i].email +'">' + contacts[i].displayname + '</a></p>');
                        }
                    }else{
                        $('#accordion').append('<p><a href="mailto:'+ contacts[i].email +'">' + contacts[i].displayname + '</a></p>');

                    }

                lastvalue = contacts[i].department;
                r++;
                }
            }
        });
        $(function() {
        $( "#accordion" ).accordion();
    });

    </script>
</head>
<body>
    <div id="contactlist">
    <div id="accordion">

    </div>
    </div>

</body>
</html>

Upvotes: 2

Views: 5494

Answers (2)

MatthewJ
MatthewJ

Reputation: 3187

You might want to change this to a jquery each loop and work with json objects directly inside it. The reason you were getting an accordion level each time was due to your loop inserting a h3 every time. I've supplied code to get you pretty much what you need.

edit: Here is a link to my forked jsfiddle => http://jsfiddle.net/TTV6d/12/

Hope this helps

var departmentlist=new Array();
$.each(contacts, function(i,contact) {
    //insert the departments
    if (contact.department != null && $('#' + contact.department).length == 0) {
        $('#accordion').append('<h3 id='+ contact.department +'><a href="#">' + contact.department + '</a></h3>');
        departmentlist.push(contact.department);
    }
    //insert contacts in the accordion
    $('#' + contact.department).after('<p><a href="mailto:' + contact.email + '">' + contact.displayname + '</a></p>');
});
$.each(departmentlist, function(i,list) {
    $("#" + list).nextUntil("h3").wrapAll("<div></div>");
});

Upvotes: 2

Jonathan Lonowski
Jonathan Lonowski

Reputation: 123473

First, be aware that browsers will generally attempt to normalize markup appended to the document: (http://jsfiddle.net/EVjaq/)

$('#container').append('<div><p>Testing</p>'); // no `</div>`
console.log($('#container').html());           // `<div><p>Testing</p></div>`

So, the open <div> in this line will be closed at the end for you, before the next <p> is appended:

$('#accordion').append('<div><p><a href="mailto:'+ contacts[i].email +'">' + contacts[i].displayname + '</a></p>');

To avoid this, you can store all of the HTML in a variable, concatenating segments together, and append it to the DOM only once it's done. Or, you can store the <div> and append to that, which can make the conditionals a bit simpler:

var lastvalue = null,
    lastdiv = null;

for (var i = 0; i <= contacts.length - 1; i++) {
    if (contacts[i].department != null) {
        if (lastvalue != contacts[i].department) {
            $('#accordion').append('<h3><a href="#">' + contacts[i].department + '</a></h3>');

            // remember `<div>`
            lastdiv = $('<div>').appendTo('#accordion');
        }

        // append to the `<div>` directly rather than `#accordion`
        // also, skip the `else` so you don't have to type this twice
        lastdiv.append('<p><a href="mailto:' + contacts[i].email + '">' + contacts[i].displayname + '</a></p>');

        lastvalue = contacts[i].department;
        r++;
    }
}

Upvotes: 0

Related Questions