Changeset 316
- Timestamp:
- Mar 26, 2010, 1:02:39 PM (14 years ago)
- Location:
- trunk/grails-app
- Files:
-
- 1 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/controllers/SearchableController.groovy
r247 r316 1 2 1 /* 3 2 * Copyright 2007 the original author or authors. … … 21 20 * Basic web interface for Grails Searchable Plugin 22 21 * 23 * @author Adem and Jahn22 * @author Maurice Nicholson 24 23 */ 25 24 class SearchableController { 26 25 def searchableService 27 28 def selectsample = {29 30 31 // produce error message here if studies don't contain samples!32 // redirect back or use error33 34 35 println "in selectsample: "36 params.each{println it}37 38 // prepare showing all studies selected in the previous view39 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 else48 {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 // subgroups66 // provide list of subgroups depending on the type of subgrouping67 // selected by the user68 def subgroups = []69 def submitButton = params["submit"] // this button's value determines the kind of subgrouping70 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 this90 subgroups = studyGroups.size()<=0 ?91 ["subject group 1","subject group 2"] : studyGroups92 93 render(view:"selectsample",model:[selectedStudies:selectedStudies,selectedStudyIds:selectedStudyIds,subgroups:subgroups])94 break95 96 case "Event Groups":97 def eventGroups = []98 if(selectedStudies!=null)99 {100 selectedStudies.each{ study ->101 println study.id102 println study.samplingEvents.each{ eventGroups.add(it) }103 }104 }105 subgroups=eventGroups106 render(view:"selectsample",model:[selectedStudies:selectedStudies,selectedStudyIds:selectedStudyIds,subgroups:subgroups])107 break108 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=timeGroups122 render("Starting Time Groups")123 render(view:"selectsample",model:[selectedStudies:selectedStudies,selectedStudyIds:selectedStudyIds,subgroups:subgroups])124 break125 126 case ">> Execute and continue with biomarker selection":127 render("Starting Time Groups")128 break129 case "<< Back to study selection":130 break131 }132 render(view:"selectsample",model:[selectedStudies:selectedStudies,selectedStudyIds:selectedStudyIds,subgroups:subgroups])133 }134 135 136 26 137 27 /** … … 166 56 render("unindexAll done") 167 57 } 168 169 170 def subjectGroups = { render ("hello") }171 172 173 58 } -
trunk/grails-app/controllers/dbnp/query/QueryController.groovy
r315 r316 33 33 } 34 34 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 35 47 def pagesFlow = { 36 48 … … 38 50 flow.page = 0 39 51 flow.pages = [ 52 [title: 'Query'], 40 53 [title: 'Study'], 41 54 [title: 'Samples'], … … 52 65 onRender { 53 66 println "done randering index" 67 flow.page=1 54 68 } 55 56 57 69 on("next") { 58 70 println "clicked next in sample" 59 } .to 'study' 60 71 } .to 'inputQuery' 61 72 } 62 73 74 inputQuery { 75 render(view:'_inputQuery') 76 onRender { 77 flow.page=1 78 } 79 } 63 80 64 81 study { 65 82 render( view:'_study') 66 83 onRender { 84 flow.page=2 85 } 67 86 on("next") { 68 87 println "clicked next in sample" 69 88 } .to 'sample' 70 89 on("previous"){}.to 'inputQuery' 71 90 } 72 73 74 91 75 92 sample { 76 93 render( view:'_sample') 77 94 onRender { 95 flow.page=3 96 } 78 97 on("next") { 79 98 println "clicked next in sample" 80 99 } .to 'biomarker' 81 100 on("previous"){}.to 'study' 82 101 } 83 102 … … 85 104 biomarker { 86 105 render( view:'_biomarker') 87 106 onRender { 107 flow.page=4 108 } 88 109 on("next") { 89 110 println "clicked next in sample" 90 111 } .to 'group' 91 112 on("previous"){}.to 'sample' 92 113 } 93 94 114 95 115 group { 96 116 render( view:'_group') 97 117 onRender { 118 flow.page=5 119 } 98 120 on("next") { 99 121 println "clicked next in sample" 100 122 } .to 'result' 101 123 on("previous"){}.to 'biomarkers' 102 124 } 103 104 105 125 106 126 result { 107 127 render( view:'_result') 108 128 129 onRender { 130 flow.page=6 131 } 132 on("previous"){}.to 'group' 109 133 } 110 111 112 113 114 115 116 117 118 119 120 121 122 134 123 135 } -
trunk/grails-app/taglib/dbnp/query/QueryTagLib.groovy
r315 r316 13 13 * 14 14 * 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) $ 18 18 */ 19 20 class QueryTagLib extends JavascriptTagLib { 19 class 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 } 21 184 22 185 /** … … 25 188 * @param Closure body (help text) 26 189 */ 27 28 190 def pageContent = {attrs, body -> 29 191 // define AJAX provider … … 31 193 32 194 // render new body content 33 34 195 out << render(template: "/query/common/tabs") 35 196 out << '<div class="content">' … … 38 199 out << render(template: "/query/common/navigation") 39 200 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 } 43 732 } -
trunk/grails-app/views/query/common/_error.gsp
r315 r316 15 15 */ 16 16 %> 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']} → ${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> 17 36 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 16 16 %> 17 17 <div id="wizard" class="wizard"> 18 <h1> Create a new study</h1>18 <h1>Query</h1> 19 19 <g:form action="pages" name="wizardForm" id="wizardForm"> 20 20 <g:hiddenField name="do" value="" /> -
trunk/grails-app/views/query/mainPage.gsp
r314 r316 1 1 2 <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> 31 25 </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 1 1 <wizard:pageContent> 2 hello world2 Study 3 3 </wizard:pageContent> -
trunk/grails-app/views/study/list_extended.gsp
r299 r316 44 44 45 45 <% if (selectedStudies.size()>0) {%> 46 47 46 48 47 <div id="tabs"> … … 225 224 226 225 <% 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()) %> 243 228 244 229 <g:each in="${protocol_list}" var="protocol"> … … 292 277 <td>${e.getPrettyDuration()}</td> 293 278 <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> 300 281 </g:each> 301 282 -
trunk/grails-app/views/study/show.gsp
r299 r316 371 371 </div> 372 372 </div> 373 </div>374 373 </body> 375 374 </html>
Note: See TracChangeset
for help on using the changeset viewer.