Easygrid
Easygrid copied to clipboard
In filterClosure, I'm trying to filter based on a hasMany association...
I'm creating a search field that filters on different criteria depending on the nature of the input. The domainClass bound to the grid is Account. If the search string only contains numbers, I assume the user is trying to search by account id, so my filter closure returns:
eq('id', input)
An Account hasMany = [phoneNumbers:PhoneNumber]
If the user's input looks like a phone number, then I want to return accounts where one of the phoneNumbers matches the input.
Something like the following pseudo code:
filterClosure { Filter filter ->
if ( filterParamValueLooksLikePhoneNumber() ) {
phoneNumbers {
value == theInput
}
}
}
I've tried several different approaches but haven't had any luck. Can I do this without modifying your GormDatasourceService.createWhereQuery method?
Something like this should work:
{ Filter filter ->
if (looksLikePhoneNumber(filter.paramValue)) {
phoneNumbers {
eq('value', filter.paramValue)
}
} else {
eq('id', filter.ParamValue)
}
}
From your pseudo code - it looks like you are trying to use the "where query" syntax, which does not work for filterClosures
Hmm, that's actually the syntax that I tried first. For some reason that doesn't work (the filter doesn't get applied, all Accounts returned), however manually using a DetachedCriteria from the console with that syntax works as expected:
//this works from the console
new BootStrap().init(ctx.servletContext)
def c = new DetachedCriteria(Account).build {
phoneNumbers {
eq('value','3105551212')
}
}
c.list()
I tried putting a breakpoint inside the phoneNumbers closure (inside the filterClosure) and it doesn't get hit.
Also, I discovered that if I put that in the initalCriteria closure, it works as expected:
initialCriteria {
phoneNumbers {
eq ( 'value', '3105551212')
}
}
Maybe it has to do with when you call build() on the criteria in GDS.createWhereQuery()?
Looks more like the Filter object for that field is never created in the first place.
The filters for the grid columns are created in the 'filters' method of the gridImplService ( I presume you use JqueryGridService) The filters for the filter form are created in FilterFormService.filters.
So, I would set a breakpoint in the filter method.
Basically, what happens, is the parameter names are compared to the column names, and if they are the same a Filter is created.
I've stepped through and a filter is definitely created, however in the sql log I see:
Hibernate: select count(*) as y0_ from account this_ where 1=1
when I try to use the phoneNumbers filter. Seems like it might be a grails bug, but I'm not sure how to narrow down the problem from here.
Stepping into DetachedCriteria.handleJunction() I see that lastJunction.criteria is empty.
I created a jira here: http://jira.grails.org/browse/GRAILS-10879 And attached a sample project there: http://jira.grails.org/secure/attachment/18749/foobar-bug-report-02122013.zip
Thanks again for your help.
Thanks.
I'll look into it. Maybe I'll spot something. In the meanwhile, you can also try this with the 'globalFilterClosure', which you define on the grid level.
Something like this:
globalFilterClosure { params ->
if (params.min && params.max) {
between("testIntProperty", params.min as int, params.max as int)
}
}
(this example is from a unit test )
globalFilterClosure works great! Thanks! I didn't know about it before, that's why I went with the filterForm approach.
Great. The globalFilterClosure was created before the filter form support. Basically it does the same thing, but less expressive.
Thanks