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?

2 Answers 2

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 ...);
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Works like a charm, although for some reason the select box then reverts to having nothing selected rather than the chosen colour>
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.
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;
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.
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.
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.