0

I wrote the code to sort divs by price attribute. But will not work correctly. Who can help? So you can see in the code jsfiddle

Js:

    $(".link-sort-list").on("click",function(e){
    var $list = $('#sort-list');
    var $productList = $('div.product-box',$list);
    $productList.sort(function(a, b){
        var keyA = $(a).attr("price");
        var keyB = $(b).attr("price");

        if($(this).hasClass('asc')){
            console.log("asc");
            return (parseInt(keyA) > parseInt(keyB)) ? 1 : 0;
        } else {
            console.log("desc");
            return (parseInt(keyA) < parseInt(keyB)) ? 1 : 0;
        }
    });
    $.each($productList, function(index, row){
        $list.append(row);
    });
    e.preventDefault();
});
T J
  • 42,762
  • 13
  • 83
  • 138

2 Answers2

2

https://jsfiddle.net/danvim/2xh4LLgr/3/

You need to remember $this changes in different function scope.

Do this to set the target:

var $this = $(this)

Updated code:

$(".link-sort-list").on("click",function(e){
    var $this = $(this);  //<--
    var $list = $('#sort-list');
    var $productList = $('div.product-box',$list);
    $productList.sort(function(a, b){
        var keyA = $(a).attr("price");
        var keyB = $(b).attr("price");

        if($this.hasClass('asc')){ //<--
            console.log("asc");
            return (parseInt(keyA) > parseInt(keyB)) ? 1 : 0;
        } else {
            console.log("desc");
            return (parseInt(keyA) < parseInt(keyB)) ? 1 : 0;
        }
    });
    $.each($productList, function(index, row){
        $list.append(row);
    });
    e.preventDefault();
});

Final Solution

But I would recommend putting the checking of $this outside the sort method. Also, you wouldn't need the shorthand-if, just return the Boolean value will do.

So I would simplify it like so: https://jsfiddle.net/danvim/2xh4LLgr/5/

This will run quicker because the checking for .asc only happens once whereas your original function will check once for every item to be compared.

$(".link-sort-list").on("click",function(e){
    var $this = $(this);
    var $list = $('#sort-list');
    var $productList = $('div.product-box',$list);
    var order = $this.hasClass('asc');
    console.log(order);
    $productList.sort(function(a, b){
        var keyA = $(a).attr("price");
        var keyB = $(b).attr("price");
            return order ? (parseInt(keyA) > parseInt(keyB)) : (parseInt(keyA) < parseInt(keyB));
    });
    $.each($productList, function(index, row){
        $list.append(row);
    });
    e.preventDefault();
});
Daniel Cheung
  • 4,779
  • 1
  • 30
  • 63
  • Click on ASC or Desc several times. With each click, divs are sorted differently!! Should sorting must be done at once? –  Jan 10 '16 at 10:39
  • My problem is that, Sorting data do not be properly. –  Jan 10 '16 at 10:44
  • @AliTD I do not quite understand the problem, did the latter link have the problem? Can you describe it with example? I tried the fiddle and items are sorted properly. – Daniel Cheung Jan 10 '16 at 11:09
1

In Daniel's answer, instead of logical comparison (<, >), use subtraction (-).

The "compare" function in sort(compare) must take two arguments a and b. The return value of the compare function needs to return a value based on these two parameters:

  1. Return greater than 0 if a is greater than b
  2. Return 0 if a equals b
  3. Return less than 0 if a is less than b

For details see the answer "How does sort function work in JavaScript", explained in a nice way.

$(".link-sort-list").on("click",function(e){
    var $this = $(this);
    var $list = $('#sort-list');
    var $productList = $('div.product-box',$list);
    var order = $this.hasClass('asc');
    console.log(order);
    $productList.sort(function(a, b){
        var keyA = $(a).attr("price");
        var keyB = $(b).attr("price");
        return order ? (parseInt(keyA) - parseInt(keyB)) : (parseInt(keyB) - parseInt(keyA));
    });
    $.each($productList, function(index, row){
       $list.append(row);
    });
    e.preventDefault();
});
Community
  • 1
  • 1
Abhay
  • 314
  • 1
  • 2
  • 11