Changeset 316

Show
Ignore:
Timestamp:
26-03-10 13:02:39 (4 years ago)
Author:
ademcan
Message:

queryController changes

Location:
trunk/grails-app
Files:
1 added
13 modified

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/dbnp/query/QueryController.groovy

    r315 r316  
    3333    } 
    3434 
     35        def results= { 
     36          println('query controller') 
     37        if (!params.q?.trim()) { 
     38            return [:] 
     39        } 
     40        try { 
     41            return [searchResult: searchableService.search(params.q, params)] 
     42        } catch (SearchEngineQueryParseException ex) { 
     43            return [parseException: true] 
     44        } 
     45    } 
     46 
    3547    def pagesFlow = { 
    3648         
     
    3850                flow.page = 0 
    3951                        flow.pages = [ 
     52                                [title: 'Query'], 
    4053                                [title: 'Study'], 
    4154                                [title: 'Samples'], 
     
    5265             onRender { 
    5366                println "done randering index" 
     67                flow.page=1 
    5468             } 
    55  
    56  
    5769             on("next") { 
    5870                println "clicked next in sample" 
    59              } .to 'study' 
    60  
     71             } .to 'inputQuery' 
    6172        }         
    6273 
     74        inputQuery { 
     75            render(view:'_inputQuery') 
     76            onRender { 
     77                flow.page=1 
     78            } 
     79        } 
    6380 
    6481        study { 
    6582             render( view:'_study') 
    66  
     83            onRender { 
     84                flow.page=2 
     85             } 
    6786             on("next") { 
    6887                println "clicked next in sample" 
    6988             } .to 'sample' 
    70  
     89             on("previous"){}.to 'inputQuery' 
    7190        } 
    72  
    73  
    7491 
    7592        sample { 
    7693             render( view:'_sample') 
    77  
     94            onRender { 
     95                flow.page=3 
     96             } 
    7897             on("next") { 
    7998                println "clicked next in sample" 
    8099             } .to 'biomarker' 
    81  
     100             on("previous"){}.to 'study' 
    82101        } 
    83102 
     
    85104        biomarker { 
    86105             render( view:'_biomarker') 
    87  
     106            onRender { 
     107                flow.page=4 
     108             } 
    88109             on("next") { 
    89110                println "clicked next in sample" 
    90111             } .to 'group' 
    91  
     112             on("previous"){}.to 'sample' 
    92113        } 
    93  
    94114 
    95115        group { 
    96116             render( view:'_group') 
    97  
     117            onRender { 
     118                flow.page=5 
     119             } 
    98120             on("next") { 
    99121                println "clicked next in sample" 
    100122             } .to 'result' 
    101  
     123             on("previous"){}.to 'biomarkers' 
    102124        } 
    103  
    104  
    105125 
    106126        result { 
    107127             render( view:'_result') 
    108128 
     129            onRender { 
     130                flow.page=6 
     131             } 
     132             on("previous"){}.to 'group' 
    109133        } 
    110  
    111  
    112  
    113  
    114  
    115  
    116  
    117  
    118  
    119  
    120  
    121  
    122134 
    123135    } 
  • trunk/grails-app/controllers/SearchableController.groovy

    r247 r316  
    1  
    21/* 
    32 * Copyright 2007 the original author or authors. 
     
    2120 * Basic web interface for Grails Searchable Plugin 
    2221 * 
    23  * @author Adem and Jahn 
     22 * @author Maurice Nicholson 
    2423 */ 
    2524class SearchableController { 
    2625    def searchableService 
    27  
    28     def selectsample = { 
    29  
    30  
    31             // produce error message here if studies don't contain samples! 
    32             // redirect back or use error 
    33  
    34  
    35             println "in selectsample: " 
    36             params.each{println it} 
    37  
    38             // prepare showing all studies selected in the previous view 
    39             def selectedStudies = [] 
    40             def selectedStudyIds = params['selectedStudyIds'] 
    41  
    42             if(selectedStudyIds!=null) 
    43             { 
    44                  def list = selectedStudyIds.findAll(/(\d)+/) 
    45                  selectedStudies = list.collect{ dbnp.studycapturing.Study.get(it) } 
    46             } 
    47             else 
    48             { 
    49                  def tmpList = [] 
    50                  def studyList = dbnp.studycapturing.Study.list() 
    51                  selectedStudyIds = [] 
    52                  params.each{ key,values-> 
    53                      if (values=="on")  tmpList.add(key) 
    54                  } 
    55  
    56                  for (i in studyList) 
    57                      if (tmpList.contains(i.getId().toString())) 
    58                      { 
    59                          selectedStudyIds.add(i.id) 
    60                          selectedStudies.add(i) 
    61                      } 
    62            } 
    63  
    64  
    65         // subgroups 
    66         // provide list of subgroups depending on the type of subgrouping 
    67         // selected by the user 
    68         def subgroups = [] 
    69         def submitButton = params["submit"]  // this button's value determines the kind of subgrouping 
    70  
    71         switch(submitButton) 
    72         { 
    73              case "Subject Groups": 
    74                   render(params) 
    75                   render("Subject Groups") 
    76                   def studyGroups = [] 
    77                   if(selectedStudies!=null) 
    78                   { 
    79                      selectedStudies.each{ study -> 
    80                          study.groups.each{ group -> studyGroups.add[group] } 
    81                      } 
    82                      println "study groups: " 
    83                      studyGroups.each{x-> println x} 
    84                   } 
    85  
    86                   // testing: 
    87                   // there is a lack of data in the mockup (subject groups are still missing) 
    88                   // as long as there are no groups in the boot script, 
    89                   // we use this 
    90                   subgroups = studyGroups.size()<=0 ? 
    91                        ["subject group 1","subject group 2"] : studyGroups 
    92  
    93                   render(view:"selectsample",model:[selectedStudies:selectedStudies,selectedStudyIds:selectedStudyIds,subgroups:subgroups]) 
    94                   break 
    95  
    96              case "Event Groups": 
    97                   def eventGroups = [] 
    98                   if(selectedStudies!=null) 
    99                   { 
    100                     selectedStudies.each{ study -> 
    101                          println study.id 
    102                          println study.samplingEvents.each{ eventGroups.add(it) } 
    103                     } 
    104                   } 
    105                   subgroups=eventGroups 
    106                   render(view:"selectsample",model:[selectedStudies:selectedStudies,selectedStudyIds:selectedStudyIds,subgroups:subgroups]) 
    107                   break 
    108  
    109              case "Starting Time Groups": 
    110  
    111                   def timeGroups = [] 
    112                   if(selectedStudies!=null) 
    113                   { 
    114                     selectedStudies.each{ study -> 
    115                          println study.samplingEvents.each{  
    116                              def timeDiff = it.getPrettyDuration( study.startDate, it.startTime )  
    117                              if( !timeGroups.contains(timeDiff) ) timeGroups.add(timeDiff) 
    118                          } 
    119                     } 
    120                   } 
    121                   subgroups=timeGroups 
    122                   render("Starting Time Groups") 
    123                   render(view:"selectsample",model:[selectedStudies:selectedStudies,selectedStudyIds:selectedStudyIds,subgroups:subgroups]) 
    124                   break 
    125  
    126              case ">> Execute and continue with biomarker selection": 
    127                   render("Starting Time Groups") 
    128                   break 
    129              case "<< Back to study selection": 
    130                   break 
    131         } 
    132         render(view:"selectsample",model:[selectedStudies:selectedStudies,selectedStudyIds:selectedStudyIds,subgroups:subgroups]) 
    133     } 
    134  
    135  
    13626 
    13727    /** 
     
    16656        render("unindexAll done") 
    16757    } 
    168  
    169  
    170     def subjectGroups = { render ("hello") } 
    171  
    172  
    17358} 
  • trunk/grails-app/taglib/dbnp/query/QueryTagLib.groovy

    r315 r316  
    1313 * 
    1414 * Revision information: 
    15  * $Rev$ 
    16  * $Author$ 
    17  * $Date$ 
     15 * $Rev: 299 $ 
     16 * $Author: duh $ 
     17 * $Date: 2010-03-22 14:40:35 +0100 (Mon, 22 Mar 2010) $ 
    1818 */ 
    19  
    20 class QueryTagLib extends JavascriptTagLib { 
     19class WizardTagLib extends JavascriptTagLib { 
     20        // define the tag namespace (e.g.: <wizard:action ... /> 
     21        static namespace = "wizard" 
     22 
     23        // define the AJAX provider to use 
     24        static ajaxProvider = "jquery" 
     25 
     26        // define default text field width 
     27        static defaultTextFieldSize = 25; 
     28 
     29        /** 
     30         * ajaxButton tag, this is a modified version of the default 
     31         * grails submitToRemote tag to work with grails webflows. 
     32         * Usage is identical to submitToRemote with the only exception 
     33         * that a 'name' form element attribute is required. E.g. 
     34         * <wizard:ajaxButton name="myAction" value="myButton ... /> 
     35         * 
     36         * you can also provide a javascript function to execute after 
     37         * success. This behaviour differs from the default 'after' 
     38         * action which always fires after a button press... 
     39         * 
     40         * @see http://blog.osx.eu/2010/01/18/ajaxifying-a-grails-webflow/ 
     41         * @see http://www.grails.org/WebFlow 
     42         * @see http://www.grails.org/Tag+-+submitToRemote 
     43         * @todo perhaps some methods should be moved to a more generic 
     44         *        'webflow' taglib or plugin 
     45         * @param Map attributes 
     46         * @param Closure body 
     47         */ 
     48        def ajaxButton = {attrs, body -> 
     49                // get the jQuery version 
     50                def jQueryVersion = grailsApplication.getMetadata()['plugins.jquery'] 
     51 
     52                // fetch the element name from the attributes 
     53                def elementName = attrs['name'].replaceAll(/ /, "_") 
     54 
     55                // javascript function to call after success 
     56                def afterSuccess = attrs['afterSuccess'] 
     57 
     58                // src parameter? 
     59                def src = attrs['src'] 
     60                def alt = attrs['alt'] 
     61 
     62                // generate a normal submitToRemote button 
     63                def button = submitToRemote(attrs, body) 
     64 
     65                /** 
     66                 * as of now (grails 1.2.0 and jQuery 1.3.2.4) the grails webflow does 
     67                 * not properly work with AJAX as the submitToRemote button does not 
     68                 * handle and submit the form properly. In order to support webflows 
     69                 * this method modifies two parts of a 'normal' submitToRemote button: 
     70                 * 
     71                 * 1) replace 'this' with 'this.form' as the 'this' selector in a button 
     72                 *    action refers to the button and / or the action upon that button. 
     73                 *    However, it should point to the form the button is part of as the 
     74                 *    the button should submit the form data. 
     75                 * 2) prepend the button name to the serialized data. The default behaviour 
     76                 *    of submitToRemote is to remove the element name altogether, while 
     77                 *    the grails webflow expects a parameter _eventId_BUTTONNAME to execute 
     78                 *    the appropriate webflow action. Hence, we are going to prepend the 
     79                 *    serialized formdata with an _eventId_BUTTONNAME parameter. 
     80                 */ 
     81                if (jQueryVersion =~ /^1.([1|2|3]).(.*)/) { 
     82                        // fix for older jQuery plugin versions 
     83                        button = button.replaceFirst(/data\:jQuery\(this\)\.serialize\(\)/, "data:\'_eventId_${elementName}=1&\'+jQuery(this.form).serialize()") 
     84                } else { 
     85                        // as of jQuery plugin version 1.4.0.1 submitToRemote has been modified and the 
     86                        // this.form part has been fixed. Consequently, our wrapper has changed as well... 
     87                        button = button.replaceFirst(/data\:jQuery/, "data:\'_eventId_${elementName}=1&\'+jQuery") 
     88                } 
     89 
     90                // add an after success function call? 
     91                // usefull for performing actions on success data (hence on refreshed 
     92                // wizard pages, such as attaching tooltips) 
     93                if (afterSuccess) { 
     94                        button = button.replaceFirst(/\.html\(data\)\;/, '.html(data);' + afterSuccess + ';') 
     95                } 
     96 
     97                // got an src parameter? 
     98                if (src) { 
     99                        def replace = 'type="image" src="' + src + '"' 
     100 
     101                        if (alt) replace = replace + ' alt="' + alt + '"' 
     102 
     103                        button = button.replaceFirst(/type="button"/, replace) 
     104                } 
     105 
     106                // replace double semi colons 
     107                button = button.replaceAll(/;{2,}/, ';') 
     108 
     109                // render button 
     110                out << button 
     111        } 
     112 
     113        /** 
     114         * generate a ajax submit JavaScript 
     115         * @see WizardTagLib::ajaxFlowRedirect 
     116         * @see WizardTagLib::baseElement (ajaxSubmitOnChange) 
     117         */ 
     118        def ajaxSubmitJs = {attrs, body -> 
     119                // define AJAX provider 
     120                setProvider([library: ajaxProvider]) 
     121 
     122                // got a function name? 
     123                def functionName = attrs.remove('functionName') 
     124                if (functionName && !attrs.get('name')) { 
     125                        attrs.name = functionName 
     126                } 
     127 
     128                // generate an ajax button 
     129                def button = this.ajaxButton(attrs, body) 
     130 
     131                // strip the button part to only leave the Ajax call 
     132                button = button.replaceFirst(/<[^\"]*\"jQuery.ajax/, 'jQuery.ajax') 
     133                button = button.replaceFirst(/return false.*/, '') 
     134 
     135                // change form if a form attribute is present 
     136                if (attrs.get('form')) { 
     137                        button = button.replaceFirst(/this\.form/, 
     138                                "\\\$('" + attrs.get('form') + "')" 
     139                        ) 
     140                } 
     141 
     142                out << button 
     143        } 
     144 
     145        /** 
     146         * generate ajax webflow redirect javascript 
     147         * 
     148         * As we have an Ajaxified webflow, the initial wizard page 
     149         * cannot contain a wizard form, as upon a failing submit 
     150         * (e.g. the form data does not validate) the form should be 
     151         * shown again. However, the Grails webflow then renders the 
     152         * complete initial wizard page into the success div. As this 
     153         * ruins the page layout (a page within a page) we want the 
     154         * initial page to redirect to the first wizard form to enter 
     155         * the webflow correctly. We do this by emulating an ajax post 
     156         * call which updates the wizard content with the first wizard 
     157         * form. 
     158         * 
     159         * Usage: <wizard:ajaxFlowRedirect form="form#wizardForm" name="next" url="[controller:'wizard',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" /> 
     160         * form = the form identifier 
     161         * name = the action to execute in the webflow 
     162         * update = the divs to update upon success or error 
     163         * 
     164         * OR: to generate a JavaScript function you can call yourself, use 'functionName' instead of 'name' 
     165         * 
     166         * Example initial webflow action to work with this javascript: 
     167         * ... 
     168         * mainPage {*  render(view: "/wizard/index") 
     169         *      onRender {*             flow.page = 1 
     170         *}*    on("next").to "pageOne" 
     171         *}* ... 
     172         * 
     173         * @param Map attributes 
     174         * @param Closure body 
     175         */ 
     176        def ajaxFlowRedirect = {attrs, body -> 
     177                // generate javascript 
     178                out << '<script type="text/javascript">' 
     179                out << '$(document).ready(function() {' 
     180                out << ajaxSubmitJs(attrs, body) 
     181                out << '});' 
     182                out << '</script>' 
     183        } 
    21184 
    22185        /** 
     
    25188         * @param Closure body  (help text) 
    26189         */ 
    27  
    28190        def pageContent = {attrs, body -> 
    29191                // define AJAX provider 
     
    31193 
    32194                // render new body content 
    33                  
    34195                out << render(template: "/query/common/tabs") 
    35196                out << '<div class="content">' 
     
    38199                out << render(template: "/query/common/navigation") 
    39200                out << render(template: "/query/common/error") 
    40                  
    41         } 
    42  
     201        } 
     202 
     203        /** 
     204         * generate a base form element 
     205         * @param String inputElement name 
     206         * @param Map attributes 
     207         * @param Closure help content 
     208         */ 
     209        def baseElement = {inputElement, attrs, help -> 
     210                // work variables 
     211                def description = attrs.remove('description') 
     212                def addExampleElement = attrs.remove('addExampleElement') 
     213                def addExample2Element = attrs.remove('addExample2Element') 
     214 
     215                // got an ajax onchange action? 
     216                def ajaxOnChange = attrs.remove('ajaxOnChange') 
     217                if (ajaxOnChange) { 
     218                        if (!attrs.onChange) attrs.onChange = '' 
     219 
     220                        // add onChange AjaxSubmit javascript 
     221                        attrs.onChange += ajaxSubmitJs( 
     222                                [ 
     223                                        functionName: ajaxOnChange, 
     224                                        url: attrs.get('url'), 
     225                                        update: attrs.get('update'), 
     226                                        afterSuccess: attrs.get('afterSuccess') 
     227                                ], 
     228                                '' 
     229                        ) 
     230                } 
     231 
     232                // execute inputElement call 
     233                def renderedElement = "$inputElement"(attrs) 
     234 
     235                // if false, then we skip this element 
     236                if (!renderedElement) return false 
     237 
     238                // render a form element 
     239                out << '<div class="element">' 
     240                out << ' <div class="description">' 
     241                out << description 
     242                out << ' </div>' 
     243                out << ' <div class="input">' 
     244                out << renderedElement 
     245                if (help()) { 
     246                        out << '        <div class="helpIcon"></div>' 
     247                } 
     248 
     249                // add an disabled input box for feedback purposes 
     250                // @see dateElement(...) 
     251                if (addExampleElement) { 
     252                        def exampleAttrs = new LinkedHashMap() 
     253                        exampleAttrs.name = attrs.get('name') + 'Example' 
     254                        exampleAttrs.class = 'isExample' 
     255                        exampleAttrs.disabled = 'disabled' 
     256                        exampleAttrs.size = 30 
     257                        out << textField(exampleAttrs) 
     258                } 
     259 
     260                // add an disabled input box for feedback purposes 
     261                // @see dateElement(...) 
     262                if (addExample2Element) { 
     263                        def exampleAttrs = new LinkedHashMap() 
     264                        exampleAttrs.name = attrs.get('name') + 'Example2' 
     265                        exampleAttrs.class = 'isExample' 
     266                        exampleAttrs.disabled = 'disabled' 
     267                        exampleAttrs.size = 30 
     268                        out << textField(exampleAttrs) 
     269                } 
     270 
     271                out << ' </div>' 
     272 
     273                // add help content if it is available 
     274                if (help()) { 
     275                        out << '  <div class="helpContent">' 
     276                        out << '    ' + help() 
     277                        out << '  </div>' 
     278                } 
     279 
     280                out << '</div>' 
     281        } 
     282 
     283        /** 
     284         * render a textFieldElement 
     285         * @param Map attrs 
     286         * @param Closure body  (help text) 
     287         */ 
     288        def textFieldElement = {attrs, body -> 
     289                // set default size, or scale to max length if it is less than the default size 
     290                if (!attrs.get("size")) { 
     291                        if (attrs.get("maxlength")) { 
     292                                attrs.size = ((attrs.get("maxlength") as int) > defaultTextFieldSize) ? defaultTextFieldSize : attrs.get("maxlength") 
     293                        } else { 
     294                                attrs.size = defaultTextFieldSize 
     295                        } 
     296                } 
     297 
     298                // render template element 
     299                baseElement.call( 
     300                        'textField', 
     301                        attrs, 
     302                        body 
     303                ) 
     304        } 
     305 
     306        /** 
     307         * render a select form element 
     308         * @param Map attrs 
     309         * @param Closure body  (help text) 
     310         */ 
     311        def selectElement = {attrs, body -> 
     312                baseElement.call( 
     313                        'select', 
     314                        attrs, 
     315                        body 
     316                ) 
     317        } 
     318 
     319        /** 
     320         * render a checkBox form element 
     321         * @param Map attrs 
     322         * @param Closure body  (help text) 
     323         */ 
     324        def checkBoxElement = {attrs, body -> 
     325                baseElement.call( 
     326                        'checkBox', 
     327                        attrs, 
     328                        body 
     329                ) 
     330        } 
     331 
     332        /** 
     333         * render a dateElement 
     334         * NOTE: datepicker is attached through wizard.js! 
     335         * @param Map attrs 
     336         * @param Closure body  (help text) 
     337         */ 
     338        def dateElement = {attrs, body -> 
     339                // transform value? 
     340                if (attrs.value instanceof Date) { 
     341                        // transform date instance to formatted string (dd/mm/yyyy) 
     342                        attrs.value = String.format('%td/%<tm/%<tY', attrs.value) 
     343                } 
     344 
     345                // add 'rel' field to identity the datefield using javascript 
     346                attrs.rel = 'date' 
     347 
     348                // set some textfield values 
     349                attrs.maxlength = (attrs.maxlength) ? attrs.maxlength : 10 
     350                attrs.addExampleElement = true 
     351 
     352                // render a normal text field 
     353                //out << textFieldElement(attrs,body) 
     354                textFieldElement.call( 
     355                        attrs, 
     356                        body 
     357                ) 
     358        } 
     359 
     360        /** 
     361         * render a dateElement 
     362         * NOTE: datepicker is attached through wizard.js! 
     363         * @param Map attrs 
     364         * @param Closure body  (help text) 
     365         */ 
     366        def timeElement = {attrs, body -> 
     367                // transform value? 
     368                if (attrs.value instanceof Date) { 
     369                        // transform date instance to formatted string (dd/mm/yyyy) 
     370                        attrs.value = String.format('%td/%<tm/%<tY %<tH:%<tM', attrs.value) 
     371                } 
     372 
     373                // add 'rel' field to identity the field using javascript 
     374                attrs.rel = 'datetime' 
     375 
     376                attrs.addExampleElement = true 
     377                attrs.addExample2Element = true 
     378                attrs.maxlength = 16 
     379 
     380                // render a normal text field 
     381                //out << textFieldElement(attrs,body) 
     382                textFieldElement.call( 
     383                        attrs, 
     384                        body 
     385                ) 
     386        } 
     387 
     388        /** 
     389         * Template form element 
     390         * @param Map attributes 
     391         * @param Closure help content 
     392         */ 
     393        def speciesElement = {attrs, body -> 
     394                // render template element 
     395                baseElement.call( 
     396                        'speciesSelect', 
     397                        attrs, 
     398                        body 
     399                ) 
     400        } 
     401 
     402        /** 
     403         * Button form element 
     404         * @param Map attributes 
     405         * @param Closure help content 
     406         */ 
     407        def buttonElement = {attrs, body -> 
     408                // render template element 
     409                baseElement.call( 
     410                        'ajaxButton', 
     411                        attrs, 
     412                        body 
     413                ) 
     414        } 
     415 
     416        /** 
     417         * render a species select element 
     418         * @param Map attrs 
     419         */ 
     420        def speciesSelect = {attrs -> 
     421                // fetch the speciesOntology 
     422                // note that this is a bit nasty, probably the ontologyName should 
     423                // be configured in a configuration file... --> TODO: centralize species configuration 
     424                def speciesOntology = Ontology.findByName('NCBI Taxonomy') 
     425 
     426                // fetch all species 
     427                attrs.from = Term.findAllByOntology(speciesOntology) 
     428 
     429                // got a name? 
     430                if (!attrs.name) { 
     431                        // nope, use a default name 
     432                        attrs.name = 'species' 
     433                } 
     434 
     435                out << select(attrs) 
     436        } 
     437 
     438        /** 
     439         * Template form element 
     440         * @param Map attributes 
     441         * @param Closure help content 
     442         */ 
     443        def templateElement = {attrs, body -> 
     444                // render template element 
     445                baseElement.call( 
     446                        'templateSelect', 
     447                        attrs, 
     448                        body 
     449                ) 
     450        } 
     451 
     452        /** 
     453         * render a template select element 
     454         * @param Map attrs 
     455         */ 
     456        def templateSelect = {attrs -> 
     457                def entity = attrs.remove('entity') 
     458 
     459                // fetch templates 
     460                if (attrs.remove('addDummy')) { 
     461                        attrs.from = [''] 
     462                        if (entity && entity instanceof Class) { 
     463                                Template.findAllByEntity(entity).each() { 
     464                                        attrs.from[attrs.from.size()] = it 
     465                                } 
     466                        } 
     467                } else { 
     468                        attrs.from = (entity) ? Template.findAllByEntity(entity) : Template.findAll() 
     469                } 
     470 
     471                // got a name? 
     472                if (!attrs.name) { 
     473                        attrs.name = 'template' 
     474                } 
     475 
     476                // got result? 
     477                if (attrs.from.size() > 0) { 
     478                        out << select(attrs) 
     479                } else { 
     480                        // no, return false to make sure this element 
     481                        // is not rendered in the template 
     482                        return false 
     483                } 
     484        } 
     485 
     486        /** 
     487         * Term form element 
     488         * @param Map attributes 
     489         * @param Closure help content 
     490         */ 
     491        def termElement = {attrs, body -> 
     492                // render term element 
     493                baseElement.call( 
     494                        'termSelect', 
     495                        attrs, 
     496                        body 
     497                ) 
     498        } 
     499 
     500        /** 
     501         * render a term select element 
     502         * @param Map attrs 
     503         */ 
     504        def termSelect = {attrs -> 
     505                // fetch all terms 
     506                attrs.from = Term.findAll()     // for now, all terms as we cannot identify terms as being treatment terms... 
     507 
     508                // got a name? 
     509                if (!attrs.name) { 
     510                        attrs.name = 'term' 
     511                } 
     512 
     513                out << select(attrs) 
     514        } 
     515 
     516        /** 
     517         * Protocol form element 
     518         * @param Map attributes 
     519         * @param Closure help content 
     520         */ 
     521        def protocolElement = {attrs, body -> 
     522                // render protocol element 
     523                baseElement.call( 
     524                        'protocolSelect', 
     525                        attrs, 
     526                        body 
     527                ) 
     528        } 
     529 
     530        /** 
     531         * render a protocol select element 
     532         * @param Map attrs 
     533         */ 
     534        def protocolSelect = {attrs -> 
     535                // fetch all protocold 
     536                attrs.from = Protocol.findAll() // for now, all protocols 
     537 
     538                // got a name? 
     539                if (!attrs.name) { 
     540                        attrs.name = 'protocol' 
     541                } 
     542 
     543                out << select(attrs) 
     544        } 
     545 
     546        def show = {attrs -> 
     547                // is object parameter set? 
     548                def o = attrs.object 
     549 
     550                println o.getProperties(); 
     551                o.getProperties().each { 
     552                        println it 
     553                } 
     554 
     555                out << "!! test version of 'show' tag !!" 
     556        } 
     557 
     558        /** 
     559         * render table headers for all subjectFields in a template 
     560         * @param Map attributes 
     561         */ 
     562        def templateColumnHeaders = {attrs -> 
     563                def template = attrs.remove('template') 
     564 
     565                // output table headers for template fields 
     566                template.fields.each() { 
     567                        out << '<div class="' + attrs.get('class') + '">' + it + '</div>' 
     568                } 
     569        } 
     570 
     571        /** 
     572         * render table input elements for all subjectFields in a template 
     573         * @param Map attributes 
     574         */ 
     575        def templateColumns = {attrs, body -> 
     576                def subject = attrs.remove('subject') 
     577                def subjectId = attrs.remove('id') 
     578                def template = attrs.remove('template') 
     579                def intFields = subject.templateIntegerFields 
     580                def stringFields = subject.templateStringFields 
     581                def floatFields = subject.templateFloatFields 
     582                def termFields = subject.templateTermFields 
     583 
     584                // output columns for these subjectFields 
     585                template.fields.each() { 
     586                        def fieldValue = subject.getFieldValue(it.name) 
     587 
     588                        // output div 
     589                        out << '<div class="' + attrs.get('class') + '">' 
     590 
     591                        // handle field types 
     592                        switch (it.type.toString()) { 
     593                                case ['STRING', 'TEXT', 'INTEGER', 'FLOAT', 'DOUBLE']: 
     594                                        out << textField( 
     595                                                name: attrs.name + '_' + it.escapedName(), 
     596                                                value: fieldValue 
     597                                        ) 
     598                                        break 
     599                                case 'STRINGLIST': 
     600                                        // render stringlist subjectfield 
     601                                        if (!it.listEntries.isEmpty()) { 
     602                                                out << select( 
     603                                                        name: attrs.name + '_' + it.escapedName(), 
     604                                                        from: it.listEntries, 
     605                                                        value: fieldValue 
     606                                                ) 
     607                                        } else { 
     608                                                out << '<span class="warning">no values!!</span>' 
     609                                        } 
     610                                        break 
     611                                case 'DATE': 
     612                                        // transform value? 
     613                                        if (fieldValue instanceof Date) { 
     614                                                if (fieldValue.getHours() == 0 && fieldValue.getMinutes() == 0) { 
     615                                                        // transform date instance to formatted string (dd/mm/yyyy) 
     616                                                        fieldValue = String.format('%td/%<tm/%<tY', fieldValue) 
     617                                                } else { 
     618                                                        // transform to date + time 
     619                                                        fieldValue = String.format('%td/%<tm/%<tY %<tH:%<tM', fieldValue) 
     620                                                } 
     621                                        } 
     622 
     623                                        // output a date field (not the 'rel' which makes the 
     624                                        // javascript front-end bind the jquery-ui datepicker) 
     625                                        out << textField( 
     626                                                name: attrs.name + '_' + it.escapedName(), 
     627                                                value: fieldValue, 
     628                                                rel: 'date' 
     629                                        ) 
     630                                        break 
     631                                case 'ONTOLOGYTERM': 
     632                                        // @see http://www.bioontology.org/wiki/index.php/NCBO_Widgets#Term-selection_field_on_a_form 
     633                                        // @see ontology-chooser.js, table-editor.js 
     634                                        //out << it.getClass() 
     635                                        out << textField( 
     636                                                name: attrs.name + '_' + it.escapedName(), 
     637                                                value: fieldValue, 
     638                                                rel: 'ontology-all-name', 
     639                                                size: 100 
     640                                        ) 
     641                                        out << hiddenField( 
     642                                                name: attrs.name + '_' + it.escapedName() + '-concept_id' 
     643                                        ) 
     644                                        out << hiddenField( 
     645                                                name: attrs.name + '_' + it.escapedName() + '-ontology_id' 
     646                                        ) 
     647                                        out << hiddenField( 
     648                                                name: attrs.name + '_' + it.escapedName() + '-full_id' 
     649                                        ) 
     650                                        break 
     651                                default: 
     652                                        // unsupported field type 
     653                                        out << '<span class="warning">!' + it.type + '</span>' 
     654                                        break 
     655                        } 
     656 
     657                        out << '</div>' 
     658                } 
     659        } 
     660 
     661        /** 
     662         * render form elements based on an entity's template 
     663         * @param Map attributes 
     664         * @param String body 
     665         */ 
     666        def templateElements = {attrs -> 
     667                def entity = (attrs.get('entity')) 
     668                def template = (entity && entity instanceof TemplateEntity) ? entity.template : null 
     669 
     670                // got a template? 
     671                if (template) { 
     672                        // render template fields 
     673                        template.fields.each() { 
     674                                def fieldValue = entity.getFieldValue(it.name) 
     675 
     676                                switch (it.type.toString()) { 
     677                                        case ['STRING', 'TEXT', 'INTEGER', 'FLOAT', 'DOUBLE']: 
     678                                                out << textFieldElement( 
     679                                                        description: it.name, 
     680                                                        name: it.escapedName(), 
     681                                                        value: fieldValue 
     682                                                ) 
     683                                                break 
     684                                        case 'STRINGLIST': 
     685                                                if (!it.listEntries.isEmpty()) { 
     686                                                        out << selectElement( 
     687                                                                description: it.name, 
     688                                                                name: it.escapedName(), 
     689                                                                from: it.listEntries, 
     690                                                                value: fieldValue 
     691                                                        ) 
     692                                                } else { 
     693                                                        out << '<span class="warning">no values!!</span>' 
     694                                                } 
     695                                                break 
     696                                        case 'ONTOLOGYTERM': 
     697                                                // @see http://www.bioontology.org/wiki/index.php/NCBO_Widgets#Term-selection_field_on_a_form 
     698                                                // @see ontology-chooser.js 
     699                                                out << textFieldElement( 
     700                                                        name: it.escapedName(), 
     701                                                        value: fieldValue, 
     702                                                        rel: 'ontology-all-name', 
     703                                                        size: 100 
     704                                                ) 
     705                                                out << hiddenField( 
     706                                                        name: it.name + '-concept_id', 
     707                                                        value: fieldValue 
     708                                                ) 
     709                                                out << hiddenField( 
     710                                                        name: it.escapedName() + '-ontology_id', 
     711                                                        value: fieldValue 
     712                                                ) 
     713                                                out << hiddenField( 
     714                                                        name: it.escapedName() + '-full_id', 
     715                                                        value: fieldValue 
     716                                                ) 
     717                                                break 
     718                                        case 'DATE': 
     719                                                out << dateElement( 
     720                                                        description: it.name, 
     721                                                        name: it.escapedName(), 
     722                                                        value: fieldValue 
     723                                                ) 
     724                                                break 
     725                                        default: 
     726                                                out << "unkown field type '" + it.type + "'<br/>" 
     727                                                break 
     728                                } 
     729                        } 
     730                } 
     731        } 
    43732} 
  • trunk/grails-app/views/query/common/_error.gsp

    r315 r316  
    1515         */ 
    1616%> 
     17<g:if test="${errors}"> 
     18        <div id="wizardError" class="error" title="errors"> 
     19                <g:each in="${errors}" var="error" status="e"> 
     20                        <p> 
     21                                <g:if test="${!e}"><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 50px 0;"></span></g:if> 
     22                                ${error.value['key']} &rarr; ${error.value['value']} 
     23${error.value['dynamic']} 
     24                        </p> 
     25                </g:each> 
     26        </div> 
     27        <script type="text/javascript"> 
     28                // mark error fields 
     29                <g:each in="${errors}" var="error"> 
     30                <g:if test="${error.value['dynamic']}"> 
     31                $("input:[name='${error.key}'], select:[name='${error.key}']").addClass('error'); 
     32                </g:if><g:else> 
     33                $("input:[name='${error.key}'], select:[name='${error.key}']").parent().parent().addClass('error'); 
     34                </g:else> 
     35                </g:each> 
    1736 
    18 error... 
     37                // show error dialog 
     38                var we = $("div#wizardError"); 
     39                we.dialog({ 
     40                        modal: true, 
     41                        width: 600, 
     42                        buttons: { 
     43                                Ok: function() { 
     44                                        $(this).dialog('close'); 
     45                                        we.remove(); 
     46                                } 
     47                        } 
     48                }); 
     49        </script> 
     50</g:if> 
     51 
  • trunk/grails-app/views/query/common/_query.gsp

    r315 r316  
    1616%> 
    1717<div id="wizard" class="wizard"> 
    18         <h1>Create a new study</h1> 
     18        <h1>Query</h1> 
    1919        <g:form action="pages" name="wizardForm" id="wizardForm"> 
    2020        <g:hiddenField name="do" value="" /> 
  • trunk/grails-app/views/query/mainPage.gsp

    r314 r316  
     1 
    12<html> 
    2     <head> 
    3       <title>Generic Study Capture Framework - Query studies</title> 
    4       <meta name="layout" content="main" /> 
    5       <script type="text/javascript"> 
    6         $(function() { 
    7                 $("#tabs").tabs(); 
    8         }); 
    9       </script> 
    10     </head> 
    11     <body> 
    12  
    13 aaaaaaa 
    14  
    15  
    16  
    17 <div id="wizard" class="wizard"> 
    18         <h1>Create a new study</h1> 
    19         <g:form action="pages" name="wizardForm" id="wizardForm"> 
    20         <g:hiddenField name="do" value="" /> 
    21                 <div id="wizardPage"> 
    22                         <wizard:ajaxFlowRedirect form="form#wizardForm" name="next" url="[controller:'query',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" /> 
    23                 </div> 
    24         </g:form> 
    25 </div> 
    26  
    27  
    28  
    29  
    30   </body> 
     3<head> 
     4        <meta name="layout" content="main"/><g:if env="production"> 
     5        <link rel="stylesheet" href="${resource(dir: 'css', file: 'wizard.min.css')}"/> 
     6        <script type="text/javascript" src="${resource(dir: 'js', file: 'jquery.qtip-1.0.0-rc3.min.js')}"></script> 
     7        <script type="text/javascript" src="${resource(dir: 'js', file: 'swfobject.min.js')}"></script> 
     8        <script type="text/javascript" src="${resource(dir: 'js', file: 'table-editor.min.js')}"></script> 
     9        <script type="text/javascript" src="${resource(dir: 'js', file: 'ontology-chooser.min.js')}"></script> 
     10        <script type="text/javascript" src="${resource(dir: 'js', file: 'timepicker-0.2.1.min.js')}"></script> 
     11        <script type="text/javascript" src="${resource(dir: 'js', file: 'wizard.min.js')}"></script> 
     12</g:if><g:else> 
     13        <link rel="stylesheet" href="${resource(dir: 'css', file: 'wizard.css')}"/> 
     14        <script type="text/javascript" src="${resource(dir: 'js', file: 'jquery.qtip-1.0.0-rc3.min.js')}"></script> 
     15        <script type="text/javascript" src="${resource(dir: 'js', file: 'swfobject.js')}"></script> 
     16        <script type="text/javascript" src="${resource(dir: 'js', file: 'table-editor.js')}"></script> 
     17        <script type="text/javascript" src="${resource(dir: 'js', file: 'ontology-chooser.js')}"></script> 
     18        <script type="text/javascript" src="${resource(dir: 'js', file: 'timepicker-0.2.1.js')}"></script> 
     19        <script type="text/javascript" src="${resource(dir: 'js', file: 'wizard.js')}"></script> 
     20</g:else> 
     21</head> 
     22<body> 
     23<g:render template="common/query"/> 
     24</body> 
    3125</html> 
  • trunk/grails-app/views/query/pages/_biomarker.gsp

    r314 r316  
    1 biomarker 
     1<wizard:pageContent> 
     2        Biomarkers 
     3</wizard:pageContent> 
     4 
  • trunk/grails-app/views/query/pages/_group.gsp

    r314 r316  
    1 group 
     1<wizard:pageContent> 
     2    Group 
     3</wizard:pageContent> 
     4 
  • trunk/grails-app/views/query/pages/_result.gsp

    r314 r316  
    1 result 
     1<wizard:pageContent> 
     2        Results 
     3</wizard:pageContent> 
     4 
  • trunk/grails-app/views/query/pages/_sample.gsp

    r314 r316  
    1 sample 
     1<wizard:pageContent> 
     2 
     3  Select samples 
     4</wizard:pageContent> 
  • trunk/grails-app/views/query/pages/_study.gsp

    r314 r316  
    11<wizard:pageContent> 
    2         hello world 
     2        Study 
    33</wizard:pageContent> 
  • trunk/grails-app/views/study/list_extended.gsp

    r299 r316  
    4444 
    4545    <% if (selectedStudies.size()>0) {%> 
    46  
    4746 
    4847        <div id="tabs"> 
     
    225224 
    226225          <% def protocol_list = [] %> 
    227           <% def tmp_protocol = stud.events.eventDescription.protocol.get(0) %> 
    228           <% def tmpBis_protocol = stud.samplingEvents.eventDescription.protocol.get(0) %> 
    229           <% protocol_list.add(tmp_protocol) %> 
    230           <% protocol_list.add(tmpBis_protocol) %> 
    231  
    232           <g:each in="${stud.events.eventDescription.protocol}" var="s"> 
    233           <% if (tmp_protocol!=s) { %> 
    234             <% protocol_list.add(s) %> 
    235             <%}%> 
    236           </g:each> 
    237  
    238  <g:each in="${stud.samplingEvents.eventDescription.protocol}" var="s"> 
    239           <% if (tmpBis_protocol!=s) { %> 
    240             <% protocol_list.add(s) %> 
    241             <%}%> 
    242           </g:each> 
     226          <% protocol_list.add(stud.events.eventDescription.protocol.unique()) %> 
     227          <% protocol_list.addAll(stud.samplingEvents.eventDescription.protocol.unique()) %> 
    243228 
    244229          <g:each in="${protocol_list}" var="protocol"> 
     
    292277          <td>${e.getPrettyDuration()}</td> 
    293278           <td><g:checkBox name="event" disabled="${true}" value="${false}"/></td> 
    294           <g:each in="${e.eventDescription.protocol.parameters}" var="param"> 
    295           <td> 
    296             ${param.name} : ${param.listEntries} 
    297           </td> 
    298             </g:each> 
    299             </tr> 
     279 
     280           </tr> 
    300281          </g:each> 
    301282 
  • trunk/grails-app/views/study/show.gsp

    r299 r316  
    371371    </div> 
    372372  </div> 
    373 </div> 
    374373</body> 
    375374</html>