Changeset 238

Show
Ignore:
Timestamp:
05-03-10 15:21:52 (4 years ago)
Author:
duh
Message:

Refectored version of the wizard

- initial template page has been removed, now is a generic 'start' page where one (in the future) may create a new study, or load and modify an already stored study
- study page incorporates study template select element, but does not yet incorporate the study template fields
- subjects page now allows creation of subjects based on a template. This change also implied the study page altogether had to change into a seperate table entity. Now the the page lists as many tables as unique templates have been selected. These tables contain all subjects that were added using that particular template. NOTE: data is not stored yet, due to the fact that templateEntity does not work properly yey (key/value pairs need to be set correctly when calling the setTemplate method)
- the JavaScript? now handles multiple tables in a page as well, and automatically initializes any underlying slider div if that is required

Location:
trunk
Files:
1 added
12 modified

Legend:

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

    r217 r238  
    4747                        flow.page = 0 
    4848                        flow.pages = [ 
    49                                 [title: 'Templates'],                   // templates 
     49                                //[title: 'Templates'],                 // templates 
     50                                [title: 'Start'],                               // load or create a study 
    5051                                [title: 'Study'],                               // study 
    5152                                [title: 'Subjects'],                    // subjects 
     
    6768                                flow.page = 1 
    6869                        } 
    69                         on("next").to "templates" 
     70                        on("next").to "start" 
    7071                } 
    7172 
     
    104105                } 
    105106 
     107                // create or modify a study 
     108                start { 
     109                        render(view: "_start") 
     110                        onRender { 
     111                                flow.page = 1 
     112                        } 
     113                        on("next") { 
     114 
     115                        }.to "study" 
     116                } 
     117 
    106118                // render and handle the study page 
     119                // TODO: make sure both template as well as logic will 
     120                //       handle Study templates as well!!! 
    107121                study { 
    108122                        render(view: "_study") 
     
    118132                                        error() 
    119133                                } 
    120                         }.to "templates" 
     134                        }.to "start" 
    121135                        on("next") { 
    122136                                flash.errors = new LinkedHashMap() 
     
    138152                                if (!flow.subjects) { 
    139153                                        flow.subjects = [] 
     154                                        flow.subjectTemplates = new LinkedHashMap() 
    140155                                } 
    141156                        } 
     
    143158                                // fetch species by name (as posted by the form) 
    144159                                def speciesTerm = Term.findByName(params.addSpecies) 
     160                                def subjectTemplateName = params.get('template') 
     161                                def subjectTemplate     = Template.findByName(subjectTemplateName) 
     162 
     163                                // add this subject template to the subject template array 
     164                                if (!flow.subjectTemplates[ subjectTemplateName ]) { 
     165                                        flow.subjectTemplates[ subjectTemplateName ] = [ 
     166                                                name: subjectTemplateName, 
     167                                                template: subjectTemplate, 
     168                                                subjects: [] 
     169                                        ] 
     170                                } 
    145171 
    146172                                // add x subject of species y 
    147173                                (params.addNumber as int).times { 
    148174                                        def increment = flow.subjects.size() 
    149                                         flow.subjects[increment] = new Subject( 
     175                                        def subject = new Subject( 
    150176                                                name: 'Subject ' + (increment + 1), 
    151177                                                species: speciesTerm, 
    152                                                 template: flow.study.template 
     178                                                template: subjectTemplate 
    153179                                        ) 
     180 
     181                                        // instantiate a new Subject 
     182                                        flow.subjects[ increment ] = subject 
     183 
     184                                        // and remember the subject id with the template 
     185                                        def subjectsSize = flow.subjectTemplates[ subjectTemplateName ]['subjects'].size() 
     186                                        flow.subjectTemplates[ subjectTemplateName ]['subjects'][ subjectsSize ] = increment 
    154187                                } 
    155188                        }.to "subjects" 
    156189                        on("next") { 
     190                                println flow.subjectTemplates 
     191                                println flow.subjects 
    157192                                flash.errors = new LinkedHashMap() 
    158193 
     
    193228                        on("add") { 
    194229                                // fetch classification by name (as posted by the form) 
    195                                 params.classification = Term.findByName(params.classification) 
     230                                //params.classification = Term.findByName(params.classification) 
    196231 
    197232                                // transform checkbox form value to boolean 
     
    427462 
    428463        /** 
    429          * re-usable code for handling event grouping in a web flow 
    430          * @param Map LocalAttributeMap (the flow scope) 
    431          * @param Map localAttributeMap (the flash scope) 
    432          * @param Map GrailsParameterMap (the flow parameters = form data) 
    433          * @returns boolean 
    434          */ 
    435         def handleEventGrouping(flow, flash, params) { 
    436                 // walk through eventGroups 
    437                 def g = 0 
    438                 flow.eventGroups.each() { 
    439                         def e = 0 
    440                         def eventGroup = it 
    441  
    442                         // reset events 
    443                         eventGroup.events = new HashSet() 
    444  
    445                         // walk through events 
    446                         flow.events.each() { 
    447                                 if (params.get('event_' + e + '_group_' + g) == 'on') { 
    448                                         eventGroup.addToEvents(it) 
    449                                 } 
    450                                 e++ 
    451                         } 
    452                         g++ 
    453                 } 
    454         } 
    455  
    456         /** 
    457464         * re-usable code for handling study form data in a web flow 
    458465         * @param Map LocalAttributeMap (the flow scope) 
     
    511518                        it.name = params.get('eventDescription_' + id + '_name') 
    512519                        it.description = params.get('eventDescription_' + id + '_description') 
    513                         it.classification = Term.findByName(params.get('eventDescription_' + id + '_classification')) 
     520                        //it.classification = Term.findByName(params.get('eventDescription_' + id + '_classification')) 
    514521                        it.isSamplingEvent = (params.containsKey('eventDescription_' + id + '_isSamplingEvent')) 
    515522 
     
    523530                } 
    524531 
    525                 return !(errors) 
     532                return !errors 
     533        } 
     534 
     535        /** 
     536         * re-usable code for handling event grouping in a web flow 
     537         * @param Map LocalAttributeMap (the flow scope) 
     538         * @param Map localAttributeMap (the flash scope) 
     539         * @param Map GrailsParameterMap (the flow parameters = form data) 
     540         * @returns boolean 
     541         */ 
     542        def handleEventGrouping(flow, flash, params) { 
     543                // walk through eventGroups 
     544                def g = 0 
     545                flow.eventGroups.each() { 
     546                        def e = 0 
     547                        def eventGroup = it 
     548 
     549                        // reset events 
     550                        eventGroup.events = new HashSet() 
     551 
     552                        // walk through events 
     553                        flow.events.each() { 
     554                                if (params.get('event_' + e + '_group_' + g) == 'on') { 
     555                                        eventGroup.addToEvents(it) 
     556                                } 
     557                                e++ 
     558                        } 
     559                        g++ 
     560                } 
    526561        } 
    527562 
     
    538573                def id = 0; 
    539574 
    540                 // iterate through subjects 
    541                 flow.subjects.each() { 
    542                         // store subject properties 
    543                         def name = params.get('subject_' + id + '_name') 
    544                         it.name = params.get('subject_' + id + '_name') 
    545                         it.species = Term.findByName(params.get('subject_' + id + '_species')) 
    546  
    547                         // remember name and check for duplicates 
    548                         if (!names[it.name]) { 
    549                                 names[it.name] = [count: 1, first: 'subject_' + id + '_name', firstId: id] 
    550                         } else { 
    551                                 // duplicate name found, set error flag 
    552                                 names[it.name]['count']++ 
    553  
    554                                 // second occurence? 
    555                                 if (names[it.name]['count'] == 2) { 
    556                                         // yeah, also mention the first 
    557                                         // occurrence in the error message 
    558                                         this.appendErrorMap(name: 'The subject name needs to be unique!', flash.errors, 'subject_' + names[it.name]['firstId'] + '_') 
    559                                 } 
    560  
    561                                 // add to error map 
    562                                 this.appendErrorMap([name: 'The subject name needs to be unique!'], flash.errors, 'subject_' + id + '_') 
    563                                 errors = true 
    564                         } 
    565  
    566                         // clear lists 
    567                         def stringList = new LinkedHashMap(); 
    568                         def intList = new LinkedHashMap(); 
    569                         def floatList = new LinkedHashMap(); 
    570                         def termList = new LinkedHashMap(); 
    571  
    572                         // get all template fields 
    573                         flow.study.template.subjectFields.each() { 
    574                                 // valid type? 
    575                                 if (!it.type) throw new NoSuchFieldException("Field name ${fieldName} not recognized") 
    576  
    577                                 // get value 
    578                                 def value = params.get('subject_' + id + '_' + it.name); 
    579                                 if (value) { 
    580                                         // add to template parameters 
    581                                         switch (it.type) { 
    582                                                 case 'STRINGLIST': 
    583                                                         stringList[it.name] = value 
    584                                                         break; 
    585                                                 case 'INTEGER': 
    586                                                         intList[it.name] = value 
    587                                                         break; 
    588                                                 case 'FLOAT': 
    589                                                         floatList[it.name] = value 
    590                                                         break; 
    591                                                 default: 
    592                                                         // unsupported type? 
    593                                                         throw new NoSuchFieldException("Field type ${it.type} not recognized") 
    594                                                         break; 
     575                // iterate through subject templates 
     576                flow.subjectTemplates.each() { 
     577                        def subjectTemplate = it.getValue().template 
     578                        def templateFields      = subjectTemplate.fields 
     579 
     580                        // iterate through subjects 
     581                        it.getValue().subjects.each() { subjectId -> 
     582                                flow.subjects[ subjectId ].name = params.get('subject_' + subjectId + '_name') 
     583                                flow.subjects[ subjectId ].species = Term.findByName(params.get('subject_' + subjectId + '_species')) 
     584 
     585                                // remember name and check for duplicates 
     586                                if (!names[ flow.subjects[ subjectId ].name ]) { 
     587                                        names[ flow.subjects[ subjectId ].name ] = [count: 1, first: 'subject_' + subjectId + '_name', firstId: subjectId] 
     588                                } else { 
     589                                        // duplicate name found, set error flag 
     590                                        names[ flow.subjects[ subjectId ].name ]['count']++ 
     591 
     592                                        // second occurence? 
     593                                        if (names[ flow.subjects[ subjectId ].name ]['count'] == 2) { 
     594                                                // yeah, also mention the first 
     595                                                // occurrence in the error message 
     596                                                this.appendErrorMap(name: 'The subject name needs to be unique!', flash.errors, 'subject_' + names[ flow.subjects[ subjectId ].name ]['firstId'] + '_') 
    595597                                        } 
    596                                 } 
    597                         } 
    598  
    599                         // set field data 
    600                         it.templateStringFields = stringList 
    601                         it.templateIntegerFields = intList 
    602                         it.templateFloatFields = floatList 
    603                         it.templateTermFields = termList 
    604  
    605                         // validate subject 
    606                         if (!it.validate()) { 
    607                                 errors = true 
    608                                 this.appendErrors(it, flash.errors) 
    609                         } 
    610  
    611                         id++; 
     598 
     599                                        // add to error map 
     600                                        this.appendErrorMap([name: 'The subject name needs to be unique!'], flash.errors, 'subject_' + subjectId + '_') 
     601                                        errors = true 
     602                                } 
     603 
     604                                // iterate through template fields 
     605                                templateFields.each() { subjectField -> 
     606                                        def value = params.get('subject_' + subjectId + '_' + subjectField.name) 
     607 
     608// TODO: UNCOMMENT THIS         if (value) flow.subjects[ subjectId ].setFieldValue(subjectField.name, value) 
     609                                } 
     610 
     611                                // validate subject 
     612                                if (!flow.subjects[ subjectId ].validate()) { 
     613                                        errors = true 
     614                                        this.appendErrors(flow.subjects[ subjectId ], flash.errors) 
     615                                } 
     616                        } 
    612617                } 
    613618 
  • trunk/grails-app/domain/dbnp/studycapturing/TemplateEntity.groovy

    r236 r238  
    44import org.codehaus.groovy.runtime.NullObject 
    55 
    6 class TemplateEntity { 
     6/** 
     7 * TemplateEntity Domain Class 
     8 * 
     9 * Revision information: 
     10 * $Rev$ 
     11 * $Author$ 
     12 * $Date$ 
     13 */ 
     14class TemplateEntity implements Serializable { 
    715 
    816        Template template 
     
    2937 
    3038        static constraints = { 
    31                 template(nullable: true) 
     39                template(nullable: true, blank: true) 
    3240 
    3341        } 
     
    8391                } 
    8492                else { 
    85                         if (templateStringFields.containsKey(fieldName) && value.class == String) { 
     93                        if (templateStringFields && templateStringFields.containsKey(fieldName) && value.class == String) { 
    8694                                this.templateStringFields[fieldName] = value 
    8795                        } 
    88                         if (templateStringListFields.containsKey(fieldName) && value.class == TemplateFieldListItem) { 
     96                        if (templateStringFields && templateStringListFields.containsKey(fieldName) && value.class == TemplateFieldListItem) { 
    8997                                // TODO: check if item really belongs to the list under fieldName 
    9098                                this.templateStringListFields[fieldName] = value 
     
    93101                                this.templateTextFields[fieldName] = value 
    94102                        } 
    95                         else if (templateIntegerFields.containsKey(fieldName) && value.class == Integer) { 
     103                        else if (templateIntegerFields && templateIntegerFields.containsKey(fieldName) && value.class == Integer) { 
    96104                                this.templateIntegerFields[fieldName] = value 
    97105                        } 
    98                         else if (templateFloatFields.containsKey(fieldName) && value.class == Float) { 
     106                        else if (templateFloatFields && templateFloatFields.containsKey(fieldName) && value.class == Float) { 
    99107                                this.templateFloatFields[fieldName] = value 
    100108                        } 
    101                         else if (templateDoubleFields.containsKey(fieldName) && value.class == Double) { 
     109                        else if (templateDoubleFields && templateDoubleFields.containsKey(fieldName) && value.class == Double) { 
    102110                                this.templateDoubleFields[fieldName] = value 
    103111                        } 
    104                         else if (templateDateFields.containsKey(fieldName) && value.class == Date) { 
     112                        else if (templateDateFields && templateDateFields.containsKey(fieldName) && value.class == Date) { 
    105113                                this.templateDateFields[fieldName] = value 
    106114                        } 
    107                         else if (templateTermFields.containsKey(fieldName) && value.class == Term) { 
     115                        else if (templateTermFields && templateTermFields.containsKey(fieldName) && value.class == Term) { 
    108116                                this.templateTermFields[fieldName] = value 
    109117                        } 
     
    129137                // TODO: initialize all template fields with the necessary keys and null values 
    130138 
    131                 println "Setting template " + newTemplate 
     139                //println "Setting template " + newTemplate 
    132140                if (template != null) { 
    133141 
  • trunk/grails-app/domain/dbnp/studycapturing/TemplateFieldListItem.groovy

    r228 r238  
    11package dbnp.studycapturing 
    22 
    3 class TemplateFieldListItem { 
    4  
     3/** 
     4 * TemplateFieldListItem Domain Class 
     5 * 
     6 * Revision information: 
     7 * $Rev$ 
     8 * $Author$ 
     9 * $Date$ 
     10 */ 
     11class TemplateFieldListItem implements Serializable { 
    512        String name 
    613 
    7         static constraints = { 
    8         } 
     14        static constraints = { 
     15        } 
    916 
    1017        String toString() { 
  • trunk/grails-app/domain/dbnp/studycapturing/TemplateFieldType.groovy

    r236 r238  
    88 * $Date$ 
    99 */ 
    10 public enum TemplateFieldType { 
     10public enum TemplateFieldType implements Serializable  { 
    1111        STRING('String'), 
    1212        TEXT('Long string'), 
  • trunk/grails-app/domain/dbnp/studycapturing/Template.groovy

    r236 r238  
    1212 */ 
    1313class Template implements Serializable { 
    14  
    1514        String name 
    1615        Class entity 
     
    2120        static constraints = { 
    2221                name(unique:['entity']) 
    23  
    2422        } 
    2523 
     
    6462                def results = [] 
    6563 
    66                 // this should not work in static context, however it does so I'll keep 
     64                // 'this' should not work in static context, however it does so I'll keep 
    6765                // this in for now :) 
    6866                this.findAll().each() { 
  • trunk/grails-app/taglib/dbnp/studycapturing/WizardTagLib.groovy

    r216 r238  
    200200                def addExample2Element  = attrs.remove('addExample2Element') 
    201201 
     202                // execute inputElement call 
     203                def renderedElement = "$inputElement"(attrs) 
     204 
     205                // if false, then we skip this element 
     206                if (!renderedElement) return false 
     207 
    202208                // render a form element 
    203209                out << '<div class="element">' 
     
    206212                out << ' </div>' 
    207213                out << ' <div class="input">' 
    208                 out << "$inputElement"(attrs) 
     214                out << renderedElement 
    209215                if(help()) { 
    210216                        out << '        <div class="helpIcon"></div>' 
     
    414420         */ 
    415421        def templateSelect = { attrs -> 
    416                 // fetch all templates 
    417                 attrs.from = Template.findAll() // for now, all templates 
     422                def entity = attrs.remove('entity') 
     423 
     424                // fetch templates 
     425                attrs.from = (entity) ? Template.findAllByEntity(entity) : Template.findAll() 
    418426 
    419427                // got a name? 
     
    421429                        attrs.name = 'template' 
    422430                } 
    423                  
    424                 out << select(attrs) 
     431 
     432                // got result? 
     433                if (attrs.from.size() >0) { 
     434                        out << select(attrs) 
     435                } else { 
     436                        // no, return false to make sure this element 
     437                        // is not rendered in the template 
     438                        return false 
     439                } 
    425440        } 
    426441 
     
    475490 
    476491                // output table headers for template fields 
    477                 template.subjectFields.each() { 
     492                template.fields.each() { 
    478493                        out << '<div class="' + attrs.get('class') + '">' + it + '</div>' 
    479494                } 
     
    494509 
    495510                // output columns for these subjectFields 
    496                 template.subjectFields.each() { 
     511                template.fields.each() { 
    497512                        // output div 
    498513                        out << '<div class="' + attrs.get('class') + '">' 
     
    506521                                                        from: it.listEntries, 
    507522                                                        value: (stringFields) ? stringFields.get(it.name) : '' 
    508                                                 ) 
     523                                                )                                                
    509524                                        } else { 
    510525                                                out << '<span class="warning">no values!!</span>' 
     
    528543                                        // unsupported field type 
    529544                                        out << '<span class="warning">!'+it.type+'</span>' 
     545                                        //out << subject.getFieldValue(it.name) 
    530546                                        break; 
    531547                        } 
     548 
    532549                        out << '</div>' 
    533550                } 
  • trunk/grails-app/views/wizard/pages/_eventDescriptions.gsp

    r217 r238  
    3030        </span> 
    3131 
    32         <wizard:termElement name="classification" description="Classification" error="classification" value="${values?.classification}"> 
    33                 The ontology reference for this particular type of event 
    34         </wizard:termElement> 
    3532        <wizard:textFieldElement name="name" description="Name" error="name" value="${values?.name}"> 
    3633                The name of the event description you are creating 
     
    5047                        <div class="column">name</div> 
    5148                        <div class="column">description</div> 
    52                         <div class="column">classification</div> 
    5349                        <div class="column">sampling event</div> 
    5450                        <div class="column">protocol</div> 
     
    6258                        <div class="column"><g:textField name="eventDescription_${i}_name" value="${eventDescription.name}" size="12" maxlength="12" /></div> 
    6359                        <div class="column"><g:textField name="eventDescription_${i}_description" value="${eventDescription.description}" size="12" maxlength="12" /></div> 
    64                         <div class="column"><wizard:termSelect name="eventDescription_${i}_classification" value="${eventDescription.classification}" /></div> 
    6560                        <div class="column"><g:checkBox name="eventDescription_${i}_isSamplingEvent" value="${eventDescription.isSamplingEvent}" /></div> 
    6661                        <div class="column"><g:if test="${eventDescription.protocol}">${eventDescription.protocol}</g:if><g:else>-</g:else></div> 
  • trunk/grails-app/views/wizard/pages/_study.gsp

    r213 r238  
    2121        </span> 
    2222         
     23        <wizard:templateElement name="template" description="Template" value="${study?.template}" entity="${dbnp.studycapturing.Study}"> 
     24                The template to use for this study 
     25        </wizard:templateElement> 
    2326        <wizard:textFieldElement name="title" description="Title" error="title" value="${study?.title}"> 
    2427                The title of the study you are creating 
     
    3942                The start date of the study      
    4043        </wizard:dateElement> 
     44 
     45        <span class="info"> 
     46                <span class="title">TODO</span> 
     47                This page should also contain the template fields of the study template selected above (if available). This is 
     48                scheduled for implementation in a later version 
     49        </span> 
     50         
    4151</wizard:pageContent> 
  • trunk/grails-app/views/wizard/pages/_subjects.gsp

    r213 r238  
    2525        subjects of species 
    2626        <wizard:speciesSelect name="addSpecies" /> 
     27        using the 
     28        <wizard:templateSelect name="template" description="Template" value="${study?.template}" entity="${dbnp.studycapturing.Subject}" /> 
     29        template 
     30 
    2731<g:if test="${subjects}"> 
    28         <div class="table"> 
    29                 <div class="header"> 
    30                         <div class="firstColumn">#</div> 
    31                         <div class="column">name</div> 
    32                         <div class="column">species</div> 
    33                         <wizard:templateColumnHeaders template="${study.template}" class="column" /> 
     32        <g:each var="subjectTemplate" in="${subjectTemplates}"> 
     33                <h1>${subjectTemplate.getValue().name} template</h1> 
     34                <div class="table"> 
     35                        <div class="header"> 
     36                                <div class="firstColumn">#</div> 
     37                                <div class="column">name</div> 
     38                                <div class="column">species</div> 
     39                                <wizard:templateColumnHeaders template="${subjectTemplate.getValue().template}" class="column" /> 
     40                        </div>   
     41                <g:each var="subjectId" in="${subjectTemplate.getValue().subjects}"> 
     42                        <div class="row"> 
     43                                <div class="firstColumn">${subjectId}</div> 
     44                                <div class="column"><g:textField name="subject_${subjectId}_name" value="${subjects[ subjectId ].name}" size="12" maxlength="12" /></div> 
     45                                <div class="column"> 
     46                                        <wizard:speciesSelect value="${subjects[ subjectId ].species}" name="subject_${subjectId}_species" /> 
     47                                </div> 
     48                                <wizard:templateColumns id="${subjectId}" template="${subjects[ subjectId ].template}" name="subject_${subjectId}" class="column" subject="${subjects[ subjectId ]}" />                          
     49                        </div> 
     50                </g:each> 
    3451                </div> 
    35         <g:each var="subject" status="i" in="${subjects}"> 
    36                 <div class="row"> 
    37                         <div class="firstColumn">${i}</div> 
    38                         <div class="column"><g:textField name="subject_${i}_name" value="${subject.name}" size="12" maxlength="12" /></div> 
    39                         <div class="column"> 
    40                                 <wizard:speciesSelect value="${subject.species}" name="subject_${i}_species" /> 
    41                         </div> 
    42                         <wizard:templateColumns id="${i}" template="${study.template}" name="subject_${i}" class="column" subject="${subject}" /> 
     52                <div class="sliderContainer"> 
     53                        <div class="slider" ></div> 
    4354                </div> 
    4455        </g:each> 
    45         </div> 
    46         <div class="sliderContainer"> 
    47                 <div class="slider"/> 
    48         </div> 
    4956</g:if> 
     57 
    5058</wizard:pageContent> 
  • trunk/grails-app/views/wizard/pages/_templates.gsp

    r213 r238  
    2121        </span> 
    2222 
    23         <wizard:templateElement name="template" description="Template" value="${study?.template}"> 
    24                 The meta data template to use for this study 
     23        <wizard:templateElement name="template" description="Template" value="${study?.template}" entity="${dbnp.studycapturing.Subject}"> 
     24                The subject template to use for this study 
    2525        </wizard:templateElement> 
    2626</wizard:pageContent> 
  • trunk/web-app/css/wizard.css

    r217 r238  
    3737.wizard .sliderContainer { 
    3838    display: block; 
    39     padding-top: 10px; 
     39    margin-top: 10px; 
    4040    width: 150px; 
    4141} 
  • trunk/web-app/js/wizard.js

    r213 r238  
    3939    // table handlers 
    4040    attachTableEvents(); 
    41     resizeWizardTable(); 
    42     attachTableSlider(); 
    43     new TableEditor().init('div.table','div.row','div.column'); 
     41    handleWizardTable(); 
     42    new TableEditor().init('div.table', 'div.row', 'div.column'); 
    4443 
    4544    // accordeon(s) 
     
    158157// the header and the rows is automatically scaled to 
    159158// the cummalative width of the columns in the header 
    160 function resizeWizardTable() { 
    161     var wizardTable = $("div#wizard").find('div.table'); 
    162  
    163     if (wizardTable) { 
     159function handleWizardTable() { 
     160    var that = this; 
     161    var wizardTables = $("div#wizard").find('div.table'); 
     162 
     163    wizardTables.each(function() { 
     164        var wizardTable = $(this); 
     165        var sliderContainer = (wizardTable.next().attr('class') == 'sliderContainer') ? wizardTable.next() : null; 
    164166        var header = wizardTable.find('div.header') 
     167        var width = 20; 
     168 
    165169        // calculate total width of elements in header 
    166         var width = 20; 
    167170        header.children().each(function() { 
    168171            // calculate width per column 
     
    183186            $(this).css({ width: width + 'px' }); 
    184187        }); 
    185     } 
    186 } 
    187  
    188 // if we have a table and a slider, make the slider 
    189 // slide the contents of the table if the content of 
    190 // the table is wider than the table itself 
    191 function attachTableSlider() { 
    192     var slider = $("div#wizard").find('div.slider'); 
    193     var header = $("div#wizard").find('div.header'); 
    194     var table = $("div#wizard").find('div.table'); 
    195  
    196     if (slider && table && header) { 
    197         // do we really need a slider? 
    198         if (header.width() < table.width()) { 
    199             // no, so hide it 
    200             slider.css({ 'display': 'none '}); 
    201         } else { 
    202             slider.slider({ 
    203                 value   : 1, 
    204                 min     : 1, 
    205                 max     : header.width() - table.width(), 
    206                 step    : 1, 
    207                 slide: function(event, ui) { 
    208                     $("div#wizard").find('div.header, div.row').css({ 'margin-left': ( 1 - ui.value ) + 'px' }); 
    209                 } 
    210             }); 
     188 
     189        // got a slider for this table? 
     190        if (sliderContainer) { 
     191            // handle slider 
     192            if (header.width() < wizardTable.width()) { 
     193                // no, so hide it 
     194                sliderContainer.css({ 'display': 'none '}); 
     195            } else { 
     196                sliderContainer.slider({ 
     197                    value   : 1, 
     198                    min     : 1, 
     199                    max     : header.width() - wizardTable.width(), 
     200                    step    : 1, 
     201                    slide: function(event, ui) { 
     202                        wizardTable.find('div.header, div.row').css({ 'margin-left': ( 1 - ui.value ) + 'px' }); 
     203                    } 
     204                }); 
     205            } 
    211206        } 
    212     } 
    213 } 
     207    }); 
     208}