Changeset 396


Ignore:
Timestamp:
May 7, 2010, 2:24:27 PM (8 years ago)
Author:
duh
Message:
  • fixed incomplete implementation of domain fields (getters, setters and constrains logic were all not implemented correctly)
  • refactored wizards pages
  • TODO: constraints on (templated) domain fields are not working anymore, this needs to be implemented properly in TemplateEntity?
Location:
trunk/grails-app
Files:
7 edited

Legend:

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

    r390 r396  
    587587                def template = params.remove('template')
    588588                if (template instanceof String && template.size() > 0) {
    589                         params.template = Template.findByName(template)
     589                        flow.study.template = Template.findByName(template)
    590590                } else if (template instanceof Template) {
    591                         params.template = template
    592                 }
    593 
     591                        flow.study.template = template
     592                }
     593
     594//println flow.study.giveFields()
     595/*
    594596                // update study instance with parameters
    595597                params.each() { key, value ->
    596598                        if (flow.study.hasProperty(key)) {
     599println ".set property ["+key+"] with value ["+value+"]"
    597600                                flow.study.setProperty(key, value);
    598601                        }
     
    602605                if (params.template) {
    603606                        params.template.fields.each() { field ->
     607println ".set field ["+field.name+"] with value ["+params.get(field.escapedName())+"]"
    604608                                flow.study.setFieldValue(field.name, params.get(field.escapedName()))
    605609                        }
    606610                }
    607 
     611*/
     612                // iterate through fields
     613                if (flow.study.template) {
     614                        flow.study.giveFields().each() {
     615                                flow.study.setFieldValue(it.name, params.get(it.escapedName()))
     616                        }
     617                }
     618println "study = " + flow.study
     619println flow.study.templateDateFields
     620               
    608621                // validate study
    609622                if (flow.study.validate()) {
     
    636649                        // iterate through subjects
    637650                        it.getValue().subjects.each() { subjectId ->
     651                                /*
    638652                                flow.subjects[ subjectId ].name = params.get('subject_' + subjectId + '_name')
    639653                                flow.subjects[ subjectId ].species = Term.findByName(params.get('subject_' + subjectId + '_species'))
     
    657671                                        errors = true
    658672                                }
     673                                */
    659674
    660675                                // iterate through template fields
    661                                 templateFields.each() { subjectField ->
     676                                //templateFields.each() { subjectField ->
     677                                flow.subjects[ subjectId ].giveFields().each() { subjectField ->
    662678                                        flow.subjects[ subjectId ].setFieldValue(
    663679                                                subjectField.name,
     
    739755                handleEventGrouping(flow, flash, params)
    740756
    741                 println flow.event
     757println flow.event
    742758
    743759                return !errors
  • trunk/grails-app/domain/dbnp/studycapturing/Study.groovy

    r392 r396  
    1212        static searchable = true
    1313        nimble.User owner
    14         String title
    1514        Date dateCreated
    1615        Date lastUpdated
    17         Date startDate
    1816
    19         // TODO: The following 4 fields should be moved into templates
    20         //String code
    21         //String researchQuestion
    22         //String description
    23         //String ecCode
    24 
     17        /**
     18         * return the domain fields for this domain class
     19         */
    2520        List<TemplateField> giveDomainFields() {
    2621                [ new TemplateField(
     
    4742        static constraints = {
    4843                owner(nullable: true, blank: true)
    49                 title(nullable: false, blank: false)
    5044                template(nullable: false, blank: false)
    5145        }
     
    5852
    5953        def String toString() {
    60                 return title;
     54                //return title;
     55                def title = this.giveDomainFields().find { it.name == 'title' }
     56
     57                return title.toString()
    6158        }
    6259
     
    8178                TemplateEntity.giveTemplates(events);
    8279        }
    83        
    84         /**
    85          * Returns the template of all subjects in the study
    86          * Throws an error if there are no or multiple subject templates
    87          */
    88         // outcommented, we shouldn't make it too easy for ourselves by introducing uncertain assumptions (1 distinct template)
    89         //def Template giveSubjectTemplate() {
    90         //      TemplateEntity.giveTemplate(subjects);
    91         //}
    9280
    9381        /**
  • trunk/grails-app/domain/dbnp/studycapturing/Subject.groovy

    r394 r396  
    1414class Subject extends TemplateEntity implements Serializable {
    1515        static searchable = true
    16         String name
    17         Term species
    1816
    1917        List<TemplateField> giveDomainFields() {
  • trunk/grails-app/domain/dbnp/studycapturing/TemplateEntity.groovy

    r392 r396  
    258258         */
    259259        def getFieldValue(String fieldName) {
    260                 if (this.properties.containsKey(fieldName)) {
    261                         return this[fieldName]
    262                 }
    263                 else {
    264                         TemplateFieldType fieldType = template.getFieldType(fieldName)
    265                         if (!fieldType) throw new NoSuchFieldException("Field name ${fieldName} not recognized")
    266                         return getStore(fieldType)[fieldName]
     260                // escape the fieldName for easy matching
     261                // (such escaped names are commonly used
     262                // in the HTTP forms of this application)
     263                def escapedLowerCaseFieldName = fieldName.toLowerCase().replaceAll("([^a-z0-9])","_")
     264
     265                // Find the target template field, if not found, throw an error
     266                TemplateField field = this.giveFields().find { it.name.toLowerCase().replaceAll("([^a-z0-9])", "_") == escapedLowerCaseFieldName }
     267
     268                // field found?
     269                if (field == null) {
     270                        // no such field
     271                        throw new NoSuchFieldException("Field ${fieldName} not recognized")
     272                } else {
     273                        return getStore(field.type)[fieldName]
    267274                }
    268275        }
     
    314321                def escapedLowerCaseFieldName = fieldName.toLowerCase().replaceAll("([^a-z0-9])","_")
    315322
    316                 // First, search if there is an entity property with the given name, and if so, set that
    317                 if (this.properties.containsKey(fieldName)) {
    318                         this[fieldName] = value                 
    319                 } else if (template == null) {
    320                         // not the found, then it is a template field, so check if there is a template
    321                         throw new NoSuchFieldException("Field ${fieldName} not found in class properties: template not set")
     323                // Find the target template field, if not found, throw an error
     324                TemplateField field = this.giveFields().find { it.name.toLowerCase().replaceAll("([^a-z0-9])", "_") == escapedLowerCaseFieldName }
     325
     326                // field found?
     327                if (field == null) {
     328                        // no such field
     329                        throw new NoSuchFieldException("Field ${fieldName} not found in class template fields")
    322330                } else {
    323                         // there is a template, check the template fields
    324                         // Find the target template field, if not found, throw an error
    325                         TemplateField field = this.template.fields.find { it.name.toLowerCase().replaceAll("([^a-z0-9])","_") == escapedLowerCaseFieldName }
    326 
    327                         if (field == null) {
    328                                 // no such field
    329                                 throw new NoSuchFieldException("Field ${fieldName} not found in class template fields")
    330                         } else {
    331                                 // Set the value of the found template field
    332                                 // Convenience setter for template string list fields: find TemplateFieldListItem by name
    333                                 if (field.type == TemplateFieldType.STRINGLIST && value && value.class == String) {
    334                                         // Kees insensitive pattern matching ;)
    335                                         def escapedLowerCaseValue = value.toLowerCase().replaceAll("([^a-z0-9])","_")
    336                                         value = field.listEntries.find {
    337                                                 it.name.toLowerCase().replaceAll("([^a-z0-9])","_") == escapedLowerCaseValue
    338                                         }
    339                                 }
    340 
    341                                 // Convenience setter for dates: handle string values for date fields
    342                                 if (field.type == TemplateFieldType.DATE && value.class == String) {
    343                                         // a string was given, attempt to transform it into a date instance
    344                                         // and -for now- assume the dd/mm/yyyy format
    345                                         def dateMatch = value =~ /^([0-9]{1,})([^0-9]{1,})([0-9]{1,})([^0-9]{1,})([0-9]{1,})((([^0-9]{1,})([0-9]{1,2}):([0-9]{1,2})){0,})/
    346                                         if (dateMatch.matches()) {
    347                                                 // create limited 'autosensing' datetime parser
    348                                                 // assume dd mm yyyy  or dd mm yy
    349                                                 def parser = 'd' + dateMatch[0][2] + 'M' + dateMatch[0][4] + (((dateMatch[0][5] as int) > 999) ? 'yyyy' : 'yy')
    350 
    351                                                 // add time as well?
    352                                                 if (dateMatch[0][7] != null) {
    353                                                         parser += dateMatch[0][6] + 'HH:mm'
    354                                                 }
    355 
    356                                                 value = new Date().parse(parser, value)
    357                                         }
    358                                 }
    359 
    360                                 // Set the field value
    361                                 // Caution: this assumes that all template...Field Maps are already initialized (as is done now above as [:])
    362                                 // If that is ever changed, the results are pretty much unpredictable (random Java object pointers?)!
    363                                 def store = getStore(field.type)
    364                                 if (!value && store[ fieldName ]) {
    365                                         println "removing " + ((super) ? super.class : '??') + " template field: " + fieldName
    366 
    367                                         // remove the item from the Map (if present)
    368                                         store.remove( fieldName )
    369                                 } else if (value) {
    370                                         println "setting " + ((super) ? super.class : '??') + " template field: " + fieldName + " ([" + value.toString() + "] of type [" + value.class + "])"
    371 
    372                                         // set value
    373                                         store[ fieldName ] = value
    374                                 }
    375                                 return this
    376                         }
    377                 }
     331                        // Set the value of the found template field
     332                        // Convenience setter for template string list fields: find TemplateFieldListItem by name
     333                        if (field.type == TemplateFieldType.STRINGLIST && value && value.class == String) {
     334                                // Kees insensitive pattern matching ;)
     335                                def escapedLowerCaseValue = value.toLowerCase().replaceAll("([^a-z0-9])", "_")
     336                                value = field.listEntries.find {
     337                                        it.name.toLowerCase().replaceAll("([^a-z0-9])", "_") == escapedLowerCaseValue
     338                                }
     339                        }
     340
     341                        // Convenience setter for dates: handle string values for date fields
     342                        if (field.type == TemplateFieldType.DATE && value && value.class == String) {
     343                                // a string was given, attempt to transform it into a date instance
     344                                // and -for now- assume the dd/mm/yyyy format
     345                                def dateMatch = value =~ /^([0-9]{1,})([^0-9]{1,})([0-9]{1,})([^0-9]{1,})([0-9]{1,})((([^0-9]{1,})([0-9]{1,2}):([0-9]{1,2})){0,})/
     346                                if (dateMatch.matches()) {
     347                                        // create limited 'autosensing' datetime parser
     348                                        // assume dd mm yyyy  or dd mm yy
     349                                        def parser = 'd' + dateMatch[0][2] + 'M' + dateMatch[0][4] + (((dateMatch[0][5] as int) > 999) ? 'yyyy' : 'yy')
     350
     351                                        // add time as well?
     352                                        if (dateMatch[0][7] != null) {
     353                                                parser += dateMatch[0][6] + 'HH:mm'
     354                                        }
     355
     356                                        value = new Date().parse(parser, value)
     357                                }
     358                        }
     359
     360                        // Set the field value
     361                        def store = getStore(field.type)
     362                        if (!value && store[fieldName]) {
     363                                println "removing " + ((super) ? super.class : '??') + " template field: " + fieldName
     364
     365                                // remove the item from the Map (if present)
     366                                store.remove(fieldName)
     367                        } else if (value) {
     368                                println "setting " + ((super) ? super.class : '??') + " template field: " + fieldName + " ([" + value.toString() + "] of type [" + value.class + "])"
     369
     370                                // set value
     371                                store[fieldName] = value
     372                        }
     373                }
     374                return this
    378375        }
    379376
  • trunk/grails-app/taglib/dbnp/studycapturing/WizardTagLib.groovy

    r391 r396  
    660660         * @param Map attributes
    661661         */
    662         def templateColumnHeaders = {attrs ->
    663                 def template = attrs.remove('template')
    664 
    665                 // output table headers for template fields
    666                 template.fields.each() {
    667                         out << '<div class="' + attrs.get('class') + '">' + it + '</div>'
     662        def templateColumnHeaders = { attrs ->
     663                def entity              = (attrs.get('entity'))
     664                def template    = (entity && entity instanceof TemplateEntity) ? entity.template : null
     665
     666                // got a template?
     667                if (template) {
     668                        // render template fields
     669                        entity.giveFields().each() {
     670                                out << '<div class="' + attrs.get('class') + '">' + it.name + '</div>'
     671                        }
    668672                }
    669673        }
     
    696700                if (template) {
    697701                        // render template fields
    698                         template.fields.each() {
     702                        entity.giveFields().each() {
    699703                                def fieldValue = entity.getFieldValue(it.name)
    700704
  • trunk/grails-app/views/wizard/pages/_study.gsp

    r389 r396  
    2525                The template to use for this study
    2626        </wizard:templateElement>
    27         <wizard:textFieldElement name="title" description="Title" error="title" value="${study?.title}">
    28                 The title of the study you are creating
    29         </wizard:textFieldElement>
    30         <wizard:dateElement name="startDate" description="Start date" error="startDate" value="${study?.startDate}">
    31                 The start date of the study
    32         </wizard:dateElement>
    3327        <g:if test="${study}"><wizard:templateElements entity="${study}" /></g:if>
    3428</wizard:pageContent>
  • trunk/grails-app/views/wizard/pages/_subjects.gsp

    r383 r396  
    3838<g:if test="${subjects}">
    3939        <g:each var="subjectTemplate" in="${subjectTemplates}">
     40                <g:set var="showHeader" value="${true}" />
    4041                <h1>${subjectTemplate.getValue().name} template</h1>
    4142                <div class="table">
     43                <g:each var="subjectId" in="${subjectTemplate.getValue().subjects}">
     44                        <g:if test="${showHeader}">
     45                        <g:set var="showHeader" value="${false}" />
    4246                        <div class="header">
    4347                                <div class="firstColumn">#</div>
    4448                                <div class="firstColumn"></div>
    45                                 <div class="column">name</div>
    46                                 <div class="column">species</div>
    47                                 <wizard:templateColumnHeaders template="${subjectTemplate.getValue().template}" class="column" />
     49                                <wizard:templateColumnHeaders entity="${subjects[ subjectId ]}" class="column" />                               
    4850                        </div>
    49                 <g:each var="subjectId" in="${subjectTemplate.getValue().subjects}">
     51                        </g:if>
    5052                        <div class="row">
    5153                                <div class="firstColumn">${subjectId + 1}</div>
     
    5355                                        <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(${subjectId});" afterSuccess="onWizardPage()" />
    5456                                </div>
    55                                 <div class="column"><g:textField name="subject_${subjectId}_name" value="${subjects[ subjectId ].name}" size="12" maxlength="12" /></div>
    56                                 <div class="column">
    57                                         <wizard:termSelect value="${subjects[ subjectId ].species}" name="subject_${subjectId}_species" ontology="1132" />
    58                                 </div>
    59                                 <wizard:templateColumns id="${subjectId}" entity="${subjects[ subjectId ]}" template="${subjects[ subjectId ].template}" name="subject_${subjectId}" class="column" subject="${subjects[ subjectId ]}" />                               
     57                                <wizard:templateColumns id="${subjectId}" entity="${subjects[ subjectId ]}" template="${subjects[ subjectId ].template}" name="subject_${subjectId}" class="column" subject="${subjects[ subjectId ]}" />
    6058                        </div>
    6159                </g:each>
Note: See TracChangeset for help on using the changeset viewer.