patel.milanb
patel.milanb

Reputation: 5992

How to Sort Div by attribute in Jquery

I have a DIV structure like this and would like to sort using following option.

  1. Whats-new
  2. Featured
  3. price-down
  4. price-up

DIV Structure

<div class="product-result-panel product-list">
    <div class="show-all-products">
        <div class="ProductList product filter-enable">
            <a href="image1.jpg" data-productid="1870" data-price="29.99" data-msrp="59.99" data-isfeatured="" data-isnew="" data-gender="WOMENS" data-colour="BLUE">
        </div>
        <div class="ProductList product filter-disable">
            <a href="image2.jpg" data-productid="1871" data-price="46.99" data-msrp="59.99" data-isfeatured="10" data-isnew="" data-gender="WOMENS" data-colour="PURPLE">
        </div>

        <div class="ProductList product filter-enable">
            <a href="image3.jpg" data-productid="1872" data-price="19.99" data-msrp="59.99" data-isfeatured="" data-isnew="44" data-gender="MENS" data-colour="ORANGE">
        </div>
        <div class="ProductList product filter-enable">
            <a href="image4.jpg" data-productid="1872" data-price="59.99" data-msrp="99.99" data-isfeatured="" data-isnew="12" data-gender="MENS" data-colour="BLACK">
        </div>
    </div>
</div>

SORT-Criteria

So when users select price-low, it should sort only filter-enable div's using the data-price attribute and sort by LOW-TO-HIGH, filter-enable is visible on the page and filter-disable is hidden in the DOM

Jquery Code got so far

// DropDownList change event
$(document).on('change', ".sorting", function (e) {
        e.preventDefault();
        var sortString = $(".sorting option:selected").val();
        SortBy(sortString);
    });

function SortBy(sortString) {
        switch(sortString) {
            case "featured":
                {
                    sortUsingNestedText($('.show-all-products'), ".ProductList:visible", "data-isfeatured");
                    break;
                }
            case "whats-new":
                {
                    sortUsingNestedText($('.show-all-products'), ".ProductList:visible", "data-isnew");
                    break;
                }
            case "price-down":
                {
                    sortUsingNestedText($('.show-all-products'), "div", "data-price");
                    break;
                }
            case "price-up":
                {
                    sortUsingNestedText($('.show-all-products'), "div", "data-price");
                    break;
                }
        }
    }

 function sortUsingNestedText(parent, childSelector, keySelector) {
        var items = parent.children(childSelector).sort(function (a, b) {
            var vA = $(keySelector, a).text();
            var vB = $(keySelector, b).text();
            return (vA < vB) ? -1 : (vA > vB) ? 1 : 0;
        });
        parent.append(items);
    }

ERROR

No Error, BUT its not doing any sorting, only first and second DIV's are getting sorted. not all of them. Is it because some of the DIV's dont have data-isfeatured, data-isnew values?

Upvotes: 0

Views: 711

Answers (2)

Yury Tarabanko
Yury Tarabanko

Reputation: 45121

You need to convert strings to floats before sorting by price.

.sort(function (a, b) {
            var vA = parseFloat($(a).children().data(keySelector));
            var vB = parseFloat($(b).children().data(keySelector));
            return vA - vB;
        })

As @Adeptus pointed out keySelector got to be without data- prefix. `

Upvotes: 1

Adeptus
Adeptus

Reputation: 683

I found the primary reason. You are useing wrong selector. Why something like "$(keySelector, a)" what it is $("data-price", "div")? second: you get text but you need data attr and data is inside "a" not in "div" You should use something like:

var vA = $(a).children().attr(keySelector);
var vB = $(b).children().attr(keySelector);

When you use this your price-up will be working( price-down give exactly the same = the same params put inside the same function )

Upvotes: 2

Related Questions