Hi,
My application has a search form, where the user can enter one or more filter criteria, and a Search" button. When the "Search" button is pressed, the filter criteria is "pushed" to the route (the "hash" part of the route, the pushstate plugin isn't used). Also, when the route changes, the search form fields are filled in from the route params. In other words, the search form fields and the route are kept in sync.
The search terms are saved on the route as follows:
...#!&filter[param1]=value1&...&filter[paramN]=valueN [1]
Suppose the user adds one more additional search parameter and press the "Search" button again: a new filter param is added to the route:
...#!&filter[param1]=value1&...&filter[paramN]=valueN&filter[paramN1]=valueN1 [2]
, where N1 = N+1.
Now, if the user push the Back browser button, the route goes back to [1], but the change event of the can.route is not fired.
Here is a fiddle to demonstrate this: http://jsfiddle.net/qYdwR/1826/.
- When the route is change for the first time to match the search criteria {filter: {x: 10}}, the change event fires correctly.
- Second, when the route changes to match the search criteria {filter: {x: 10, y: 20}}, the change event fires correctly. This simulates that a new additional filter criterion is added to the form and the Search button is pressed.
- In the 3rd step, we simulate the user going "Back" to the previous search ("Back" button pressed) by setting the route hash to match the initial search criteria {filter: {x: 10}}. There is no change event fired here.
- Also, in the 4th step, the route hash is made to match the search criteria {filter: {z: 30}}. A change event is fired, but the route attrs are incorrect. Instead of {"filter":{"z":"30"}}, it shows "filter":{"x":"10","y":"20","z":"30"}}.
The problems seems to be in the setState function, at the end of the can.route plugin, where old params are removed and new params are added to the route, but only if they are at the first level, i.e. if the search criteria would have been pushed to the route as follows:
...#!¶m1=value1&...¶mN=valueN
But this approach would limit the application to only one filter "object", i.e. if I want to search red apples and yellow pears, I should be able to search using the route:
#!&apples[color]=red&pears[color]=yellow
What do you think?