开发者

Javascript sorting DIVs based on class

I am trying to sort the following static HTML product listing based on the div that contains the price. In this case the divs all have a class of price-bold. Is there a way to sort the list of products using javascript to sort lowest to highest an开发者_Go百科d highest to lowest with a button/text on-click command? Your help and expertise is greatly appreciated. Thank you, Dan

<div id="gallerypaginate2" class="paginationstyle"></div>
<div id="contents">
    <table width="100%" class="vertical" id="contents-table">
        <tr class="pagination-row">
            <td width="25%" class="horizontal-seperator vertical-seperator">
                <a href="mica136-3s.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2126916" width="125" height="71" border="0" hspace="0" vspace="0" alt="3-Shade Billiard Light - Oversized" title="3-Shade Billiard Light - Oversized" /></a>
                <div class="name"><a href="mica136-3s.html" title="3-Shade Billiard Light - Oversized">3-Shade Billiard Light - Oversized</a></div>
                <div class="price-bold">$2,088.00</div>
            </td>
            <td width="25%" class="horizontal-seperator vertical-seperator">
                <a href="micaf101-01-abbey.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2132333" width="125" height="118" border="0" hspace="0" vspace="0" alt="Abbey Craftsman Fan and Mica Light Kit" title="Abbey Craftsman Fan and Mica Light Kit" /></a>
                <div class="name"><a href="micaf101-01-abbey.html" title="Abbey Craftsman Fan and Mica Light Kit">Abbey Craftsman Fan and Mica Light Kit</a></div>
                <div class="price-bold">$711.00</div>
            </td>
            <td width="25%" class="horizontal-seperator vertical-seperator">
                <a href="mica007.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2150148" width="103" height="125" border="0" hspace="0" vspace="0" alt="Beanpot Table Lamp" title="Beanpot Table Lamp" /></a>
                <div class="name"><a href="mica007.html" title="Beanpot Table Lamp">Beanpot Table Lamp</a></div>
                <div class="price-bold">$442.00</div>
            </td>
            <td width="25%" class="horizontal-seperator">
                <a href="mica012.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2162401" width="125" height="71" border="0" hspace="0" vspace="0" alt="Buffet Table Lamp" title="Buffet Table Lamp" /></a>
                <div class="name"><a href="mica012.html" title="Buffet Table Lamp">Buffet Table Lamp</a></div>
                <div class="price-bold">$370.00</div>
            </td>
        </tr>
        <tr class="pagination-row">
            <td width="25%" class="horizontal-seperator vertical-seperator">
                <a href="mica051.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2169261" width="125" height="71" border="0" hspace="0" vspace="0" alt="Bungalow Floor Lamp" title="Bungalow Floor Lamp" /></a>
                <div class="name"><a href="mica051.html" title="Bungalow Floor Lamp">Bungalow Floor Lamp</a></div>
                <div class="price-bold">$1,370.00</div>
            </td>
            <td width="25%" class="horizontal-seperator vertical-seperator">
                <a href="mica119c.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2177066" width="125" height="71" border="0" hspace="0" vspace="0" alt="Carmel Wall Sconce" title="Carmel Wall Sconce" /></a>
                <div class="name"><a href="mica119c.html" title="Carmel Wall Sconce">Carmel Wall Sconce</a></div>
                <div class="price-bold">$505.00</div>
            </td>
            <td width="25%" class="horizontal-seperator vertical-seperator">
                <a href="micaf101-bw.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2182877" width="125" height="71" border="0" hspace="0" vspace="0" alt="Ceiling Fan with Bell White Light Kit" title="Ceiling Fan with Bell White Light Kit" /></a>
                <div class="name"><a href="micaf101-bw.html" title="Ceiling Fan with Bell White Light Kit">Ceiling Fan with Bell White Light Kit</a></div>
                <div class="price-bold">$524.00</div>
            </td>
            <td width="25%" class="horizontal-seperator">
                <a href="micaf101-c.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2192940" width="125" height="71" border="0" hspace="0" vspace="0" alt="Ceiling Fan with Coppersmith Mica Light Kit" title="Ceiling Fan with Coppersmith Mica Light Kit" /></a>
                <div class="name"><a href="micaf101-c.html" title="Ceiling Fan with Coppersmith Mica Light Kit">Ceiling Fan with Coppersmith Mica Light Kit</a></div>
                <div class="price-bold">$695.00</div>
            </td>
        </tr></table>
</div>
<div id="gallerypaginate" class="paginationstyle"><a href="#" rel="previous">Prev</a> <span class="flatview"></span> <a href="#" rel="next">Next</a></div>


Knowing that the length of my solution would probably scare you off, I decided to make a pure JS solution as a challenge.

Here it is, in all of its weighty glory:

addListeners();

function addListeners()
{
    var toggle = toggleTableSort;
    var node = document.getElementById("sortTables");
    node.onclick = toggle();
}

function toggleTableSort()
{
    var status = 0;
    return function()
    {
        var table = getTable();
        var tableData = table['data'];
        var rows = table['rows'];
        if(status === 0)
        {
            status = 1;
            sortTableData(tableData, rows, "descending");
        }else if(status === 1)
        {
            status = 0;
            sortTableData(tableData, rows, "ascending");  
        }
    }   
}

function getTable()
{
    var container = document.getElementById("contents-table");
    var tbody =  getElementNodes(container, "TBODY", 1, {})[0];
    var rows = getElementNodes(tbody, "TR", 0, {"class": "pagination-row"});
    var tableData = grabTableData(rows);
    return {"data": tableData, "rows": rows};   
}

function getElementNodes(parent, tag, num, attributes)
{
    var nodes = parent.childNodes;
    var temp = [];
    tag = tag.toUpperCase();
    if(num === 0)
    {
        num = nodes.length;   
    }
    for(var i=0;i<nodes.length;i++)
    {
        var node = nodes[i];
        if(temp.length <= num)
        {
            if(node.nodeType === 1 && node.tagName === tag)
            {
                var attributeCheck = true;
                for(var attribute in attributes)
                {
                    if(attributes.hasOwnProperty(attribute))
                    {
                        var newAttribute;
                        if(attribute === "class" && !node.getAttribute(attribute))
                        {
                            newAttribute = "className";   
                        }
                        if(newAttribute)
                        {
                            if(node.getAttribute(newAttribute) !== attributes[attribute])
                            {
                                attributeCheck = false;
                                break;
                            }
                        }else if(!newAttribute)
                        {
                            if(node.getAttribute(attribute) !== attributes[attribute])
                            {
                                attributeCheck = false;
                                break;
                            }
                        }
                    }
                }
                if(attributeCheck)
                {
                    temp.push(node);   
                }
            }
        }else if(temp.length > num)
        {
            break;   
        }
    }
    return temp;
}

function grabTableData(rows)
{
    var data = [];
    for(var i=0;i<rows.length;i++)
    {
        var row = rows[i];
        var tableData = getElementNodes(row, "TD", 0, {"width": "25%"});
        data = data.concat(tableData);
    }
    return data;
}

function sortTableData(tableData, rows, order)
{
    var prices = getPrices(tableData);
    var temp = trimPrices(prices);
    order = order.toLowerCase();
    switch(order)
    {
        case "descending":
        temp = sortParallelData(tableData, temp, order, {"data": tableData, "rows": rows}, orderTables);
        break;
        case "ascending":
        temp = sortParallelData(tableData, temp, order, {"data": tableData, "rows": rows}, orderTables);
        break;      
    }
}

function orderTables(tableData, tableCells)
{
   var rows = tableData['rows'];
   var data = tableData['data'];    
   for(var i=0;i<rows.length;i++)
   {
       var items = tableCells.slice(i * 4, (i * 4) + 4);
       var cells = data.slice(i * 4, (i * 4) + 4);
       for(var j=0;j<rows[i].childNodes.length;j++)
       {
           var node = rows[i].childNodes[j];
           rows[i].removeChild(node);   
       }
       for(var k=0;k<items.length;k++)
       {
           var item = items[k];
           var cell = cells[k];
           rows[i].appendChild(item);
       }
   }

}

function getPrices(tableData)
{
    var prices = [];
    for(var i=0;i<tableData.length;i++)
    {
        var data = tableData[i];
        var node = getElementNodes(data, "DIV", 1, {"class": "price-bold"})[0];
        var text;
        var whitespace;
        if(node.innerText)
        {
            text = node.innerText;
        }else if(node.textContent)
        {
            text = node.textContent;
        }
        whitespace = text.match(/\s+/);
        text = text.replace(whitespace, "");
        prices.push(text);
    }
    return prices;
}

function trimPrices(prices)
{
    var temp = [];
    for(var i=0;i<prices.length;i++)
    {
        var price = prices[i];
        temp.push(price.replace("$", "").replace(",", ""));
    }
    return temp;
}

function sortParallelData(first, second, order, data, callback)
{
    var matches = 0;
    var parallel = first;
    var cached = second;
    var left, right, temp;
    order = order.toLowerCase();   
    switch(order)
    {
        case "descending":
        for(var i=0;i<cached.length;i++)
        {
            left = parseInt(cached[i], 10);
            right = parseInt(cached[i+1], 10);
            temp = parallel[i+1];
            if(right > left)
            {
                cached[i+1] = left;
                parallel[i+1] = parallel[i];
                parallel[i] = temp;
                cached[i] = right;
                matches++;  
            }  
        }
        break;
        case "ascending":
        for(var i=0;i<cached.length;i++)
        {
            left = parseInt(cached[i], 10);
            right = parseInt(cached[i+1], 10);
            temp = parallel[i+1];
            if(left > right)
            {
                cached[i+1] = left;
                parallel[i+1] = parallel[i];
                parallel[i] = temp
                cached[i] = right;
                matches++;  
            }  
        }
        break;
    }
    if(matches > 0)
    {
        sortParallelData(first, second, order, data, callback);
    }else
    {
        callback(data, parallel);  
    }
}

http://jsfiddle.net/t6ysg/8/

Two assumptions were made, that being your table has a tbody tag containing your contents, and that you would always have 4 td elements per table row.

Tested as working in: Firefox 4, Chrome 4, Opera 11, Safari 4, IE 8 + Quirks, and IE 7 + Quirks.


You can simply call .sort() on the <td/> and in the sort find the price and do your comparison.

function SortItems(compare) {
    var elm = $("#contents-table td");
    elm.sort(function(a, b) {
        var priceAText = $(a).find(".price-bold").text().replace(/[^\d]/g, "");
        var priceA = parseFloat(priceAText);

        var priceBText = $(b).find(".price-bold").text().replace(/[^\d]/g, "");
        var priceB = parseFloat(priceBText);
        return compare(priceA, priceB);
    });
    //put them back in the table in the sorted order.
    $("#contents-table tr:first").append(elm.slice(0, 4));
    $("#contents-table tr:last").append(elm.slice(4, 8));
}

$("#high").toggle(function(){
    $(this).text("Sort Low");
    SortItems(function(a, b){ return a< b;});
}, function(){
    $(this).text("Sort High");
    SortItems(function(a, b){ return a> b;});
});

working jsfiddle example

fiddle with some simple fadeOut animation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜