I have an ASP.NET MVC site with AngularJS in views, and I need to do list filtering based on specific controls using AngularJS. Here are the controls:
An input text field that acts like a search but uses the angular model for a list. The list is currently in format, however I plan to change it to divs.
The list (for now, since it will be divs later) is tied to the input box (ng-model), but is also filtered to handle pagination based on the search box.
angular The Pogination Bootstrap UI control controls pagination for the search box, but also for the slider.
A custom angular slider, which should (since this is the problem now), which should filter the list based on the price component.
Currently, the list is sent via an ajax http call from angular, which populates a list of JSON objects with many properties. The list is currently being filtered out from the input box through the Location property on the JSON object (although it does it automatically as you type, it finds the location property and filters it - I am puzzled by how since I was new to AngularJS, because I did not say that it filters the Location property).
The problem is that I would also like it to filter the list based on the Price property of the JSON object. In my code, I tried to do this using custom filters and a clock, but none of this works. I also want the page to be refreshed as the list narrows the same way as for the input window.
Thus, the list should be filtered by the input input field, as well as by the slider (and, possibly, by flags or drop-down lists, if I plan to update it later, but so far the list is filtered only by the price indicator and input field).
Here is my code:
HTML
<div data-ng-app="dealsPage"> <input type="text" data-ng-model="cityName" /> <div data-ng-controller="DestinationController"> <ul> <li data-ng-repeat="deals in destinations | startFrom:(currentPage - 1)*pageSize | limitTo:pageSize | priceSorter:curLow:curHigh">{{deals.Location}} -- {{deals.Price}}</li> </ul> <br /> <pagination rotate="true" num-pages="noOfPages" current-page="currentPage" max-size="maxSize" class="pagination-small" boundary-links="true"></pagination> <br /> <slider min="{{min}}" max="{{max}}" low="curLow" high="curHigh" round="2" step="0.25" translate="translate(val)"></slider> <br /> Value: {{curLow}} -- {{curHigh}} <br /> Range: {{range}} </div>
Angularjs
var destApp = angular.module('dealsPage', ['ui.bootstrap']); var sliderDirective; destApp.controller('DestinationController', function ($scope, $http, $filter) { $scope.destinations = {}; $scope.filteredDestinations = {}; $scope.min = 300; $scope.max = 1000; $scope.curLow = 320; $scope.curHigh = 980; $scope.translate = function (val) { return val + "° C"; }; $scope.range = 0; $http.get('/Deals/GetDeals').success(function (data) { $scope.destinations = data; }); $scope.pageSize = 10; $scope.maxSize = 5; //Watch for pagination based on the input search box. $scope.$watch('cityName', function (newCityName) { $scope.currentPage = 1; $scope.filteredDestinations = $filter('filter')($scope.destinations, $scope.cityName); $scope.noOfPages = isNaN($scope.filteredDestinations.length / 10) ? 200 : $scope.filteredDestinations.length / 10; }); //These two watches are for the slider controls to observe pagination, but should I use the list filtereing logic in here and how? $scope.$watch('curLow', function (newValue) { $scope.range = Math.round($scope.curHigh - newValue); $scope.filteredDestinations = $filter('filter')($scope.destinations, $scope.range); $scope.noOfPages = isNaN($scope.filteredDestinations.length / 10) ? 200 : $scope.filteredDestinations.length / 10; }); $scope.$watch('curHigh', function (newValue) { $scope.range = Math.round(newValue - $scope.curLow); $scope.filteredDestinations = $filter('filter')($scope.destinations, $scope.range); $scope.noOfPages = isNaN($scope.filteredDestinations.length / 10) ? 200 : $scope.filteredDestinations.length / 10; });}); destApp.directive('slider', function ($timeout, $compile)....//Code for slider here); destApp.filter('startFrom', function () { return function (input, start) { start = +start; //parse to int return input.slice(start); }; }); destApp.filter('priceSorter', function () { var filteredInput = new Array(); return function (input, curLow, curHigh) { for (var x = 0; x <= input.length; x++) { if ((input[x].Price > curLow) && (input[x].Price < curHigh)) { filteredInput.push(input[x]); } } //This should work as I can see the filtering taking place, but the list does not get rendered on the view! return filteredInput; };});
I thought about making the slider a new model, because I want it to be filtered by the ul list using the Price property, but I donโt know how to make the slider an ng model.
In any case, I get the feeling that filtering is the way to go here, as my custom filter is called, and I can execute my own logic as shown, but the new array is not displayed after the changes are filtered.
Thank you very much,
Ben.