Skip to content
This repository
  • 4 commits
  • 4 files changed
  • 0 comments
  • 2 contributors
May 14, 2012
Roberto Guerra uris77 Add renderErrorsAsMap to Components
In a Composer, it is now possible to do:
self.renderErrorsAsMap(bean:map)
This does the same as renderErrors, but instead of taking domain class,
it takes a list of maps. The map is structured as follows:
[field: field, error: error].
This is useful whenever one is using an api that returns json , or a
map.
91c6d06
May 15, 2012
Roberto Guerra uris77 Typo in comment b6e9193
Roberto Guerra uris77 Renderer Util provides renderMapAsErrors
ComponentErrorRendererUtil dynamically adds renderMapAsErrors. This
allows the input elements of a form to display errors from a map.

Example usage:
I prefer to extract all errors from a domain class into a map. In
Bootstrap I add the following code:

grailsApplication.domainClasses.each{domainClass->
   domainClass.metaClass.retrieveErrorsAsMap = {
      def errors = []
      for(error in delegate?.errors?.fieldErrors){
         def _domain = [
            field: error.field,
            error: messageSource.getMessage(error,null)
            ]
         errors.add(_domain)
      }
   return errors
   }
}

This then allows me retrieve a list of map of errors :

def domainInstance = new Domain()
domainInstance.validate()
def errors = domainInstance.retrieveErrorsAsMap()

And in my composer I can have these errors rendered in their
corresponding input elements as follows:

def create(){
   def domainInstance = new Domain()
   domainInstance.validate()
   def errors = domainInstance.retrieveErrorsAsMap()

   if(errors){
      self.renderMapAsErrors(bean: errors)
   }else{
      flash.message = "Success!"
   }

}

In the example above, you can not see the benefit of something like
this, but if we encapsulate all domain transactions in services, or if
we are working with JSON obtained through some ajax request or a web
service, then this becomes handy.

An example using a service:

class MyService{
   def create(params){
      def instance = [:]
      def _instance = new Domain(params)

      _instance.validate()
      if(_instance.hasErrors()){
         instance.errors = _instance.retrieveErrorsAsMap()
      }else{
         _instance.save()
         instance = _instance.properties
      }

      return instance
   }
}

In the Composer:

void onClick_saveSomething(Event e){
   def instance = myService.create(self.params)
   if(instance.errors){
      self.renderMapAsErrors(bean: instance)
   }else{
      flash.message = 'Success!'
   }
}
a9688ff
Jun 11, 2012
groovyquan Merge pull request #63 from uris77/render_map_as_errors
Render map as errors
a3274c1
7 ZkuiGrailsPlugin.groovy
@@ -10,6 +10,7 @@ import org.grails.plugins.zkui.artefacts.composer.ComposerArtefactHandler
10 10 import org.grails.plugins.zkui.artefacts.vm.ViewModelArtefactHandler
11 11 import org.grails.plugins.zkui.metaclass.RedirectDynamicMethod
12 12 import org.grails.plugins.zkui.util.UriUtil
  13 +import org.grails.plugins.zkui.util.ComponentErrorRendererUtil
13 14 import org.zkoss.zk.ui.Component
14 15 import org.zkoss.zk.ui.Executions
15 16 import org.zkoss.zk.ui.Page
@@ -235,6 +236,10 @@ The different is it more likely to use the Grails' infrastructures such as gsp,
235 236 }
236 237 }
237 238
  239 + ComponentErrorRendererUtil errorRendererUtil = new ComponentErrorRendererUtil()
  240 +
  241 + errorRendererUtil.addRenderMapAsErrors()
  242 +
238 243 org.zkoss.zk.ui.Session.metaClass.getAt = { String name ->
239 244 delegate.getAttribute(name)
240 245 }
@@ -359,4 +364,4 @@ The different is it more likely to use the Grails' infrastructures such as gsp,
359 364 // TODO Implement code that is executed when the project configuration changes.
360 365 // The event is the same as for 'onChange'.
361 366 }
362   -}
  367 +}
2  application.properties
... ... @@ -1,5 +1,5 @@
1 1 #Grails Metadata file
2   -#Thu May 10 09:44:42 CST 2012
  2 +#Tue May 15 08:48:49 CST 2012
3 3 app.grails.version=2.0.3
4 4 app.name=zkui
5 5 plugins.rest-client-builder=1.0.2
21 src/groovy/org/grails/plugins/zkui/util/ComponentErrorRendererUtil.groovy
... ... @@ -0,0 +1,21 @@
  1 +package org.grails.plugins.zkui.util
  2 +
  3 +import org.zkoss.zul.impl.InputElement
  4 +import org.zkoss.zk.ui.Component
  5 +
  6 +class ComponentErrorRendererUtil{
  7 +
  8 + public void addRenderMapAsErrors(){
  9 + org.zkoss.zk.ui.Component.metaClass.renderMapAsErrors = {Map args->
  10 + for(_error in args.bean.errors){
  11 + def name = _error.field
  12 +
  13 + def selectedComponentList = delegate.select("[name='${name}']")
  14 + if(selectedComponentList.size() > 0 && selectedComponentList[0] instanceof InputElement){
  15 + selectedComponentList[0].setErrorMessage(_error.error)
  16 + }
  17 + }
  18 +
  19 + }
  20 + }
  21 +}
38 test/unit/org/grails/plugins/zkui/util/ComponentErrorRendererUtilTests.groovy
... ... @@ -0,0 +1,38 @@
  1 +package org.grails.plugins.zkui.util
  2 +
  3 +import static org.junit.Assert.*
  4 +import org.zkoss.zul.impl.InputElement
  5 +import org.zkoss.zk.ui.Component
  6 +import org.zkoss.zul.Textbox
  7 +import org.zkoss.zul.Window
  8 +import grails.test.*
  9 +
  10 +class ComponentErrorRendererUtilTests extends ComposerUnitTestCase{
  11 +
  12 + Window component
  13 + Textbox txt1
  14 +
  15 + @Before
  16 + void setUp(){
  17 + Window.metaClass.select = { [txt1] }
  18 + component = new Window()
  19 + txt1 = new Textbox()
  20 + txt1.setName('name')
  21 + component.appendChild(txt1)
  22 + }
  23 +
  24 + @Test
  25 + void should_add_renderMapAsErrors_to_InputElement(){
  26 + ComponentErrorRendererUtil util = new ComponentErrorRendererUtil()
  27 + util.addRenderMapAsErrors()
  28 +
  29 + def params = [errors:[[field: 'name', error: 'Name can not be empty']]]
  30 +
  31 + component.renderMapAsErrors(bean: params)
  32 +
  33 + assertEquals 'Name can not be empty', txt1.getErrorMessage()
  34 +
  35 +
  36 + }
  37 +
  38 +}

No commit comments for this range

Something went wrong with that request. Please try again.