Changeset 332


Ignore:
Timestamp:
Apr 8, 2010, 6:02:16 PM (10 years ago)
Author:
duh
Message:
  • introduced template fields validation
  • added i18n messaging for validation errors
  • added template field validation support to subject fields in wizard
  • TODO: an unsetTemplateField(...) method should be added to TemplateEntity? and used in the wizard. As setting an empty value (=empty string) should result in the particular value be unset in the TemplateEntity? instance... This issue results now in not being able to unset previously set template fields.
Location:
trunk/grails-app
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/dbnp/studycapturing/WizardController.groovy

    r326 r332  
    590590                // walk through template fields
    591591                if (params.template) {
    592                         params.template.fields.each() {field ->
     592                        params.template.fields.each() { field ->
    593593                                def value = params.get(field.escapedName())
    594594
     
    722722                                if (!flow.subjects[ subjectId ].validate()) {
    723723                                        errors = true
    724                                         this.appendErrors(flow.subjects[ subjectId ], flash.errors)
     724                                        this.appendErrors(flow.subjects[ subjectId ], flash.errors, 'subject_' + subjectId + '_')
    725725                                }
    726726                        }
     
    755755        def getHumanReadableErrors(object) {
    756756                def errors = [:]
    757 
    758757                object.errors.getAllErrors().each() {
    759758                        errors[it.getArguments()[0]] = it.getDefaultMessage()
  • trunk/grails-app/domain/dbnp/studycapturing/TemplateEntity.groovy

    r321 r332  
    22
    33import dbnp.data.Term
     4import org.springframework.validation.FieldError
    45
    56/**
     
    1213 */
    1314abstract class TemplateEntity implements Serializable {
    14 
    1515        Template template
    16 
    1716        Map templateStringFields = [:]
    1817        Map templateTextFields = [:]
     
    3534        ]
    3635
     36        static mapping = {
     37                tablePerHierarchy false
     38
     39                templateTextFields type: 'text'
     40        }       
     41
     42        /**
     43         * Contraints
     44         *
     45         * All template fields have their own custom validator. Note that there
     46         * currently is a lot of code repitition. Ideally we don't want this, but
     47         * unfortunately due to scope issues we cannot re-use the code. So make sure
     48         * to replicate any changes to all pieces of logic!
     49         */
    3750        static constraints = {
    3851                template(nullable: true, blank: true)
    39 
    40         }
    41 
    42         static mapping = {
    43                 tablePerHierarchy false
    44 
    45                 templateTextFields type: 'text'
     52                templateStringFields(validator: { fields, obj, errors ->
     53                        def error = false
     54
     55                        // iterate through fields
     56                        fields.each { key, value ->
     57                                // check if value is of proper type
     58                                if (value.class != String) {
     59                                        // it's not, try to cast it to the proper type
     60                                        try {
     61                                                fields[key] = (value as String)
     62                                        } catch (Exception e) {
     63                                                // could not typecast properly, value is of inproper type
     64                                                error = true
     65                                                errors.rejectValue(
     66                                                        'templateStringFields',
     67                                                        'templateEntity.typeMismatch.string',
     68                                                        [key, value.class] as Object[],
     69                                                        'Property {0} must be of type String and is currently of type {1}'
     70                                                )
     71                                        }
     72                                }
     73                        }
     74                        return (!error)
     75                })
     76                templateTextFields(validator: { fields, obj, errors ->
     77                        def error = false
     78                        fields.each { key, value ->
     79                                if (value.class != String) {
     80                                        try {
     81                                                fields[key] = (value as String)
     82                                        } catch (Exception e) {
     83                                                error = true
     84                                                errors.rejectValue(
     85                                                        'templateTextFields',
     86                                                        'templateEntity.typeMismatch.string',
     87                                                        [key, value.class] as Object[],
     88                                                        'Property {0} must be of type String and is currently of type {1}'
     89                                                )
     90                                        }
     91                                }
     92                        }
     93                        return (!error)
     94                })
     95                templateStringListFields(validator: { fields, obj, errors ->
     96                        def error = false
     97                        fields.each { key, value ->
     98                                if (value.class != TemplateFieldListItem) {
     99                                        try {
     100                                                fields[key] = (value as TemplateFieldListItem)
     101                                        } catch (Exception e) {
     102                                                error = true
     103                                                errors.rejectValue(
     104                                                        'templateIntegerFields',
     105                                                        'templateEntity.typeMismatch.templateFieldListItem',
     106                                                        [key, value.class] as Object[],
     107                                                        'Property {0} must be of type TemplateFieldListItem and is currently of type {1}'
     108                                                )
     109                                        }
     110                                }
     111                        }
     112                        return (!error)
     113                })
     114                templateIntegerFields(validator: { fields, obj, errors ->
     115                        def error = false
     116                        fields.each { key, value ->
     117                                if (value.class != Integer) {
     118                                        try {
     119                                                fields[key] = (value as Integer)
     120                                        } catch (Exception e) {
     121                                                error = true
     122                                                errors.rejectValue(
     123                                                        'templateIntegerFields',
     124                                                        'templateEntity.typeMismatch.integer',
     125                                                        [key, value.class] as Object[],
     126                                                        'Property {0} must be of type Integer and is currently of type {1}'
     127                                                )
     128                                        }
     129                                }
     130                        }
     131                        return (!error)
     132                })
     133                templateFloatFields(validator: { fields, obj, errors ->
     134                        def error = false
     135                        fields.each { key, value ->
     136                                if (value.class != Float) {
     137                                        try {
     138                                                fields[key] = (value as Float)
     139                                        } catch (Exception e) {
     140                                                error = true
     141                                                errors.rejectValue(
     142                                                        'templateFloatFields',
     143                                                        'templateEntity.typeMismatch.float',
     144                                                        [key, value.class] as Object[],
     145                                                        'Property {0} must be of type Float and is currently of type {1}'
     146                                                )
     147                                        }
     148                                }
     149                        }
     150                        return (!error)
     151                })
     152                templateDoubleFields(validator: { fields, obj, errors ->
     153                        def error = false
     154                        fields.each { key, value ->
     155                                if (value.class != Double) {
     156                                        try {
     157                                                fields[key] = (value as Double)
     158                                        } catch (Exception e) {
     159                                                error = true
     160                                                errors.rejectValue(
     161                                                        'templateDoubleFields',
     162                                                        'templateEntity.typeMismatch.double',
     163                                                        [key, value.class] as Object[],
     164                                                        'Property {0} must be of type Double and is currently of type {1}'
     165                                                )
     166                                        }
     167                                }
     168                        }
     169                        return (!error)
     170                })
     171                templateDateFields(validator: { fields, obj, errors ->
     172                        def error = false
     173                        fields.each { key, value ->
     174                                if (value.class != Date) {
     175                                        try {
     176                                                fields[key] = (value as Date)
     177                                        } catch (Exception e) {
     178                                                error = true
     179                                                errors.rejectValue(
     180                                                        'templateDateFields',
     181                                                        'templateEntity.typeMismatch.date',
     182                                                        [key, value.class] as Object[],
     183                                                        'Property {0} must be of type Date and is currently of type {1}'
     184                                                )
     185                                        }
     186                                }
     187                        }
     188                        return (!error)
     189                })
     190                templateTermFields(validator: { fields, obj, errors ->
     191                        def error = false
     192                        fields.each { key, value ->
     193                                if (value.class != Term) {
     194                                        try {
     195                                                fields[key] = (value as Term)
     196                                        } catch (Exception e) {
     197                                                error = true
     198                                                errors.rejectValue(
     199                                                        'templateTermFields',
     200                                                        'templateEntity.typeMismatch.term',
     201                                                        [key, value.class] as Object[],
     202                                                        'Property {0} must be of type Term and is currently of type {1}'
     203                                                )
     204                                        }
     205                                }
     206                        }
     207                        return (!error)
     208                })
    46209        }
    47210
     
    177340                if (templates.size() == 0) {
    178341                        throw new NoSuchFieldException("No templates found in collection!")
    179                 }
    180                 else if (templates.size() == 1) {
     342                } else if (templates.size() == 1) {
    181343                        return templates[0];
    182                 }
    183                 else {
     344                } else {
    184345                        throw new NoSuchFieldException("Multiple templates found in collection!")
    185346                }
    186347        }
    187 
    188         def validate() {
    189                 return super.validate()
    190         }
    191348}
  • trunk/grails-app/i18n/messages.properties

    r70 r332  
    5454typeMismatch.java.math.BigDecimal=Property {0} must be a valid number
    5555typeMismatch.java.math.BigInteger=Property {0} must be a valid number
     56
     57// TemplateEntity errors
     58templateEntity.typeMismatch.integer=Property {0} must be of type Integer and is currently of type {1}
     59templateEntity.typeMismatch.string=Property {0} must be of type String and is currently of type {1}
     60templateEntity.typeMismatch.templateFieldListItem=Property {0} must be of type TemplateFieldListItem and is currently of type {1}
     61templateEntity.typeMismatch.float=Property {0} must be of type Float and is currently of type {1}
     62templateEntity.typeMismatch.double=Property {0} must be of type Double and is currently of type {1}
     63templateEntity.typeMismatch.date=Property {0} must be of type Date and is currently of type {1}
     64templateEntity.typeMismatch.term=Property {0} must be of type Term and is currently of type {1}
  • trunk/grails-app/views/wizard/common/_error.gsp

    r299 r332  
    2828                // mark error fields
    2929                <g:each in="${errors}" var="error">
     30                var element = $("input:[name='${error.key}'], input:[name='${error.key.toLowerCase().replaceAll("([^a-z0-9])","_")}'], select:[name='${error.key}'], select:[name='${error.key.toLowerCase().replaceAll("([^a-z0-9])","_")}']");
    3031                <g:if test="${error.value['dynamic']}">
    31                 $("input:[name='${error.key}'], select:[name='${error.key}']").addClass('error');
     32                element.addClass('error');
    3233                </g:if><g:else>
    33                 $("input:[name='${error.key}'], select:[name='${error.key}']").parent().parent().addClass('error');
     34                element.parent().parent().addClass('error');
    3435                </g:else>
    3536                </g:each>
Note: See TracChangeset for help on using the changeset viewer.