|
I see lots of people asking this question, but no viable answers.
In SpringMVC, it is trivial to register a PropertyEditor against a type or property name for a single controller, by registering it in the WebDataBinder via the InitBinder annotation on a method in the controller. There doesn't appear to be a comparable mechanism in grails. I don't want to override the property editor for every property of that type in the application. I want to do it for a single command object in a single controller. While I could give the property some unique name in order to register that property editor against properties with that name, that strikes me as an incredibly invasive way to solve that problem. Is there no other way to get access to the web data binder just for a single controller and/or action? In all of the responses to similar queries I find in the list and on stack overflow, none actually suggest a solution that isn't global in nature.
|
|
You need to add a Spring bean of type PropertyEditorRegistrar to your resources.groovy
-- Graeme Rocher On Wednesday, July 25, 2012 at 3:10 AM, Samuel Gendler wrote:
|
|
On Jul 24, 2012, at 11:36 PM, Graeme Rocher wrote: > You need to add a Spring bean of type PropertyEditorRegistrar to your resources.groovy Graeme, I'm not clear on your answer (and I need to do the exact same thing as Samuel). The mechanism to register a PropertyEditor is not unclear, you add a PropertyEditorRegistrar in resources.groovy with something like this… beans = { configurer(org.springframework.beans.factory.config.CustomEditorConfigurer) { propertyEditorRegistrars = [ref("registrar")] } registrar(com.brigston.CustomPropertyEditorRegistrar) } But in that registrar, you only have a couple of ways of specifying *which* properties to associate your propertyEditors with. You can do it for *all* properties matching a given class (all BigDecimal classes in this example)… registry.registerCustomEditor(java.math.BigDecimal.class, new CurrencyPropertyEditor()) …or all properties matching a class and a specific property name (all BigDecimal classes named "price" in this next example)... registry.registerCustomEditor(java.math.BigDecimal.class, "price", new CurrencyPropertyEditor()) The problem is that the above is still too generic. You will bind the PropertyEditor to *any* BigDecimal named "price". In my app, I have two Domain objects with BigDecimals named "price". I do not want to associate my PropertyEditor with the "price" property of both of them, just one. In Spring MVC, Sam notes you can bind a propertyEditor to just a single Controller method, not globally throughout the app for all properties matching a classname, or a classname+property name. What's the way to do this in Grails? Thanks! - Gary P.S. And thanks Samuel for asking this question. Perfect timing (for me), I just ran across this problem tonight. > > -- > Graeme Rocher > > On Wednesday, July 25, 2012 at 3:10 AM, Samuel Gendler wrote: > >> I see lots of people asking this question, but no viable answers. >> >> In SpringMVC, it is trivial to register a PropertyEditor against a type or property name for a single controller, by registering it in the WebDataBinder via the InitBinder annotation on a method in the controller. There doesn't appear to be a comparable mechanism in grails. I don't want to override the property editor for every property of that type in the application. I want to do it for a single command object in a single controller. While I could give the property some unique name in order to register that property editor against properties with that name, that strikes me as an incredibly invasive way to solve that problem. Is there no other way to get access to the web data binder just for a single controller and/or action? In all of the responses to similar queries I find in the list and on stack overflow, none actually suggest a solution that isn't global in nature. >> >> > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
The only way I can think right now is to manually create the data binder:
def binder = GrailsDataBinder.createBinder(target, target.class.name) binder.registerCustomEditor(BigDecimal, new MyCustomEditor()) binder.bind(params) Cheers -- Graeme Rocher On Wednesday, July 25, 2012 at 9:29 AM, Gary Affonso wrote:
|
|
On Wed, Jul 25, 2012 at 12:42 AM, Graeme Rocher <[hidden email]> wrote:
Can we put creating an officially supported mechanism for doing this on the radar somehow? I see requests for this all over the internet and a lot of frustration with the lack of an answer. This is the first time I've seen an answer resembling yours, and it isn't entirely clear where I would put this code and what 'target' and 'target.class.name' actually refer to - the controller? If so, how do I get a reference to the controller before my action fires and data binding occurs? This looks like it is the equivalent of annotating a method with @InitBinder in SpringMVC, but without the annotation it isn't clear where to put the code. |
|
It is already on the radar. See http://grails.org/Roadmap under "Grails 2.3 - Data Binding improvements"
-- Graeme Rocher On Wednesday, July 25, 2012 at 12:09 PM, Samuel Gendler wrote:
|
|
In reply to this post by ideasculptor
Oh and you put the code in a controller action
Cheers -- Graeme Rocher On Wednesday, July 25, 2012 at 12:09 PM, Samuel Gendler wrote:
|
|
On Wed, Jul 25, 2012 at 3:27 AM, Graeme Rocher <[hidden email]> wrote:
Thanks. And then I have to manually call bindData, I assume? I know the docs cover doing that, though I've never done so.
|
|
In reply to this post by ideasculptor
On 25/07/2012 11:09, Samuel Gendler wrote:
> Can we put creating an officially supported mechanism for doing this on > the radar somehow? I see requests for this all over the internet and a > lot of frustration with the lack of an answer. This is the first time > I've seen an answer resembling yours, and it isn't entirely clear where > I would put this code and what 'target' and 'target.class.name > <http://target.class.name>' actually refer to - the controller? If so, > how do I get a reference to the controller before my action fires and > data binding occurs? This looks like it is the equivalent of annotating > a method with @InitBinder in SpringMVC, but without the annotation it > isn't clear where to put the code. You could achieve something similar to Spring MVC's InitBinder mechanism using a custom PropertyEditorRegistrar that does something like this public void registerCustomEditors(PropertyEditorRegistry registry) { def req = RequestContextHolder.requestAttributes?.currentRequest if(req) { def currentController = GrailsWebUtil.getControllerFromRequest(req) if(currentController?.respondsTo('registerCustomEditors')) { currentController.registerCustomEditors(registry) } } } (This implementation just looks for a particular named method on the controller, but you could use the same sort of trick to look for an annotated method instead). Ian -- Ian Roberts | Department of Computer Science [hidden email] | University of Sheffield, UK --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
In reply to this post by ideasculptor
No you call the bind method on the GrailsDataBinder itself
-- Graeme Rocher On Wednesday, July 25, 2012 at 12:33 PM, Samuel Gendler wrote:
|
|
On Wed, Jul 25, 2012 at 3:52 AM, Graeme Rocher <[hidden email]> wrote:
yep, I figured it out. Without a clue as to what was meant by 'target' and 'objectName' in the createBinder() method. I had to dig into the source to figure out that it was the bind target, not the controller. I'm still not sure what the target name is supposed to be, but it seems to be ignored, since this is now functioning as desired:
def cmd = new AnalysisCommand() def binder = GrailsDataBinder.createBinder(cmd, "cmd")
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("MM/dd/yyyy HH:mm"), false)) binder.bind(params)
I assume targetName is intended for when params are qualified with a name and you wish to bind to multiple command objects. I guess any unqualified names are bound, regardless of the targetName value?
|
| Powered by Nabble | Edit this page |
