Reputation: 638
I have a list view that can be sorted, searched and filtered. From that list view the user can edit items in multiple steps. Finally after editing and reviewing the changes the user goes back to the list. Now I want the list to use the same sorting, search term and filters that the user set before and show the correct results.
How can multiple paramters (sorting, search, filter) be stored and reused when showing the list action?
Possible unsatisfactory ways that I thought of:
save the parameters in the session object. This seems to require a lot of code to handle multiple parameters (check if parameter was passed to action, store new value, if parameter was not passed, get old parameter from session, handle empty string parameters):
Long longParameter
if(params.containsKey('longParameter')) {
longParameter = params.getLong('longParameter')
session.setAttribute('longParameter', longParameter)
} else {
longParameter = session.getAttribute('longParameter') as Long
params['longParameter'] = longParameter
}
Upvotes: 1
Views: 334
Reputation: 39907
Using session
is your best bet. Just save the preference when preferred. I mean, when user sorts, or filter, just save that information in the session
, for that particular <controller>.<action>
, before returning the page. Next time, check the session
, if it has anything related to that <controller>.<action>
, apply those; otherwise render the default page.
You might like to use some Interceptor
for this, as suggested by sbglasius, here.
I hope you're getting my point.
Upvotes: 1
Reputation: 3124
If you want to make it more generic you could use an Interceptor
instead.
This could perhaps be generalized like this:
class SessionParamInterceptor {
SessionParamInterceptor() {
matchAll() // You could match only controllers that are relevant.
}
static final List<String> sessionParams = ['myParam','otherParam','coolParam']
boolean before() {
sessionParams.each {
// If the request contains param, then set it in session
if (params.containsKey(it)) {
session[it] = params[it]
} else {
// Else, get the value from session (it will be null, if not present)
params[it] = session[it]
}
}
true
}
}
The static sessionParams
holds the parameters you want to store/retrieve from session.
If the params
contains an element from the list, it is stored in session
under the same name. If not, it is taken from session
(given that it exists).
In your controller, you can now just access params.getLong('theParam')
like you always would. You could also use Grails parameter conversion:
def myAction(Long theParam) {
}
Lots of LOC saved.
Upvotes: 3
Reputation: 1152
I use the session as well. Here is a sample that you may adapt to your needs:
def list() {
if (request.method == 'GET' && !request.queryString) {
if (session[controllerName]) {
// Recall params from memory
params.putAll(session[controllerName])
}
} else {
// Save params to memory and redirect to get clean URL
session[controllerName] = extractParams(params)
redirect(action: actionName)
return
}
// Do your actions here...
}
def extractParams(params) {
def ret = [:]
params.each { entry ->
if (entry.key.startsWith("filter_") || entry.key == "max" || entry.key == "offset" || entry.key == "sort" || entry.key == "order") {
ret[entry.key] = entry.value
}
}
return ret
}
Upvotes: 1