Changeset 1260


Ignore:
Timestamp:
Dec 10, 2010, 3:12:28 PM (13 years ago)
Author:
work@…
Message:
  • resolves #198, user friendly error messages in wizard
Location:
trunk/grails-app
Files:
4 edited

Legend:

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

    r1227 r1260  
    88import dbnp.authentication.AuthenticationService
    99import dbnp.authentication.SecUser
     10import org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib
    1011
    1112
     
    3031class WizardController {
    3132        def authenticationService
     33        def validationTagLib = new ValidationTagLib()   
    3234
    3335        /**
     
    145147                                        }
    146148                                } else if (flow.jump && flow.jump.action == 'create') {
     149                                        if (!flow.study) flow.study = new Study()
    147150                                        toStudyPage()
    148151                                } else {
     
    167170                                // clean the flow scope
    168171                                flow.remove('study')
     172
     173                                // create a new study instance
     174                                if (!flow.study) flow.study = new Study()                               
    169175
    170176                                // set 'quicksave' variable to false
     
    469475                                // remove eventGroup
    470476                                def eventGroupToRemove = flow.study.eventGroups.find { it.getIdentifier() == (params.get('do') as int) }
    471                                 if (eventGroupToRemove) {
    472                                         println flow.study.deleteEventGroup( eventGroupToRemove )
    473                                 }
    474477                        }.to "events"
    475478                        on("previous") {
     
    664667                                    flow.assay.setFieldValue(
    665668                                            'externalAssayID',
    666                                             this.ucwords(flow.study.code).replaceAll("([ ]{1,})", "") + '_' + this.ucwords(template.name).replaceAll("([ ]{1,})", "")
     669                                            ucwords(flow.study.code).replaceAll("([ ]{1,})", "") + '_' + ucwords(template.name).replaceAll("([ ]{1,})", "")
    667670                                    )
    668671                            }
     
    673676                                    flow.assay.setFieldValue(
    674677                                            'externalAssayID',
    675                                             this.ucwords(flow.study.code).replaceAll("([ ]{1,})", "") + '_' + this.ucwords(template.name).replaceAll("([ ]{1,})", "")
     678                                            ucwords(flow.study.code).replaceAll("([ ]{1,})", "") + '_' + ucwords(template.name).replaceAll("([ ]{1,})", "")
    676679                                    )
    677680                            }
     
    708711                        }.to "assays"
    709712                        on("deleteAssay") {
    710                                 println params
    711 
    712713                                // handle form data
    713714                                assayPage(flow, flash, params)
     
    908909         */
    909910        def loadStudy(flow, flash, params, user) {
    910                 flash.wizardErrors = new LinkedHashMap()
     911                flash.wizardErrors      = [:]
    911912               
    912913                // load study
     
    960961         */
    961962        def studyPage(flow, flash, params) {
    962                 // remember the params in the flash scope
    963                 flash.values = params
     963                flash.values            = params
     964                flash.wizardErrors      = [:]
    964965
    965966                // instantiate study of it is not yet present
     
    968969                // did the study template change?
    969970                if (params.get('template').size() && flow.study.template?.name != params.get('template')) {
    970                         println ".change study template!"
    971 
    972                         // yes, was the template already set?
    973                         if (flow.study.template instanceof Template) {
    974                                 // yes, first make sure all values are unset?
    975                                 println "!!! check the database fields if data of a previous template remains in the database or is deleted by GORM!"
    976                         }
    977 
    978971                        // set the template
    979972                        flow.study.template = Template.findByName(params.remove('template'))
     
    1004997                }
    1005998
    1006                 // validate the study
    1007                 if (flow.study.validate()) {
    1008                         // instance is okay
    1009                         return true
     999                // have we got a template?
     1000                if (flow.study.template && flow.study.template instanceof Template) {
     1001                        // validate the study
     1002                        if (flow.study.validate()) {
     1003                                // instance is okay
     1004                                return true
     1005                        } else {
     1006                                // validation failed
     1007                                this.appendErrors(flow.study, flash.wizardErrors)
     1008                                return false
     1009                        }
    10101010                } else {
    1011                         // validation failed
    1012                         flash.wizardErrors = [:]
    1013                         this.appendErrors(flow.study, flash.wizardErrors)
     1011                        // no, return an error that the template is not set
     1012                        this.appendErrorMap(['template': g.message(code: 'select.not.selected.or.add', args: ['template'])], flash.wizardErrors)
    10141013                        return false
    10151014                }
     
    10241023         */
    10251024        def handlePublications(flow, flash, params) {
     1025                flash.wizardErrors      = [:]
     1026
    10261027                if (!flow.study.publications) flow.study.publications = []
    10271028
     
    10651066         */
    10661067        def handleContacts(flow, flash, params) {
     1068                flash.wizardErrors      = [:]
     1069
    10671070                if (!flow.study.persons) flow.study.persons = []
    10681071
     
    11261129         */
    11271130        def handleUsers(flow, flash, params, type) {
     1131                flash.wizardErrors = [:]
     1132
    11281133                def users = []
    11291134
     
    11401145
    11411146                // Users are saved as user_id
    1142                 def userIDs = params.get( type + '_ids')
     1147                def userIDs = params.get(type + '_ids')
    11431148                if (userIDs) {
    11441149                        // Find the individual IDs and make integers
     
    11531158                                        def user = SecUser.get(id)
    11541159                                        if (user) {
    1155                                             users.add(user)
     1160                                                users.add(user)
    11561161                                        } else {
    11571162                                                log.info('.user with ID ' + id + ' not found in database.')
     
    11671172                if (type == "readers") {
    11681173                        if (flow.study.readers)
    1169                         flow.study.readers.clear()
     1174                                flow.study.readers.clear()
    11701175                        users.each { flow.study.addToReaders(it) }
    11711176                } else if (type == "writers") {
    11721177                        if (flow.study.writers)
    1173                         flow.study.writers.clear()
     1178                                flow.study.writers.clear()
    11741179
    11751180                        users.each { flow.study.addToWriters(it) }
    11761181                }
    1177         }
     1182        }
    11781183
    11791184        /**
     
    12861291                        errors = true
    12871292                        if (number < 1) this.appendErrorMap(['addNumber': 'Enter a positive number of subjects to add'], flash.wizardErrors)
    1288                         if (!species)   this.appendErrorMap(['species': 'You need to select a species, or add one if it is not yet present'], flash.wizardErrors)
    1289                         if (!template)  this.appendErrorMap(['template': 'You need to select a template, or add one if it is not yet present'], flash.wizardErrors)
     1293                        if (!species)   this.appendErrorMap(['species': g.message(code: 'select.not.selected.or.add', args: ['species'])], flash.wizardErrors)
     1294                        if (!template)  this.appendErrorMap(['template': g.message(code: 'select.not.selected.or.add', args: ['template'])], flash.wizardErrors)
    12901295                }
    12911296
     
    13531358                                                        eventGroup.subjects.each() { subject ->
    13541359                                                                // instantiate a sample for this subject / event
    1355                                                                 def samplingEventName = this.ucwords(event.template.name)
    1356                                                                 def eventGroupName = this.ucwords(eventGroup.name).replaceAll("([ ]{1,})", "")
    1357                                                                 def sampleName = (this.ucwords(subject.name) + '_' + samplingEventName + '_' + eventGroupName + '_' + new RelTime(event.startTime).toString()).replaceAll("([ ]{1,})", "")
     1360                                                                def samplingEventName = ucwords(event.template.name)
     1361                                                                def eventGroupName = ucwords(eventGroup.name).replaceAll("([ ]{1,})", "")
     1362                                                                def sampleName = (ucwords(subject.name) + '_' + samplingEventName + '_' + eventGroupName + '_' + new RelTime(event.startTime).toString()).replaceAll("([ ]{1,})", "")
    13581363                                                                def tempSampleIterator = 0
    13591364                                                                def tempSampleName = sampleName
     
    14501455                                                // iterate through samplingEvents
    14511456                                                eventGroup.samplingEvents.each() { samplingEvent ->
    1452                                                         def samplingEventName = this.ucwords(samplingEvent.template.name)
    1453                                                         def eventGroupName = this.ucwords(eventGroup.name)
    1454                                                         def sampleName = (this.ucwords(subject.name) + '_' + samplingEventName + '_' + eventGroupName + '_' + new RelTime(samplingEvent.startTime).toString()).replaceAll("([ ]{1,})", "")
     1457                                                        def samplingEventName = ucwords(samplingEvent.template.name)
     1458                                                        def eventGroupName = ucwords(eventGroup.name)
     1459                                                        def sampleName = (ucwords(subject.name) + '_' + samplingEventName + '_' + eventGroupName + '_' + new RelTime(samplingEvent.startTime).toString()).replaceAll("([ ]{1,})", "")
    14551460                                                        def tempSampleIterator = 0
    14561461                                                        def tempSampleName = sampleName
     
    16091614                        flow.study.assays.each() { assay ->
    16101615                                if (params.get( 'sample_' + sample.getIdentifier() + '_assay_' + assay.getIdentifier() )) {
    1611                                         println "add sample "+sample.getIdentifier()+" to assay "+assay.getIdentifier()
    16121616                                        // add sample to assay
    16131617                                        assay.addToSamples( sample )
     
    16161620                                        assay.removeFromSamples( sample )
    16171621                                }
    1618                                 println assay.samples
    16191622                        }
    16201623                }
     
    16311634         * @return String
    16321635         */
    1633         def ucwords(String text) {
     1636        public static ucwords(String text) {
    16341637                def newText = ''
    16351638
     
    16701673        def getHumanReadableErrors(object) {
    16711674                def errors = [:]
    1672                 object.errors.getAllErrors().each() {
    1673                         def message = it.toString()
    1674 
    1675                         //errors[it.getArguments()[0]] = it.getDefaultMessage()
    1676                         errors[it.getArguments()[0]] = message.substring(0, message.indexOf(';'))
     1675                object.errors.getAllErrors().each() { error ->
     1676                        // error.codes.each() { code -> println code }
     1677
     1678                        // generally speaking g.message(...) should work,
     1679                        // however it fails in some steps of the wizard
     1680                        // (add event, add assay, etc) so g is not always
     1681                        // availably. Using our own instance of the
     1682                        // validationTagLib instead so it is always
     1683                        // available to us
     1684                        errors[ error.getArguments()[0] ] = validationTagLib.message(error: error)
    16771685                }
    16781686
     
    16871695         */
    16881696        def appendErrors(object, map) {
    1689                 this.appendErrorMap(this.getHumanReadableErrors(object), map)
     1697                this.appendErrorMap(getHumanReadableErrors(object), map)
    16901698        }
    16911699
    16921700        def appendErrors(object, map, prepend) {
    1693                 this.appendErrorMap(this.getHumanReadableErrors(object), map, prepend)
     1701                this.appendErrorMap(getHumanReadableErrors(object), map, prepend)
    16941702        }
    16951703
  • trunk/grails-app/i18n/messages.properties

    r1167 r1260  
    5555typeMismatch.java.math.BigInteger=Property {0} must be a valid number
    5656
    57 // TemplateEntity errors
    58 templateEntity.typeMismatch.integer=Property {0} must be of type Integer and is currently of type {1}
    59 templateEntity.typeMismatch.string=Property {0} must be of type String and is currently of type {1}
    60 templateEntity.tooLong.string=Property {0} may contain at most 255 characters.
     57# Generic error messages
     58nullable={0} is required and may not be left blank
     59select.not.selected=You need to select a {0}
     60select.not.selected.or.add=You need to select a {0}, or add one if it is not yet present
     61
     62# TemplateEntity errors
     63templateEntity.typeMismatch.long={0} has to be an absolute number (without comma's)
     64templateEntity.typeMismatch.double={0} must be a number
     65templateEntity.typeMismatch.integer={0} must be a number
     66templateEntity.typeMismatch.string={0} must be a text (maximum 255 characters)
     67templateEntity.tooLong.string={0} may contain at most 255 characters
    6168templateEntity.typeMismatch.templateFieldListItem=Property {0} must be of type TemplateFieldListItem and is currently of type {1}
    62 templateEntity.typeMismatch.float=Property {0} must be of type Float and is currently of type {1}
    63 templateEntity.typeMismatch.double=Property {0} must be of type Double and is currently of type {1}
    64 templateEntity.typeMismatch.date=Property {0} must be of type Date and is currently of type {1}
    65 templateEntity.typeMismatch.term=Property {0} must be of type Term and is currently of type {1}
    66 
     69templateEntity.typeMismatch.date={0} must be a date
     70templateEntity.typeMismatch.term={0} must be an ontology term
    6771event.endTime.greaterThanStartTime=End time should be greater than or equal to the Start Time
  • trunk/grails-app/i18n/messages_nl.properties

    r1181 r1260  
    5454typeMismatch.java.math.BigDecimal=Attribuut {0} is geen geldig nummer
    5555typeMismatch.java.math.BigInteger=Attribuut {0} is geen geldig nummer
     56
     57# Generic error messages
     58nullable={0} is verplicht en mag niet leeg zijn
     59select.not.selected=Je moet een {0} kiezen
     60select.not.selected.or.add=Je moet een {0} kiezen, of er een toevoegen als hij nog niet bestaat
     61
     62
     63# Template entity meesages
     64templateEntity.typeMismatch.long={0} moet een absoluut getal zijn (zonder komma's)
     65templateEntity.typeMismatch.double={0} moet een getal zijn
     66templateEntity.typeMismatch.integer={0} moet een getal zijn
     67templateEntity.typeMismatch.string={0} moest een tekst zijn (maximum 255 karakters)
     68templateEntity.tooLong.string={0} maar maar 255 karakters bevatten
     69templateEntity.typeMismatch.templateFieldListItem={0} moet van het type TemplateFieldListItem zijn en momenteel is het een {1} instantie
     70templateEntity.typeMismatch.date={0} moet een datum zijn
     71templateEntity.typeMismatch.term={0} must ontology term zijn
     72event.endTime.greaterThanStartTime=de eindtijd moet groter of gelijk zijn aan de begin tijd
  • trunk/grails-app/views/wizard/common/_error.gsp

    r1149 r1260  
    2727                // mark error fields
    2828                <g:each in="${wizardErrors}" var="error">
    29                 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])","_")}']");
     29                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])","_")}'], textarea:[name='${error.key}'], textarea:[name='${error.key.toLowerCase().replaceAll("([^a-z0-9])","_")}']");
    3030                 <g:if test="${error.value['dynamic']}">
    3131                element.addClass('error');
Note: See TracChangeset for help on using the changeset viewer.