I have been working on a demo shopping app using AngularJS where I want to be able to list products on the basket page and then sort the list based on some nutritional attributes. I have the sort feature working for each of the attributes, using ng-repeat to loop through the array of items and ng-click to sort the order of the items.
As a next step I want to show some additional information on a product when the list is sorted. Each time you sort the list I would like any products that exceed X in the attribute sorted by to be highlighted e.g. maybe a red background, and displays the actual figure. Anything below X should be displayed as normal. When the list is in its default view I wouldn’t want any of this formatting to be displayed.
The sort is triggered using the following dropdown:
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
{{sortedBy}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a href="#" event-focus="click" data-value="unsorted" value="unsorted" event-focus-id="ProductID" ng-click="reload()">Default</a></li>
<li><a href="#" event-focus="click" data-value="Energy" value="Energy" event-focus-id="ProductID" ng-click="order('HealthStats.Energy')">Energy</a></li>
<li><a href="#" event-focus="click" data-value="fat" event-focus-id="ProductID" ng-click="order('HealthStats.Fat')">Fat</a></li>
<li><a href="#" event-focus="click" data-value="saturates" event-focus-id="ProductID" ng-click="order('HealthStats.Saturates')">Saturates</a></li>
<li><a href="#" event-focus="click" data-value="sugar" event-focus-id="ProductID" ng-click="order('HealthStats.Sugar')">Sugar</a></li>
<li><a href="#" event-focus="click" event-focus-id="ProductID" ng-click="order('HealthStats.Salt')" data-value="salt">Salt</a></li>
</ul>
The sort uses the following controller:
app.controller('sortAttribute', function($scope, $http, localStorageService) {
$scope.basketID = localStorageService.get('basketID');
console.log($scope.basketID);
$http.get("../api/BasketService?basketId=" + $scope.basketID)
.then(function(response){
$scope.products = response.data.BasketContentItemList;
})
$scope.predicate = ProductID;
$scope.sortedBy = 'Sort Basket By:'
$scope.reverse = false;
$scope.order = function(predicate) {
$scope.reverse = true;
$scope.predicate = predicate;
$scope.sortedBy = predicate.substr(12, predicate.length);
};
** I have removed parts of the controller that aren’t relevant
This ng-repeat then prints the product name, quantity, price and image:
<div class = "product-list-info-container" ng-repeat="product in products | orderBy:predicate:reverse" >
<div class = "product-image">
<span class="label label-primary"></span><img ng-src="{{ product.ImageUrl }}" />
</div>
<div class="product-name">
<span ng-style="set_color(attribute)" class="label label-primary" ><!--Description :--></span><p> {{ product.ProductName }} x {{ product.Quantity }}</p>
</div>
<div class="product-price">
<span class="label label-primary"><!--Description :--></span><p> £{{ product.ProductPrice}}</p>
</div>
</div>
The products are returned in this format:
{
"BasketContents": {
"BasketContentItemList": {
"ProductInformation": [
{
"ProductID": "3257340",
"HealthStats": {
"Energy": "30",
"Fat": "0.1",
"Salt": "0.1",
"Saturates": "0.1",
"Sugar": "6"
},
"ImageUrl": "../images/340_0000003257340_IDShot_90x90.jpg",
"ProductName": "Strawberries",
"ProductPrice": "2.00",
"Quantity": "1",
"QuantityOfUnit": "400",
"UnitOfMeasurement": "G"
},
{
"ProductID": "3250075",
"HealthStats": {
"Energy": "198",
"Fat": "19.5",
"Salt": "0",
"Saturates": "4.1",
"Sugar": "0.5"
},
"ImageUrl": "../images/075_0000003250075_IDShot_90x90.jpg",
"ProductName": "AVOCADOS",
"ProductPrice": "1.75",
"Quantity": "1",
"QuantityOfUnit": "1",
"UnitOfMeasurement": "SNGL"
}
I have been researching different ways to change the styling based on a value within the array but so far the only the thing I have found that can be used in conjunction with ng-repeat is $first – however this is not suitable as this means the styling is always applied to the first product in the list even if it doesn’t exceed the required value.
TLDR; does anyone know how I can apply conditional formatting to items within an ng-repeat based on a value within the array?