I'm completely new to AngularJS and facing a filtering issue with a custom function. My goal is to have:
- Checkboxes for product categories
- Checkboxes for product sub-categories
- A showcase of products
When a user clicks on a category, the sub-categories should update (be enabled, selected), followed by the products being filtered accordingly.
In my app.js file, I currently have:
var ProductApp = angular.module('ProductApp', []);
var rootUrl = $("#linkRoot").attr("href");
ProductApp.controller('ProductController', function ($scope, $http, $timeout) {
// API calls to get data
$http.get(rootUrl + '/GetJsonCategories').success(function (data) {
$scope.categories = data;
});
$http.get(rootUrl + '/GetJsonSubCategories').success(function (data) {
$scope.subcategories = data;
});
$http.get(rootUrl + '/GetJsonProducts').success(function (data) {
$scope.products = data;
})
.then(function (data, status, headers, config) {
// Callback function
$timeout(function () {
runJqueryScripts();
}, 0);
})
$scope.showAll = true;
function ForceFilterFn() {
for (product in $scope.products) {
$scope.filterFn($scope.products[product]);
}
};
$scope.filterFn = function (product) {
if ($scope.showAll) { return true; }
var sel = false;
for (category in $scope.subcategories) {
var t = $scope.subcategories[category];
if (t.selected) {
if (product.CategoryId === t.CategoryId ) {
return true;
}
}
}
return sel;
};
$scope.ChangeCategory = function () {
alert("Category Changed");
};
$scope.ChangeSubCategory = function () {
for (t in $scope.subcategories) {
if ($scope.subcategories[t].selected) {
$scope.showAll = false;
return;
}
}
$scope.showAll = true;
};
});
function equalHeight(group) {
tallest = 0;
group.each(function () {
thisHeight = $(this).height();
if (thisHeight > tallest) {
tallest = thisHeight;
}
});
group.each(function () { $(this).height(tallest); });
}
function runJqueryScripts() {
equalHeight($(".thumbnail"));
$("[rel='tooltip']").tooltip();
$('.thumbnail').hover(
function () {
$(this).find('.caption').slideDown(250);
},
function () {
$(this).find('.caption').slideUp(250);
}
);
}
As for the HTML markup:
<div ng-app="ProductApp" class="container">
<!-- upper section -->
<div class="row">
<div class="col-sm-3">
<!-- left -->
<h3><i class="glyphicon glyphicon-cog"></i> Filters</h3>
<hr>
<ul ng-controller="ProductController" class="nav nav-stacked" id="categoryfilter">
<li>
<a id="MainCategory" href="">
<i class="glyphicon glyphicon-tag"></i> Product categories
</a>
</li>
<li ng-repeat="category in categories">
<input type="checkbox" ng-model="category.selected" value="{{category.CategoryId}}" ng-change="ChangeCategory()"> {{category.Text}}
</li>
</ul>
<ul ng-controller="ProductController" class="nav nav-stacked" id="subcategoryfilter">
<li>
<a id="SubCategory" href="">
<i class="glyphicon glyphicon-tags"></i> Product sub-categories
</a>
</li>
<li ng-repeat="subcategory in subcategories">
<input type="checkbox" ng-model="subcategory.selected" value="{{subcategory.CategoryId}}" ng-change="ChangeSubCategory()"> {{subcategory.Text}}
</li>
</ul>
<hr>
</div><!-- /span-3 -->
<div class="col-sm-9">
<!-- column 2 -->
<h3><i class="glyphicon glyphicon-dashboard"></i> Products </h3>
<hr>
<div ng-controller="ProductController" class="row">
<div ng-repeat="product in products | filter:filterFn" class="col-xs-6 col-sm-4">
<div class="thumbnail">
<img ng-src="@Url.Action("LoadImage", "Images")?ImagePath={{ product.ImagePath}}" alt="Product image" class="img-responsive" />
<div class="caption">
<strong> {{ product.ProductName }}</strong>
<p> {{ product.Description }}</p>
<p>
<span class="label label-primary pull-left">Price</span>
<span class="label label-primary label-as-badge pull-right"> {{ product.Price }} </span>
</p>
<p>
<a href="#" class="btn btn-primary center-block" role="button">
<span class="glyphicon glyphicon-shopping-cart" style="vertical-align:middle"></span> Order
</a>
</p>
</div>
<strong>{{ product.ProductName }}</strong>
</div>
</div>
</div>
<!--/col-span-6-->
</div><!--/row-->
</div><!--/col-span-9-->
</div><!--/row-->
@section Scripts{
<script type="text/javascript" src="@Url.Content("~/Scripts/angular.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/app.js")"></script>
}
Currently, there seems to be an issue with the filtering functionality as the products aren't updating. It appears that $scope.filterFn
is only called once during page load. Any assistance would be greatly appreciated.
Thank you in advance!