Changeset 390


Ignore:
Timestamp:
May 3, 2010, 3:55:29 PM (14 years ago)
Author:
duh
Message:
  • refactored TemplateEntity? to check for and handle event + domain fields properly
  • refactored wizard event page to

1) display events seperated in event templates
2) display cross-template event groups

  • todo: event fields are not yet properly handled
Location:
trunk/grails-app
Files:
4 edited

Legend:

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

    r389 r390  
    242242                                flow.page = 4
    243243
     244                                /*
    244245                                if (!flow.event) flow.event = new Event()
    245246                                if (!flow.events) flow.events = []
     
    247248                                        flow.eventGroups = []
    248249                                        flow.eventGroups[0] = new EventGroup(name: 'Group 1')   // 1 group by default
     250                                }
     251                                */
     252
     253                                if (!flow.event) {
     254                                        flow.event                      = new Event()
     255                                        flow.events                     = []
     256                                        flow.eventGroups        = []
     257                                        flow.eventGroups[0]     = new EventGroup(name: 'Group 1')       // 1 group by default
     258                                        flow.eventTemplates     = [:]
    249259                                }
    250260                        }
     
    303313                                }
    304314                                */
    305                                 flash.values = params
     315                                flash.values                    = params
     316                                def eventTemplateName   = params.get('template')
     317                                def eventTemplate               = Template.findByName(eventTemplateName)
     318
     319                                // add this event template to the event template array
     320                                if (!flow.eventTemplates[ eventTemplateName ]) {
     321                                        flow.eventTemplates[ eventTemplateName ] = [
     322                                                name: eventTemplateName,
     323                                                template: eventTemplate,
     324                                                events: []
     325                                        ]
     326                                }
    306327
    307328                                // handle study data
     
    310331                                // validate event object
    311332                                if (flow.event.validate()) {
    312                                         //flow.events[ flow.events.size() ] = flow.event
     333
     334flow.event.template.fields.each() {
     335        println "["+it.name+"] = "+flow.event.getFieldValue(it.name)   
     336}
     337                                        // it validated! Duplicate the event object...
     338                                        def newEvent    = flow.event
     339                                        def increment   = flow.events.size()
     340
     341                                        // ...store it in the events map in the flow scope...
     342                                        flow.events[ increment ] = newEvent
     343
     344                                        // ...and 'reset' the event object in the flow scope
     345                                        flow.event = new Event(template: newEvent.template)
     346                                       
     347                                        // remember the event id with the template
     348                                        def eventSize = flow.eventTemplates[ eventTemplateName ]['events'].size()
     349                                        flow.eventTemplates[ eventTemplateName ]['events'][ eventSize ] = increment
     350
    313351                                        success()
    314352                                } else {
     353                                        // it does not validate, show error feedback
    315354                                        flash.errors = [:]
    316355                                        this.appendErrors(flow.event, flash.errors)
     
    382421                                flash.values = params
    383422                                flash.errors = [:]
     423                                /*
    384424
    385425                                // handle event groupings
     
    394434                                        error()
    395435                                }
    396                         }.to "confirm"
     436                                */
     437                        }.to "events"
    397438                }
    398439
     
    524565        }
    525566
     567        /**
     568         * re-usable code for handling study form data in a web flow
     569         * @param Map LocalAttributeMap (the flow scope)
     570         * @param Map localAttributeMap (the flash scope)
     571         * @param Map GrailsParameterMap (the flow parameters = form data)
     572         * @returns boolean
     573         */
     574        def handleStudy(flow, flash, params) {
     575                // create study instance if we have none
     576                if (!flow.study) flow.study = new Study();
     577
     578                // create date instance from date string?
     579                // @see WizardTagLibrary::dateElement{...}
     580                if (params.get('startDate')) {
     581                        params.startDate = new Date().parse("d/M/yyyy", params.get('startDate').toString())
     582                } else {
     583                        params.remove('startDate')
     584                }
     585
     586                // if a template is selected, get template instance
     587                def template = params.remove('template')
     588                if (template instanceof String && template.size() > 0) {
     589                        params.template = Template.findByName(template)
     590                } else if (template instanceof Template) {
     591                        params.template = template
     592                }
     593
     594                // update study instance with parameters
     595                params.each() { key, value ->
     596                        if (flow.study.hasProperty(key)) {
     597                                flow.study.setProperty(key, value);
     598                        }
     599                }
     600
     601                // walk through template fields
     602                if (params.template) {
     603                        params.template.fields.each() { field ->
     604                                flow.study.setFieldValue(field.name, params.get(field.escapedName()))
     605                        }
     606                }
     607
     608                // validate study
     609                if (flow.study.validate()) {
     610                        return true
     611                } else {
     612                        // validation failed, feedback errors
     613                        flash.errors = [:]
     614                        this.appendErrors(flow.study, flash.errors)
     615                        return false
     616                }
     617        }
     618
     619        /**
     620         * re-usable code for handling subject form data in a web flow
     621         * @param Map LocalAttributeMap (the flow scope)
     622         * @param Map localAttributeMap (the flash scope)
     623         * @param Map GrailsParameterMap (the flow parameters = form data)
     624         * @returns boolean
     625         */
     626        def handleSubjects(flow, flash, params) {
     627                def names = [:];
     628                def errors = false;
     629                def id = 0;
     630
     631                // iterate through subject templates
     632                flow.subjectTemplates.each() {
     633                        def subjectTemplate = it.getValue().template
     634                        def templateFields      = subjectTemplate.fields
     635
     636                        // iterate through subjects
     637                        it.getValue().subjects.each() { subjectId ->
     638                                flow.subjects[ subjectId ].name = params.get('subject_' + subjectId + '_name')
     639                                flow.subjects[ subjectId ].species = Term.findByName(params.get('subject_' + subjectId + '_species'))
     640
     641                                // remember name and check for duplicates
     642                                if (!names[ flow.subjects[ subjectId ].name ]) {
     643                                        names[ flow.subjects[ subjectId ].name ] = [count: 1, first: 'subject_' + subjectId + '_name', firstId: subjectId]
     644                                } else {
     645                                        // duplicate name found, set error flag
     646                                        names[ flow.subjects[ subjectId ].name ]['count']++
     647
     648                                        // second occurence?
     649                                        if (names[ flow.subjects[ subjectId ].name ]['count'] == 2) {
     650                                                // yeah, also mention the first
     651                                                // occurrence in the error message
     652                                                this.appendErrorMap(name: 'The subject name needs to be unique!', flash.errors, 'subject_' + names[ flow.subjects[ subjectId ].name ]['firstId'] + '_')
     653                                        }
     654
     655                                        // add to error map
     656                                        this.appendErrorMap([name: 'The subject name needs to be unique!'], flash.errors, 'subject_' + subjectId + '_')
     657                                        errors = true
     658                                }
     659
     660                                // iterate through template fields
     661                                templateFields.each() { subjectField ->
     662                                        flow.subjects[ subjectId ].setFieldValue(
     663                                                subjectField.name,
     664                                                params.get( 'subject_' + subjectId + '_' + subjectField.escapedName() )
     665                                        )
     666                                }
     667
     668                                // validate subject
     669                                if (!flow.subjects[ subjectId ].validate()) {
     670                                        errors = true
     671                                        this.appendErrors(flow.subjects[ subjectId ], flash.errors, 'subject_' + subjectId + '_')
     672                                }
     673                        }
     674                }
     675
     676                return !errors
     677        }
    526678
    527679        /**
     
    548700                // set template
    549701                if (params.template) flow.event.template = params.template
    550 println flow.event.template
    551 println params
    552                
     702
    553703                // update event instance with parameters
    554704                params.each() { key, value ->
    555                         try {
     705                        // does this event have such a property or (if
     706                        // a template is set) such a template field?
     707                        if (flow.event.fieldExists(key)) {
     708                                // yes, set it
    556709                                flow.event.setFieldValue(key, value)
    557                                 println "has "+key
    558                         } catch (Exception e) {
    559                                 println "does NOT have "+key
    560                         }
    561                         /*
    562                         if (flow.event.hasProperty(key)) {
    563 println "has property " +  key
    564                                 flow.event.setProperty(key, value);
    565                         }
    566                         */
    567                 }
    568         }
    569 
    570         /**
    571          * re-usable code for handling study form data in a web flow
    572          * @param Map LocalAttributeMap (the flow scope)
    573          * @param Map localAttributeMap (the flash scope)
    574          * @param Map GrailsParameterMap (the flow parameters = form data)
    575          * @returns boolean
    576          */
    577         def handleStudy(flow, flash, params) {
    578                 // create study instance if we have none
    579                 if (!flow.study) flow.study = new Study();
    580 
    581                 // create date instance from date string?
    582                 // @see WizardTagLibrary::dateElement{...}
    583                 if (params.get('startDate')) {
    584                         params.startDate = new Date().parse("d/M/yyyy", params.get('startDate').toString())
    585                 } else {
    586                         params.remove('startDate')
    587                 }
    588 
    589                 // if a template is selected, get template instance
    590                 def template = params.remove('template')
    591                 if (template instanceof String && template.size() > 0) {
    592                         params.template = Template.findByName(template)
    593                 } else if (template instanceof Template) {
    594                         params.template = template
    595                 }
    596 
    597                 // update study instance with parameters
    598                 params.each() { key, value ->
    599                         if (flow.study.hasProperty(key)) {
    600                                 flow.study.setProperty(key, value);
    601                         }
    602                 }
    603 
    604                 // walk through template fields
    605                 if (params.template) {
    606                         params.template.fields.each() { field ->
    607                                 flow.study.setFieldValue(field.name, params.get(field.escapedName()))
    608                         }
    609                 }
    610 
    611                 // validate study
    612                 if (flow.study.validate()) {
    613                         return true
    614                 } else {
    615                         // validation failed, feedback errors
    616                         flash.errors = [:]
    617                         this.appendErrors(flow.study, flash.errors)
    618                         return false
    619                 }
    620         }
    621 
    622         /**
    623          * re-usable code for handling eventDescription form data in a web flow
    624          * @param Map LocalAttributeMap (the flow scope)
    625          * @param Map localAttributeMap (the flash scope)
    626          * @param Map GrailsParameterMap (the flow parameters = form data)
    627          * @returns boolean
    628          */
    629         def handleEventDescriptions(flow, flash, params) {
    630                 def names = [:]
    631                 def errors = false
    632                 def id = 0
    633 
    634                 flow.eventDescriptions.each() {
    635                         it.name = params.get('eventDescription_' + id + '_name')
    636                         it.description = params.get('eventDescription_' + id + '_description')
    637                         it.protocol = Protocol.findByName(params.get('eventDescription_' + id + '_protocol'))
    638                         //it.classification = Term.findByName(params.get('eventDescription_' + id + '_classification'))
    639                         it.isSamplingEvent = (params.containsKey('eventDescription_' + id + '_isSamplingEvent'))
    640 
    641                         // validate eventDescription
    642                         if (!it.validate()) {
    643                                 errors = true
    644                                 this.appendErrors(it, flash.errors, 'eventDescription_' + id + '_')
    645                         }
    646 
    647                         id++
    648                 }
     710                        }
     711                }
     712
     713                // handle event objects
     714                flow.eventTemplates.each() {
     715                        def eventTemplate       = it.getValue().template
     716                        def templateFields      = eventTemplate.fields
     717
     718                        // iterate through events
     719                        it.getValue().events.each() { eventId ->
     720                                // iterate through template fields
     721                                templateFields.each() { eventField ->
     722                                        flow.events[ eventId ].setFieldValue(
     723                                                eventField.name,
     724                                                params.get( 'event_' + eventId + '_' + eventField.escapedName() )
     725                                        )
     726                                }
     727
     728                                // validate event
     729                                if (!flow.events[ eventId ].validate()) {
     730                                        errors = true
     731                                        this.appendErrors(flow.events[ eventId ], flash.errors, 'event_' + eventId + '_')
     732                                }
     733
     734
     735                        }
     736                }
     737
     738                // handle event grouping
     739                handleEventGrouping(flow, flash, params)
     740
     741                println flow.event
    649742
    650743                return !errors
     
    680773
    681774        /**
    682          * re-usable code for handling subject form data in a web flow
    683          * @param Map LocalAttributeMap (the flow scope)
    684          * @param Map localAttributeMap (the flash scope)
    685          * @param Map GrailsParameterMap (the flow parameters = form data)
    686          * @returns boolean
    687          */
    688         def handleSubjects(flow, flash, params) {
    689                 def names = [:];
    690                 def errors = false;
    691                 def id = 0;
    692 
    693                 // iterate through subject templates
    694                 flow.subjectTemplates.each() {
    695                         def subjectTemplate = it.getValue().template
    696                         def templateFields      = subjectTemplate.fields
    697 
    698                         // iterate through subjects
    699                         it.getValue().subjects.each() { subjectId ->
    700                                 flow.subjects[ subjectId ].name = params.get('subject_' + subjectId + '_name')
    701                                 flow.subjects[ subjectId ].species = Term.findByName(params.get('subject_' + subjectId + '_species'))
    702 
    703                                 // remember name and check for duplicates
    704                                 if (!names[ flow.subjects[ subjectId ].name ]) {
    705                                         names[ flow.subjects[ subjectId ].name ] = [count: 1, first: 'subject_' + subjectId + '_name', firstId: subjectId]
    706                                 } else {
    707                                         // duplicate name found, set error flag
    708                                         names[ flow.subjects[ subjectId ].name ]['count']++
    709 
    710                                         // second occurence?
    711                                         if (names[ flow.subjects[ subjectId ].name ]['count'] == 2) {
    712                                                 // yeah, also mention the first
    713                                                 // occurrence in the error message
    714                                                 this.appendErrorMap(name: 'The subject name needs to be unique!', flash.errors, 'subject_' + names[ flow.subjects[ subjectId ].name ]['firstId'] + '_')
    715                                         }
    716 
    717                                         // add to error map
    718                                         this.appendErrorMap([name: 'The subject name needs to be unique!'], flash.errors, 'subject_' + subjectId + '_')
    719                                         errors = true
    720                                 }
    721 
    722                                 // iterate through template fields
    723                                 templateFields.each() { subjectField ->
    724                                         flow.subjects[ subjectId ].setFieldValue(
    725                                                 subjectField.name,
    726                                                 params.get( 'subject_' + subjectId + '_' + subjectField.escapedName() )
    727                                         )
    728                                 }
    729 
    730                                 // validate subject
    731                                 if (!flow.subjects[ subjectId ].validate()) {
    732                                         errors = true
    733                                         this.appendErrors(flow.subjects[ subjectId ], flash.errors, 'subject_' + subjectId + '_')
    734                                 }
    735                         }
    736                 }
    737 
    738                 return !errors
    739         }
    740 
    741         /**
    742775         * return the object from a map of objects by searching for a name
    743776         * @param String name
  • trunk/grails-app/domain/dbnp/studycapturing/TemplateEntity.groovy

    r389 r390  
    270270         */
    271271        def fieldExists(String fieldName) {
    272                 TemplateFieldType fieldType = template.getFieldType(fieldName)
    273 
    274                 // If the field is found, a TemplateFieldType is returned
    275                 // otherwise null
    276                 if (fieldType) {
    277                     return true
    278                 } else {
    279                     return false
    280                 }
     272                // escape the fieldName for easy matching
     273                // (such escaped names are commonly used
     274                // in the HTTP forms of this application)
     275                def escapedLowerCaseFieldName = fieldName.toLowerCase().replaceAll("([^a-z0-9])","_")
     276
     277                // check if this domain class has got this property
     278                if (this.properties.containsKey(fieldName)) {
     279                        // domain class contains this property
     280                        return true
     281                } else if (template == null) {
     282                        // no, and we haven't got a template set either
     283                        return false
     284                } else {
     285                        // the domain class doesn't have this property but
     286                        // it has a template defined. Check the template
     287                        // fields to see if such a template field exists
     288                        TemplateField field = this.template.fields.find { it.name.toLowerCase().replaceAll("([^a-z0-9])","_") == escapedLowerCaseFieldName }
     289
     290                        // does the template field exist?
     291                        if (field == null) {
     292                                // no such template field
     293                                return false
     294                        } else {
     295                                // found!
     296                                return true
     297                        }
     298                }
    281299        }
    282300
     
    287305         */
    288306        def setFieldValue(String fieldName, value) {
     307                // escape the fieldName for easy matching
     308                // (such escaped names are commonly used
     309                // in the HTTP forms of this application)
     310                def escapedLowerCaseFieldName = fieldName.toLowerCase().replaceAll("([^a-z0-9])","_")
     311
    289312                // First, search if there is an entity property with the given name, and if so, set that
    290313                if (this.properties.containsKey(fieldName)) {
     
    296319                        // there is a template, check the template fields
    297320                        // Find the target template field, if not found, throw an error
    298                         TemplateField field = this.template.fields.find { it.name == fieldName }
     321                        TemplateField field = this.template.fields.find { it.name.toLowerCase().replaceAll("([^a-z0-9])","_") == escapedLowerCaseFieldName }
    299322
    300323                        if (field == null) {
     
    306329                                if (field.type == TemplateFieldType.STRINGLIST && value && value.class == String) {
    307330                                        // Kees insensitive pattern matching ;)
    308                                         value = field.listEntries.find { it.name ==~ /(?i)($value)/ }
     331                                        def escapedLowerCaseValue = value.toLowerCase().replaceAll("([^a-z0-9])","_")
     332                                        value = field.listEntries.find {
     333                                                it.name.toLowerCase().replaceAll("([^a-z0-9])","_") == escapedLowerCaseValue
     334                                        }
    309335                                }
    310336
  • trunk/grails-app/taglib/dbnp/studycapturing/WizardTagLib.groovy

    r389 r390  
    689689                def renderType  = attrs.remove('renderType')
    690690                def entity              = (attrs.get('entity'))
    691                 println entity
    692                 println entity.class
    693                 println entity instanceof TemplateEntity
     691                def prependName = (attrs.get('name')) ? attrs.remove('name')+'_' : ''
    694692                def template    = (entity && entity instanceof TemplateEntity) ? entity.template : null
    695693                def inputElement= null
     
    711709                                                out << "$inputElement"(
    712710                                                        description: it.name,
    713                                                         name: it.escapedName(),
     711                                                        name: prependName + it.escapedName(),
    714712                                                        value: fieldValue
    715713                                                )
     
    720718                                                        out << "$inputElement"(
    721719                                                                description: it.name,
    722                                                                 name: it.escapedName(),
     720                                                                name: prependName + it.escapedName(),
    723721                                                                from: it.listEntries,
    724722                                                                value: fieldValue
     
    733731                                                inputElement = (renderType == 'element') ? 'textFieldElement' : 'textField'
    734732                                                out << "$inputElement"(
    735                                                         name: it.escapedName(),
     733                                                        name: prependName + it.escapedName(),
    736734                                                        value: fieldValue,
    737735                                                        rel: 'ontology-all-name',
     
    739737                                                )
    740738                                                out << hiddenField(
    741                                                         name: it.name + '-concept_id',
     739                                                        name: prependName + it.name + '-concept_id',
    742740                                                        value: fieldValue
    743741                                                )
    744742                                                out << hiddenField(
    745                                                         name: it.escapedName() + '-ontology_id',
     743                                                        name: prependName + it.escapedName() + '-ontology_id',
    746744                                                        value: fieldValue
    747745                                                )
    748746                                                out << hiddenField(
    749                                                         name: it.escapedName() + '-full_id',
     747                                                        name: prependName + it.escapedName() + '-full_id',
    750748                                                        value: fieldValue
    751749                                                )
     
    768766                                                out << "$inputElement"(
    769767                                                        description: it.name,
    770                                                         name: it.escapedName(),
     768                                                        name: prependName + it.escapedName(),
    771769                                                        value: fieldValue,
    772770                                                        rel: 'date'
  • trunk/grails-app/views/wizard/pages/_events.gsp

    r389 r390  
    2626        <g:if test="${event?.template}"><wizard:templateElements entity="${event}" /></g:if>
    2727        <g:if test="${event?.template}"><wizard:buttonElement name="add" value="Add" url="[controller:'wizard',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()"/></g:if>
     28
     29<g:if test="${events}">
     30        <g:each var="eventTemplate" in="${eventTemplates}">
     31                <h1>${eventTemplate.getValue().name} template</h1>
     32        <div class="table">
     33                <div class="header">
     34                        <div class="firstColumn">#</div>
     35                        <div class="firstColumn"></div>
     36                        <wizard:templateColumnHeaders template="${eventTemplate.getValue().template}" class="column"/>
     37                        <g:if test="${eventGroups}"><g:each var="eventGroup" status="g" in="${eventGroups}">
     38                        <div class="column">
     39                                <g:textField name="eventGroup_${g}_name" value="${eventGroup.name}" />
     40                                <wizard:ajaxButton name="deleteEventGroup" src="../images/icons/famfamfam/delete.png" alt="delete this eventgroup" class="famfamfam" value="-" url="[controller:'wizard',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" before="\$(\'input[name=do]\').val(${g});" afterSuccess="onWizardPage()" />
     41                        </div>
     42                        </g:each></g:if>
     43                        <div class="column">
     44                                <wizard:ajaxButton name="addEventGroup" src="../images/icons/famfamfam/add.png" alt="add a new eventgroup" class="famfamfam" value="+" url="[controller:'wizard',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()" />
     45                        </div>
     46                </div>
     47                <g:each var="eventId" in="${eventTemplate.getValue().events}">
     48                        <div class="row">
     49                                <div class="firstColumn">${eventId + 1}</div>
     50                                <div class="firstColumn">
     51                                        <wizard:ajaxButton name="delete" src="../images/icons/famfamfam/delete.png" alt="delete this subject" class="famfamfam" value="-" url="[controller:'wizard',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" before="\$(\'input[name=do]\').val(${eventId});" afterSuccess="onWizardPage()"/>
     52                                </div>
     53                                <wizard:templateColumns id="${eventId}" entity="${events[ eventId ]}" template="${events[ eventId ].template}" name="event_${eventId}" class="column" />
     54                                <g:if test="${eventGroups}"><g:each var="eventGroup" status="j" in="${eventGroups}">
     55                                <div class="column">
     56                                        <g:if test="${eventGroup.events.find{ it == event} }">
     57                                                <input type="checkbox" name="event_${eventId}_group_${j}" checked="checked" />
     58                                        </g:if><g:else>
     59                                                <input type="checkbox" name="event_${eventId}_group_${j}"/>
     60                                        </g:else>
     61                                </div>
     62                                </g:each></g:if>
     63                                <div class="column"></div>
     64                        </div>
     65                </g:each>
     66        </div>
     67        <div class="sliderContainer">
     68                <div class="slider"></div>
     69        </div>
     70        </g:each>
     71</g:if>
     72
    2873<% /*
    29 <g:if test="${events}">
     74        ----- START ----- <br/>
    3075        <g:each var="event" status="i" in="${events}">
    3176        <div class="table">
     
    5196                        </div>
    5297                        <div class="column">${event.template}</div>
    53                         <wizard:templateColumns id="${i}" entity="${event}" template="${event.template}" name="event${i}" class="column" />
     98                        <wizard:templateColumns id="${i}" entity="${event}" template="${event.template}" name="event_${i}" class="column" />
    5499                        <g:if test="${eventGroups}"><g:each var="eventGroup" status="j" in="${eventGroups}">
    55100                        <div class="column">
     
    64109                </div>
    65110        </div>
     111                <div class="sliderContainer">
     112                        <div class="slider"></div>
     113                </div>
     114
    66115        </g:each>
    67 */ %>
    68 <% /*
     116
    69117        <div class="table">
    70118                <div class="header">
Note: See TracChangeset for help on using the changeset viewer.