Angular, using select input filter to update route?
Asked Answered
W

2

7

I have my app set up where a list of products can be filtered by colour using a select input, I also have the $routeprovider passing this colour param to the page if it is present in the url.

What I want to do now is update the url / route when the select box is changed. How do I bind the change of the select to the route?

Wernher answered 6/2, 2013 at 13:21 Comment(0)
P
12

select has an undocumented ng-change parameter that you can use to call a function to set $location.path:

<select ... ng-model="color" ng-change="updatePath()">

Controller:

function MyCtrl($scope, $location) {
    $scope.updatePath = function() {
       $location.path(... use $scope.color here ...);
    }
}
Purchasable answered 6/2, 2013 at 15:46 Comment(5)
Works like a charm, although for some reason the select box then reverts to having nothing selected rather than the chosen colour>Wernher
In your controller, set $scope.color to the color parameter from the route. Note that if you are using an array of objects to generate your select list, you'll need to set $scope.color to point to an element of that array. See this post for more info.Purchasable
I am using the product array to populate the select list, but am also using this (underscore) to pull unique colour titles from that array code $scope.uniqueColours = function() { return _.chain($scope.products) .pluck('colour_title') .flatten() .unique() .value(); }; code so it no longer reflects the initial product array. s it not possible to set $scope.by_colour = $routeParams.colour_title;Wernher
The way select and ng-options work, you have to initialize your ng-model to an element of the array used in ng-options. So in your controller, you'll need to loop through your array and find the appropriate element, then set $scope.by_colour to that.Purchasable
Thanks again @Mark Rajcok, I've marked the response above as correct as it answers my original query. I was initially using ng-repeat to build my options rather than ng-options, which leads to another question but not really relevant in this thread.Wernher
J
4

Your <select> element will be bound to a model with ng-model, which you can $watch and use to update either $location.path or $location.search. Personally, I'd suggest using $location.search: you can change just the parameter you want, and its a bit less work since you don't have to have knowledge of the entire path in your controller.

So assuming you have a <select> element like this:

<select ng-model="selectedColor" ng-options="color for color in colors">

You can use $watch to watch your bound value and update your $location.search, making sure to set it to null if color is undefined or otherwise falsey (this clears the search parameter):

$scope.$watch('selectedColor', function (color) {
    if (color) {
      $location.search('color', color); 
    } else {
      $location.search('color', null);
    }
});

You might want to set up a two-way binding between the search parameter and your local model so that changes will be reflected in your <select>:

$scope.$watch('$location.search().color', function (color) {
    $scope.selectedColor = color;
});

Then it's just a matter of accessing $routeParams.color in your routed controller.

See this plunk for a complete working example.

Jinja answered 6/2, 2013 at 16:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.