Elyasomer
Elyasomer

Reputation: 113

how to sort by price with jquery

hello I am having a problem sorting products by price and this is my code. I am trying to sort product box but it's not working.

<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script>
$(document).on("change", ".price-sorting", function() {

    var sortingMethod = $(this).val();

    if(sortingMethod == 'l2h')
    {
        sortProductsPriceAscending();
    }
    else if(sortingMethod == 'h2l')
    {
        sortProductsPriceDescending();
    }

});
function sortProductsPriceAscending()
{
    var products = $('.product');
products.sort(function(a, b){ return $(a).data("price")-$(b).data("price")});
$(".products-grid").html(products);

}

function sortProductsPriceDescending()
{
        var products = $('.product');
products.sort(function(a, b){ return $(b).data("price") - $(a).data("price")});
$(".products-grid").html(products);
}
</script>
    </head>
 


    <body>
    <select class="price-sorting type-regular" name="price-sorting">
    <option selected disabled>Default</option>
    <option value="l2h">Low to high</option>
    <option value="h2l">High to low</option>
</select>

 <div class="flex-containershop products-grid">

        
    <div class="productbox">  <a href="#"  data-price="300"> <img class="boximage" src="images/new%20design,jpeg.jpg"></img></a>
        
        <p class="procutboxtext">Price:</p> <p class="price" title="USD">300$</p>
        <p class="procutboxtext">Color:<span class="white"></span> <span class="black"></span></p>
    </div>
    
        
    <div class="productbox">  <a href="#" data-price="6"> <img class="boximage" src="images/new%20design,jpeg.jpg"></img></a>
        
        <p class="procutboxtext">Price:</p> <p class="price" title="USD">6$</p>
        <p class="procutboxtext">Color:<span class="white"></span> <span class="black"></span></p>
    </div>
    
        
    <div class="productbox">  <a href="#" data-price="30"> <img class="boximage" src="images/new%20design,jpeg.jpg"></img></a>
        
        <p class="procutboxtext">Price:</p> <p class="price" title="USD">30$</p>
        <p class="procutboxtext">Color:<span class="white"></span> <span class="black"></span></p>
    </div>
    
        
    <div class="productbox">  <a href="#" data-price="20"> <img class="boximage" src="images/new%20design,jpeg.jpg"></img></a>
        
        <p class="procutboxtext">Price:</p> <p class="price" title="USD">20$</p>
        <p class="procutboxtext">Color:<span class="white"></span> <span class="black"></span></p>
    </div>
    
        

    
    </div>
    </body>
</html>

Upvotes: 1

Views: 1175

Answers (3)

Twisty
Twisty

Reputation: 30893

Consider the following code.

$(function() {
  function sortProductsPrice(dir) {
    var products = [];
    var par = $(".productbox:eq(0)").parent();
    $('.productbox').each(function(i, el) {
      products.push(el);
    });
    if (dir == "l2h") {
      products.sort(function(a, b) {
        return parseInt($(".price", a).text()) - parseInt($(".price", b).text());
      });
    } else {
      products.sort(function(a, b) {
        return parseInt($(".price", b).text()) - parseInt($(".price", a).text());
      });
    }
    par.html("");
    $.each(products, function(i, el) {
      par.append(el);
    });
  }

  $(document).on("change", ".price-sorting", function() {
    var method = $(this).val();
    if (method != 'default') {
      sortProductsPrice(method);
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<select class="price-sorting type-regular" name="price-sorting">
  <option selected disabled>Default</option>
  <option value="l2h">Low to high</option>
  <option value="h2l">High to low</option>
</select>
<div class="flex-containershop products-grid">
  <div class="productbox">
    <a href="#" data-price="300"> <img class="boximage" src="images/new%20design,jpeg.jpg"></img>
    </a>
    <p class="procutboxtext">Price:</p>
    <p class="price" title="USD">300$</p>
    <p class="procutboxtext">Color:<span class="white"></span> <span class="black"></span></p>
  </div>
  <div class="productbox">
    <a href="#" data-price="6"> <img class="boximage" src="images/new%20design,jpeg.jpg"></img>
    </a>
    <p class="procutboxtext">Price:</p>
    <p class="price" title="USD">6$</p>
    <p class="procutboxtext">Color:<span class="white"></span> <span class="black"></span></p>
  </div>
  <div class="productbox">
    <a href="#" data-price="30"> <img class="boximage" src="images/new%20design,jpeg.jpg"></img>
    </a>
    <p class="procutboxtext">Price:</p>
    <p class="price" title="USD">30$</p>
    <p class="procutboxtext">Color:<span class="white"></span> <span class="black"></span></p>
  </div>
  <div class="productbox">
    <a href="#" data-price="20"> <img class="boximage" src="images/new%20design,jpeg.jpg"></img>
    </a>
    <p class="procutboxtext">Price:</p>
    <p class="price" title="USD">20$</p>
    <p class="procutboxtext">Color:<span class="white"></span> <span class="black"></span></p>
  </div>
</div>

First, you should build an Array of Elements and then sort that array. Once sorted you have to redraw them in the proper order.

If you need to compare the Price, you need to get that value first. This can be done with .text(). To use it in evaluation or math, you should convert it to Integer.

Upvotes: 1

Dan Orlovsky
Dan Orlovsky

Reputation: 1093

So, a couple things to note:

HTML elements load from top to bottom. So with your script being placed in the <head> tag risks your event listener: $(document).on("change", ".price-sorting" is at risk of not actually being attached to the element. See ready(), or append your script to the bottom of the page.

Secondly, I noticed you weren't targeting an element that I could find on the page: $('.product'), and you were also expecting data-price to be on the element you were targeting when in reality it was on the child anchor tag.

To fix your code I updated two things:

I put the data-price attribute on the parent element itself:

<div class="productbox" data-price="300"> (for all of them, of course).

And targeted the productbox:

var products = $('.productbox');

And sorting functions as expected.

Upvotes: 0

Pablo CG
Pablo CG

Reputation: 816

I did some updates to your code.

You were not getting the price value but the nodes in the sort, so that couldn't be compared.

$(document).on("change", ".price-sorting", function() {

    var sortingMethod = $(this).val();

    if(sortingMethod == 'l2h')
    {
        sortProductsPriceAscending();
    }
    else if(sortingMethod == 'h2l')
    {
        sortProductsPriceDescending();
    }

});

function getAmount(price){
  return parseFloat(price.replace('$', ''));
}


function sortProductsPriceAscending()
{
    var products = $('.productbox');
    products.sort(function(a, b){ return getAmount($(a).children('.price').text()) - getAmount($(b).children('.price').text()) });
    $(".products-grid").html(products);

}

function sortProductsPriceDescending()
{
    var products = $('.productbox');
    products.sort(function(a, b){ return getAmount($(b).children('.price').text()) - getAmount($(a).children('.price').text()) });
    $(".products-grid").html(products);

}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>

    <body>
    <select class="price-sorting type-regular" name="price-sorting">
    <option selected disabled>Default</option>
    <option value="l2h">Low to high</option>
    <option value="h2l">High to low</option>
</select>

 <div class="flex-containershop products-grid">

        
    <div class="productbox">  <a href="#"  data-price="300"> <img class="boximage" src="images/new%20design,jpeg.jpg"></img></a>
        
        <p class="procutboxtext">Price:</p> <p class="price" title="USD">300$</p>
        <p class="procutboxtext">Color:<span class="white"></span> <span class="black"></span></p>
    </div>
    
        
    <div class="productbox">  <a href="#" data-price="6"> <img class="boximage" src="images/new%20design,jpeg.jpg"></img></a>
        
        <p class="procutboxtext">Price:</p> <p class="price" title="USD">6$</p>
        <p class="procutboxtext">Color:<span class="white"></span> <span class="black"></span></p>
    </div>
    
        
    <div class="productbox">  <a href="#" data-price="30"> <img class="boximage" src="images/new%20design,jpeg.jpg"></img></a>
        
        <p class="procutboxtext">Price:</p> <p class="price" title="USD">30$</p>
        <p class="procutboxtext">Color:<span class="white"></span> <span class="black"></span></p>
    </div>
    
        
    <div class="productbox">  <a href="#" data-price="20"> <img class="boximage" src="images/new%20design,jpeg.jpg"></img></a>
        
        <p class="procutboxtext">Price:</p> <p class="price" title="USD">20$</p>
        <p class="procutboxtext">Color:<span class="white"></span> <span class="black"></span></p>
    </div>
    
        

    
    </div>
    </body>
</html>

Upvotes: 1

Related Questions