Gaurav Aggarwal Gaurav Aggarwal - 4 months ago 8
HTML Question

ng-repeat sorting for price inappropriate

I am using angular

ng-repeat
with
orderBy
for a product catalogue page to order the products according to select change.

Here
orderBy
name is working fine but when it comes to price it order like this
1,10,11,12,13,14,2,3,4,5,6,7,8,9
because its checking only first value.

I need the result like this
1,2,3,4,5,6,7,8,9,10,11,12,13,14


select html

<select ng-model="sortFilter" ng-init="sortFilter='name'">
<option value="name">Default</option>
<option value="price">Price Low to High</option>
<option value="-price">Price High to Low</option>
</select>


products html

<div class="col-sm-3" ng-repeat="product in products | orderBy:sortFilter">
<div class="product_box clearfix">
<div class="product_img">
<img src="images/{{product.imgLink}}">
</div>
<div class="product_right">
<div class="product_details">
<p class="product_name">{{product.name}}</p>
<p class="product_price">{{product.price}}</p>
</div>
<div class="buy_product">
<p><a href="{{product.link}}"><i class="fa fa-shopping-cart"></i> Buy Now</a></p>
</div>
</div>
</div>




product ng-repeat code

$scope.products = [
{imgLink: 'product1.jpg', name: 'Wingtip Congnac Oxford', price: '$ 14.00', link: '#'},
{imgLink: 'product1.jpg', name: 'Wingtip Congnac Oxford', price: '$ 13.00', link: '#'},
{imgLink: 'product1.jpg', name: 'Wingtip Congnac Oxford', price: '$ 12.00', link: '#'},
{imgLink: 'product1.jpg', name: 'Wingtip Congnac Oxford', price: '$ 11.00', link: '#'},
{imgLink: 'product1.jpg', name: 'Wingtip Congnac Oxford', price: '$ 10.00', link: '#'},
{imgLink: 'product1.jpg', name: 'Wingtip Congnac Oxford', price: '$ 9.00', link: '#'},
{imgLink: 'product1.jpg', name: 'Wingtip Congnac Oxford', price: '$ 8.00', link: '#'},
{imgLink: 'product1.jpg', name: 'Wingtip Congnac Oxford', price: '$ 7.00', link: '#'},
{imgLink: 'product1.jpg', name: 'Wingtip Congnac Oxford', price: '$ 6.00', link: '#'},
{imgLink: 'product1.jpg', name: 'eWingtip Congnac Oxford', price: '$ 5.00', link: '#'},
{imgLink: 'product1.jpg', name: 'dWingtip Congnac Oxford', price: '$ 4.00', link: '#'},
{imgLink: 'product1.jpg', name: 'cWingtip Congnac Oxford', price: '$ 3.00', link: '#'},
{imgLink: 'product1.jpg', name: 'bWingtip Congnac Oxford', price: '$ 2.00', link: '#'},
{imgLink: 'product1.jpg', name: 'aWingtip Congnac Oxford', price: '$ 1.00', link: '#'},
];

Answer

Change your HTML to:

<select ng-model="sortFilter" ng-init="sortFilter='name'">
    <option value="name">Default</option>
    <option value="sort_price">Price Low to High</option>
    <option value="-sort_price">Price High to Low</option>
</select>
<div class="col-sm-3" ng-repeat="product in products | orderBy:sortFilter" ng-init="product.sort_price = parsePriceToFloat(product.price)">
    <div class="product_box clearfix">
        <div class="product_img">
            <img src="images/{{product.imgLink}}">
        </div>
        <div class="product_right">
            <div class="product_details">
                <p class="product_name">{{product.name}}</p>
                <p class="product_price">{{product.price}}</p>
            </div>
            <div class="buy_product">
                <p><a href="{{product.link}}"><i class="fa fa-shopping-cart"></i> Buy Now</a></p>
            </div>
        </div>
    </div>
</div>

And add a function inside of your controller:

$scope.parsePriceToFloat = function(price) {
    return Number(String(price).replace(/[^0-9\.]+/g,""));
}

That parsePriceToFloat function is going to remove any non-numeric values and return a Number type which can then be sorted by your orderBy code.