Skip to content Skip to sidebar Skip to footer

Nested Order List Under Ajax

I have two arrays from two different xml files, one stores category information, one stores products under categories. They are connected via categoryID. Samples of the xml files a

Solution 1:

Create a data structure that will help you build the list easier.

Suppose you have the following data:

categories.xml

<?xml version="1.0" encoding="UTF-8"?>
<Categories>
    <Category>
        <ID>1</ID>
        <Name>Beverages</Name>
        <Description>Soft drinks, coffees, teas, beer, and ale</Description>
    </Category>
    <Category>
        <ID>2</ID>
        <Name>Condiments</Name>
        <Description>Sweet and savory sauces, relishes, spreads, and seasonings</Description>
    </Category>
</Categories>

products.xml

<?xml version="1.0" encoding="UTF-8"?>
<Products>
    <Product>
        <ID>1</ID>
        <Name>Chai</Name>
        <CategoryID>1</CategoryID>
        <QuantityPerUnit>10 boxes x 20 bags</QuantityPerUnit>
        <UnitPrice>18</UnitPrice>
    </Product>
    <Product>
        <ID>2</ID>
        <Name>Chang</Name>
        <CategoryID>1</CategoryID>
        <QuantityPerUnit>24 - 12 oz bottles</QuantityPerUnit>
        <UnitPrice>19</UnitPrice>
    </Product>
    <Product>
        <ID>3</ID>
        <Name>Chen</Name>
        <CategoryID>2</CategoryID>
        <QuantityPerUnit>6 - 20 oz bottles</QuantityPerUnit>
        <UnitPrice>5</UnitPrice>
    </Product>
    <Product>
        <ID>4</ID>
        <Name>Chow</Name>
        <CategoryID>2</CategoryID>
        <QuantityPerUnit>12 - 40 oz mustard</QuantityPerUnit>
        <UnitPrice>14</UnitPrice>
    </Product>
</Products>

Let's build an object where the key is the category ID and the value is the category data with an additional field products to hold all its related products.

{
    '1': {
        name: 'Beverages',
        description: 'Soft drinks, coffees, teas, beer, and ale',
        products: [ ... ]
    },
    '2': {
        name: 'Condiments',
        description: 'Sweet and savory sauces, relishes, spreads, and seasonings',
        products: [ ... ]
    }
}

When building the object, the key is important because when we will be iterating over the products, we'll be able to easily add them to their respective category's products array as shown below:

var data = {};

categories.find('Category').each(function () {
    var category = $(this);
    var id = category.find('ID').text();
    data[id] = {
        id: id,
        name: category.find('Name').text(),
        description: category.find('Description').text(),
        products: []
    };
})

products.find('Product').each(function () {
    var product = $(this);
    var categoryId = product.find('CategoryID').text();
    if (data.hasOwnProperty(categoryId)) {
        data[categoryId].products.push({
            id: product.find('ID').text(),
            name: product.find('Name').text(),
            quantityPerUnit: product.find('QuantityPerUnit').text(),
            unitPrice: product.find('UnitPrice').text()
        });
    }
});

Once we have this object, we can now build the HTML by running two nested loops.

var list  = '<ol type="i">';
$.each(data, function (i, category) {
    list += '<li>' + category.name
    list += '<ol type="a">';
    $.each(category.products, function (j, product) {
        list += '<li>' + product.name + '</li>';
    });
    list += '</ol>';
    list += '</li>';
})
list += '</ol>';

Putting everything together

<!-- placeholder to hold list -->
<div id="products"></div>

<script>
$(function () {
    // simplified way to get 2 ajax responses
    $.when(
        $.get('categories.xml'),
        $.get('products.xml')
    ).done(function (catRes, prodRes) {
        var categories = $($.parseXML(catRes[2].responseText)).find('Categories'),
            products = $($.parseXML(prodRes[2].responseText)).find('Products');

        // build a data structure to organize both responses
        var data = {};

        categories.find('Category').each(function () {
            var category = $(this);
            var id = category.find('ID').text();
            data[id] = {
                id: id,
                name: category.find('Name').text(),
                description: category.find('Description').text(),
                products: []
            };
        })

        products.find('Product').each(function () {
            var product = $(this);
            var categoryId = product.find('CategoryID').text();
            if (data.hasOwnProperty(categoryId)) {
                data[categoryId].products.push({
                    id: product.find('ID').text(),
                    name: product.find('Name').text(),
                    quantityPerUnit: product.find('QuantityPerUnit').text(),
                    unitPrice: product.find('UnitPrice').text()
                });
            }
        });

        // build HTML using data structure
        var list  = '<ol type="i">';
        $.each(data, function (i, category) {
            list += '<li>' + category.name
            list += '<ol type="a">';
            $.each(category.products, function (j, product) {
                list += '<li>' + product.name + '</li>';
            });
            list += '</ol>';
            list += '</li>';
        })
        list += '</ol>';

        $('#products').html(list);
    });
});
</script>

Useful links:


Post a Comment for "Nested Order List Under Ajax"