When you define an exposed filter and the results expand on more than one page, the themed pager doesn't seem to use the selection made by the user in the exposed filter. Thus, when you go to page 2, the query is reset to its original state.
There are more than one way to solve this. Here are the ones I can think of, let me know what would be your favorite:
- Use $_SESSION.
This allows you to continue filtering without adding values to the url. It's transparent. When the user comes back to the view, her filters are still set as she left them.
- Use $_GET.
This would make the url a bit more complex but would allow developers to link directly to a given url.
I would go for $_GET, it adds a nice new feature (direct linking to a selection from anywhere else in the site). But this would mean that instead of using method POST for your exposed filter form submission, you would also use method GET to keep consistency.
Comments
Comment #1
mansion commentedOther problem I found:
It seems the exposed filter form posts to PHP_SELF or something like that. Thus, pager info is kept in the url. It means that if you are on page 3 and change the filter selection then submit, you will still be on page 3 of the results, even if there is no page 3. I would expect the pager to be reset upon exposed filter submission.
Comment #2
mansion commentedAn idea I had to solve the first issue...
You remove support for arguments as it is now and you use only exposed filters. Then you allow a filter to be exposed with a GUI or only in the URL. In every case, the filter is exposed in the url. This means a major modification of your code I guess, but that's the most elegant solution I could think of. Unless I missed something of course...
Comment #3
mansion commentedFollowing my monologue...
Another easier solution would be to have a way to link arguments to exposed filters. Not every exposed filters can be mapped to arguments but some can, for example the taxid argument can be mapped to the taxonomy module filters.
Again, there can be different implementation of this, depending on whether you think the view admin gui is intended for developers or for noobs. At the moment, it looks more developers oriented.
So you could simply add a field in the exposed filter table that would say whether the filter is linked to an argument and store the argument position in the table.
Then when you build the pager, you just check if any exposed filters are mapped to any arguments and construct a parameter array you pass to theme_pager.
Comment #4
mansion commentedOk, I have implemented my idea. It's incomplete but it works for me, with my settings. I simply check if there is a link between the exposed filters and the arguments from a field I added to the exposed filter table between views_argument.type and exposed_filter.arg_type (it's very bad design not to use primary keys BTW). If there is, I take the POSTed value and rebuild an url with it, then redirect using drupal_goto().
Anyway, first step to have pager work with exposed filters is to add the following in theme_views_display_filters():
or whatever it is to look drupalish, I can't bother to use a 5+ parameter function for this.
This way, when you resubmit the exposed filter form and there is an argument or a page number in the query, it's reset.
The rest of the solution will come later, if anyone shows some interest to the issue. I am sick of this monologue.
Comment #5
cooperaj commentedAlthough this went on a bit I'd like to second a solution to this issue. In it's current state exposed filters and pagiation are fundamentally incompatable. There are just too many confusing functionality conflicts.
Thanks
Adam
Comment #6
merlinofchaos commentedIn it's current state exposed filters and pagiation are fundamentally incompatable
I disagree with this. They should be completely compatible.
- Use $_SESSION.
This allows you to continue filtering without adding values to the url. It's transparent. When the user comes back to the view, her filters are still set as she left them.
This isn't a bad idea and maybe something to consider.
- Use $_GET.
This would make the url a bit more complex but would allow developers to link directly to a given url.
I'd like to do this; limitaitons in the formsapi forced me to rip out the $_GET stuff I had initially written the system with. I think I've figured out how to resolve that, though; if I have, this is the solution I'll go with.
Another easier solution would be to have a way to link arguments to exposed filters. Not every exposed filters can be mapped to arguments but some can, for example the taxid argument can be mapped to the taxonomy module filters.
This solution is, IMO, unworkable. Arguments are inherently incompatible with exposed filters due to the issues with ordering. The 2nd argument cannot give given without the first argument present. (Yes it can be wildcarded, but).
The concise answer:
I'll likely recode this to use $_GET once I have a nice block of time to do it. It's not a simple task but I believe it needs to be done. The location of the exposed filter form generation code needs to be moved -- it needs to be generated *much* earlier in the view process. And, of course, since formsapi refuses to use $_GET, despite providing a way to set the form method to 'get' (which is obnoxious), I'll have to control the form default values myself. But I'm pretty sure I can resolve that with some elbow grease.
Comment #7
merlinofchaos commentedHEAD now handles this properly.
Comment #8
(not verified) commented