Changeset 1461
- Timestamp:
- Feb 1, 2011, 2:36:57 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/controllers/dbnp/importer/ImporterController.groovy
r1456 r1461 2 2 3 3 import dbnp.studycapturing.* 4 4 import org.dbnp.gdt.* 5 5 import grails.converters.JSON 6 //import cr.co.arquetipos.crypto.Blowfish7 6 import org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib 8 7 import grails.plugins.springsecurity.Secured -
trunk/grails-app/taglib/dbnp/importer/ImporterTagLib.groovy
r1456 r1461 15 15 16 16 package dbnp.importer 17 17 import org.dbnp.gdt.* 18 18 import org.apache.poi.ss.usermodel.Cell 19 19 import org.apache.poi.ss.usermodel.DataFormatter -
trunk/grails-app/taglib/dbnp/studycapturing/WizardTagLib.groovy
r1460 r1461 2 2 3 3 import dbnp.authentication.SecUser 4 import cr.co.arquetipos.crypto.Blowfish5 import nl.grails.plugins.ajaxflow.AjaxflowTagLib6 4 import org.dbnp.gdt.* 7 5 … … 18 16 * $Date$ 19 17 */ 20 class WizardTagLib extends AjaxflowTagLib {18 class WizardTagLib extends GdtTagLib { 21 19 def AuthenticationService 22 20 23 // define the tag namespace (e.g.: <wizard:action ... />24 static namespace = "wizard"25 26 // define default text field width27 static defaultTextFieldSize = 25;28 29 /**30 * generate a base form element31 * @param String inputElement name32 * @param Map attributes33 * @param Closure help content34 */35 def baseElement = { inputElement, attrs, help ->36 log.info ".rendering [" + inputElement + "] with name [" + attrs.get('name') + "] and value [" + ((attrs.value) ? attrs.get('value').toString() : "-") + "]"37 38 // work variables39 def description = attrs.remove('description')40 def addExampleElement = attrs.remove('addExampleElement')41 def addExample2Element = attrs.remove('addExample2Element')42 def helpText = help().trim()43 44 // execute inputElement call45 def renderedElement = "$inputElement"(attrs)46 47 // if false, then we skip this element48 if (!renderedElement) return false49 50 // render a form element51 out << '<div class="element'+ ((attrs.get('required')) ? ' required' : '') +'"'+ ((attrs.get('elementId')) ? 'id="'+attrs.remove('elementId')+'"': '') + '>'52 out << ' <div class="description">'53 out << ((description) ? description.replaceAll(/[a-z][A-Z][a-z]/) { it[0] + ' ' + it[1..2] }.replaceAll(/\w+/) { it[0].toUpperCase() + ((it.size() > 1) ? it[1..-1] : '') } : '')54 out << ' </div>'55 out << ' <div class="input">'56 out << renderedElement57 out << ((helpText.size() > 0) ? ' <div class="helpIcon"></div>' : '')58 59 // add an disabled input box for feedback purposes60 // @see dateElement(...)61 if (addExampleElement) {62 def exampleAttrs = new LinkedHashMap()63 exampleAttrs.name = attrs.get('name') + 'Example'64 exampleAttrs.class = 'isExample'65 exampleAttrs.disabled = 'disabled'66 exampleAttrs.size = 3067 out << textField(exampleAttrs)68 }69 70 // add an disabled input box for feedback purposes71 // @see dateElement(...)72 if (addExample2Element) {73 def exampleAttrs = new LinkedHashMap()74 exampleAttrs.name = attrs.get('name') + 'Example2'75 exampleAttrs.class = 'isExample'76 exampleAttrs.disabled = 'disabled'77 exampleAttrs.size = 3078 out << textField(exampleAttrs)79 }80 81 out << ' </div>'82 83 // add help content if it is available84 if (helpText.size() > 0) {85 out << ' <div class="helpContent">'86 out << ' ' + helpText87 out << ' </div>'88 }89 90 out << '</div>'91 }92 93 /**94 * bind an ajax submit to an onChange event95 * @param attrs96 * @return attrs97 */98 private getAjaxOnChange = { attrs ->99 // work variables100 def internetExplorer = (request.getHeader("User-Agent") =~ /MSIE/)101 def ajaxOnChange = attrs.remove('ajaxOnChange')102 103 // is ajaxOnChange defined104 if ( ajaxOnChange ) {105 if (!attrs.onChange) attrs.onChange = ''106 107 // add onChange AjaxSubmit javascript108 if (internetExplorer) {109 // - somehow IE submits these onchanges twice which messes up some parts of the wizard110 // (especially the events page). In order to bypass this issue I have introduced an111 // if statement utilizing the 'before' and 'after' functionality of the submitToRemote112 // function. This check expects lastRequestTime to be in the global Javascript scope,113 // (@see pageContent) and calculates the time difference in miliseconds between two114 // onChange executions. If this is more than 100 miliseconds the request is executed,115 // otherwise it will be ignored... --> 20100527 - Jeroen Wesbeek116 attrs.onChange += ajaxSubmitJs(117 [118 before: "var execute=true;try { var currentTime=new Date().getTime();execute = ((currentTime-lastRequestTime) > 100);lastRequestTime=currentTime; } catch (e) {};if (execute) { 1",119 after: "}",120 functionName: ajaxOnChange,121 url: attrs.get('url'),122 update: attrs.get('update'),123 afterSuccess: attrs.get('afterSuccess')124 ],125 ''126 )127 } else {128 // this another W3C browser that actually behaves as expected... damn you IE, DAMN YOU!129 attrs.onChange += ajaxSubmitJs(130 [131 functionName: ajaxOnChange,132 url: attrs.get('url'),133 update: attrs.get('update'),134 afterSuccess: attrs.get('afterSuccess')135 ],136 ''137 )138 }139 }140 141 return attrs142 }143 144 /**145 * render an ajaxButtonElement146 * @param Map attrs147 * @param Closure body (help text)148 */149 def ajaxButtonElement = { attrs, body ->150 baseElement.call(151 'ajaxButton',152 attrs,153 body154 )155 }156 157 /**158 * render a textFieldElement159 * @param Map attrs160 * @param Closure body (help text)161 */162 def textFieldElement = { attrs, body ->163 // set default size, or scale to max length if it is less than the default size164 if (!attrs.get("size")) {165 if (attrs.get("maxlength")) {166 attrs.size = ((attrs.get("maxlength") as int) > defaultTextFieldSize) ? defaultTextFieldSize : attrs.get("maxlength")167 } else {168 attrs.size = defaultTextFieldSize169 }170 }171 172 // render template element173 baseElement.call(174 'textField',175 attrs,176 body177 )178 }179 180 /**181 * render a textAreaElement182 * @param Map attrs183 * @param Closure body (help text)184 */185 def textAreaElement = { attrs, body ->186 // set default size, or scale to max length if it is less than the default size187 188 // render template element189 baseElement.call(190 'textArea',191 attrs,192 body193 )194 }195 196 197 /**198 * render a select form element199 * @param Map attrs200 * @param Closure body (help text)201 */202 def selectElement = { attrs, body ->203 baseElement.call(204 'select',205 attrs,206 body207 )208 }209 210 /**211 * render a checkBox form element212 * @param Map attrs213 * @param Closure body (help text)214 */215 def checkBoxElement = { attrs, body ->216 baseElement.call(217 'checkBox',218 attrs,219 body220 )221 }222 223 /**224 * render a set of radio form elements225 * @param Map attrs226 * @param Closure body (help text)227 */228 def radioElement = { attrs, body ->229 baseElement.call(230 'radioList',231 attrs,232 body233 )234 }235 236 /**237 * render a set of radio elements238 * @param Map attrs239 * @param Closure body (help text)240 */241 def radioList = { attrs ->242 def checked = true243 244 attrs.elements.each {245 out << radio(246 name: attrs.name,247 value: it,248 checked: (attrs.value == it || (!attrs.value && checked))249 )250 out << it251 checked = false252 }253 }254 255 /**256 * render a dateElement257 * NOTE: datepicker is attached through wizard.js!258 * @param Map attrs259 * @param Closure body (help text)260 */261 def dateElement = { attrs, body ->262 // transform value?263 if (attrs.value instanceof Date) {264 // transform date instance to formatted string (dd/mm/yyyy)265 attrs.value = String.format('%td/%<tm/%<tY', attrs.value)266 }267 268 // add 'rel' field to identity the datefield using javascript269 attrs.rel = 'date'270 271 // set some textfield values272 attrs.maxlength = (attrs.maxlength) ? attrs.maxlength : 10273 attrs.addExampleElement = true274 275 // render a normal text field276 //out << textFieldElement(attrs,body)277 textFieldElement.call(278 attrs,279 body280 )281 }282 283 /**284 * render a dateElement285 * NOTE: datepicker is attached through wizard.js!286 * @param Map attrs287 * @param Closure body (help text)288 */289 def timeElement = { attrs, body ->290 // transform value?291 if (attrs.value instanceof Date) {292 // transform date instance to formatted string (dd/mm/yyyy)293 attrs.value = String.format('%td/%<tm/%<tY %<tH:%<tM', attrs.value)294 }295 296 // add 'rel' field to identity the field using javascript297 attrs.rel = 'datetime'298 299 attrs.addExampleElement = true300 attrs.addExample2Element = true301 attrs.maxlength = 16302 303 // render a normal text field304 //out << textFieldElement(attrs,body)305 textFieldElement.call(306 attrs,307 body308 )309 }310 311 /**312 * Button form element313 * @param Map attributes314 * @param Closure help content315 */316 def buttonElement = { attrs, body ->317 // render template element318 baseElement.call(319 'ajaxButton',320 attrs,321 body322 )323 }324 325 326 /**327 * Term form element328 * @param Map attributes329 * @param Closure help content330 */331 def termElement = { attrs, body ->332 // render term element333 baseElement.call(334 'termSelect',335 attrs,336 body337 )338 }339 340 /**341 * Term select element342 * @param Map attributes343 */344 // TODO: change termSelect to use Term accessions instead of preferred names, to make it possible to track back345 // terms from multiple ontologies with possibly the same preferred name346 def termSelect = { attrs ->347 def from = []348 349 // got ontologies?350 if (attrs.ontologies) {351 // are the ontologies a string?352 if (attrs.ontologies instanceof String) {353 attrs.ontologies.split(/\,/).each() { ncboId ->354 // trim the id355 ncboId.trim()356 357 // fetch all terms for this ontology358 def ontology = Ontology.findAllByNcboId(ncboId)359 360 // does this ontology exist?361 if (ontology) {362 ontology.each() {363 Term.findAllByOntology(it).each() {364 // key = ncboId:concept-id365 from[ from.size() ] = it.name366 }367 }368 }369 }370 } else if (attrs.ontologies instanceof Set) {371 // are they a set instead?372 def ontologyList = ""373 374 // iterate through set375 attrs.ontologies.each() { ontology ->376 if (ontology) {377 ontologyList += ontology.ncboId + ","378 379 Term.findAllByOntology(ontology).each() {380 from[ from.size() ] = it.name381 }382 383 // strip trailing comma384 attrs.ontologies = ontologyList[0..-2]385 }386 }387 }388 389 // sort alphabetically390 from.sort()391 392 // add a dummy field?393 if (attrs.remove('addDummy')) {394 from.add(0,'')395 }396 397 // define 'from'398 attrs.from = from399 400 // add 'rel' attribute401 attrs.rel = 'term'402 403 // got an ajaxOnChange defined?404 attrs = getAjaxOnChange.call(405 attrs406 )407 408 out << select(attrs)409 } else {410 out << "<b>ontologies missing!</b>"411 }412 }413 414 /**415 * Ontology form element416 * @param Map attributes417 * @param Closure help content418 */419 def ontologyElement = { attrs, body ->420 // @see http://www.bioontology.org/wiki/index.php/NCBO_Widgets#Term-selection_field_on_a_form421 // @see ontology-chooser.js, table-editor.js422 baseElement.call(423 'textField',424 [425 name: attrs.name,426 value: attrs.value,427 description: attrs.description,428 rel: 'ontology-' + ((attrs.ontology) ? attrs.ontology : 'all'),429 size: 25430 ],431 body432 )433 out << hiddenField(434 name: attrs.name + '-concept_id'435 )436 out << hiddenField(437 name: attrs.name + '-ontology_id'438 )439 out << hiddenField(440 name: attrs.name + '-full_id'441 )442 }443 444 21 /** 445 22 * Study form element … … 480 57 481 58 /** 482 * Template form element483 * @param Map attributes484 * @param Closure help content485 */486 def templateElement = { attrs, body ->487 // render template element488 baseElement.call(489 'templateSelect',490 attrs,491 body492 )493 }494 495 /**496 * render a template select element497 * @param Map attrs498 */499 def templateSelect = { attrs ->500 def entity = attrs.remove('entity')501 502 // add the entity class name to the element503 // do we have crypto information available?504 if (grailsApplication.config.crypto) {505 // generate a Blowfish encrypted and Base64 encoded string.506 attrs['entity'] = URLEncoder.encode(507 Blowfish.encryptBase64(508 entity.toString().replaceAll(/^class /, ''),509 grailsApplication.config.crypto.shared.secret510 )511 )512 } else {513 // base64 only; this is INSECURE! As this class514 // is instantiated elsewehere. Possibly exploitable!515 attrs['entity'] = URLEncoder.encode(entity.toString().replaceAll(/^class /, '').bytes.encodeBase64())516 }517 518 // fetch templates519 attrs.from = (entity) ? Template.findAllByEntity(entity) : Template.findAll()520 521 // got a name?522 if (!attrs.name) {523 attrs.name = 'template'524 }525 526 // add a rel element if it does not exist527 if (!attrs.rel) {528 attrs.rel = 'template'529 }530 531 // got an ajaxOnChange defined?532 attrs = getAjaxOnChange.call(533 attrs534 )535 536 // got result?537 if (attrs.from.size() > 0 || attrs.get('addDummy')) {538 // transform all values into strings539 def from = []540 attrs.from.each { from[ from.size() ] = it.toString() }541 542 // sort alphabetically543 from.sort()544 545 // add a dummy field?546 if (attrs.remove('addDummy')) {547 from.add(0,'')548 }549 550 // set attributes551 attrs.from = from552 attrs.value = (attrs.value) ? attrs.value.toString() : ''553 554 // output select element555 out << select(attrs)556 } else {557 // no, return false to make sure this element558 // is not rendered in the template559 return false560 }561 }562 563 564 /**565 * File form element566 * @param Map attributes567 * @param Closure help content568 */569 def fileFieldElement = { attrs, body ->570 // render term element571 baseElement.call(572 'fileField',573 attrs,574 body575 )576 }577 578 /**579 * file field.580 * @param attributes581 */582 def fileField = { attrs ->583 /*584 out << '<input type="file" name="' + attrs.name + '"/>'585 if( attrs.value ) {586 out << '<a href="' + resource(dir: '') + '/file/get/' + attrs.value + '" class="isExample">Now contains: ' + attrs.value + '</a>'587 }588 */589 590 out << '<div id="upload_button_' + attrs.name + '" class="upload_button">Upload</div>';591 out << '<input type="hidden" name="' + attrs.name + '" id="' + attrs.name + '" value="' + attrs.value + '">';592 out << '<div id="' + attrs.name + 'Example" class="upload_info"></div>';593 out << '<a id="' + attrs.name + 'Delete" class="upload_del" href="#" onClick="if( confirm( \'Are you sure to delete this file?\' ) ) { deleteFile( \'' + attrs.name + '\' ); } return false;"><img src="' + resource( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' ) + '"></a>';594 out << '<script type="text/javascript">';595 out << ' $(document).ready( function() { ';596 out << ' var filename = "' + attrs.value + '";';597 out << ' fileUploadField( "' + attrs.name + '" );';598 out << ' if( filename != "" ) {';599 out << ' $("#' + attrs.name + 'Delete").show();';600 out << ' $("#' + attrs.name + 'Example").html("Current file: " + createFileHTML( filename ) )';601 out << ' }';602 out << ' } );';603 out << "</script>\n";604 }605 606 /**607 59 * Protocol form element 608 60 * @param Map attributes 609 61 * @param Closure help content 610 * /62 * 611 63 def protocolElement = { attrs, body -> 612 64 // render protocol element … … 621 73 * render a protocol select element 622 74 * @param Map attrs 623 * /75 * 624 76 def protocolSelect = { attrs -> 625 77 // fetch all protocold … … 645 97 out << "!! test version of 'show' tag !!" 646 98 } 647 648 /** 649 * render table headers for all subjectFields in a template 650 * @param Map attributes 651 */ 652 def templateColumnHeaders = { attrs -> 653 def entity = (attrs.get('entity')) 654 def template = (entity && entity instanceof TemplateEntity) ? entity.template : null 655 def columnWidths= (attrs.get('columnWidths')) ? attrs.remove('columnWidths') : [] 656 657 // got a template? 658 if (template) { 659 // render template fields 660 entity.giveFields().each() { 661 // Format the column name by: 662 // - separating combined names (SampleName --> Sample Name) 663 // - capitalizing every seperate word 664 def ucName = it.name.replaceAll(/[a-z][A-Z][a-z]/) { 665 it[0] + ' ' + it[1..2] 666 }.replaceAll(/\w+/) { 667 it[0].toUpperCase() + ((it.size() > 1) ? it[1..-1] : '') 668 } 669 670 // strip spaces 671 def ucNameSpaceless = ucName.replaceAll(/ /) { '' } 672 673 // do we have to use a specific width for this column? 674 if (columnWidths[ucName]) { 675 out << '<div class="' + attrs.get('class') + '" style="width:' + columnWidths[ucNameSpaceless] + 'px;" rel="resized">' + ucName + (it.unit ? " (${it.unit})" : '') 676 } else { 677 out << '<div class="' + attrs.get('class') + '">' + ucName + (it.unit ? " (${it.unit})" : '') 678 } 679 if (it.comment) { 680 out << '<div class="helpIcon"></div>' 681 out << '<div class="helpContent">' + it.comment + '</div>' 682 } 683 out << '</div>' 684 } 685 } 686 } 687 688 def templateColumns = { attrs -> 689 // render template fields as columns 690 attrs.renderType = 'column' 691 out << renderTemplateFields(attrs) 692 } 693 694 def templateElements = { attrs -> 695 // render template fields as form elements 696 attrs.renderType = 'element' 697 out << renderTemplateFields(attrs) 698 } 699 700 /** 701 * render form elements based on an entity's template 702 * @param Map attributes 703 * @param String body 704 */ 705 def renderTemplateFields = { attrs -> 706 def renderType = attrs.remove('renderType') 707 def entity = (attrs.get('entity')) 708 def prependName = (attrs.get('name')) ? attrs.remove('name')+'_' : '' 709 def template = (entity && entity instanceof TemplateEntity) ? entity.template : null 710 def inputElement= null 711 def addDummy = (attrs.get('addDummy')) ? true : false 712 713 // got a template? 714 if (template) { 715 // render template fields 716 entity.giveFields().each() { 717 def fieldValue = entity.getFieldValue(it.name) 718 def helpText = (it.comment && renderType == 'element') ? it.comment : '' 719 def ucName = it.name[0].toUpperCase() + it.name.substring(1) 720 721 // output column opening element? 722 if (renderType == 'column') { 723 out << '<div class="' + attrs.get('class') + '">' 724 } 725 726 switch (it.type.toString()) { 727 case ['STRING', 'DOUBLE', 'LONG']: 728 inputElement = (renderType == 'element') ? 'textFieldElement' : 'textField' 729 out << "$inputElement"( 730 description : ucName, 731 name : prependName + it.escapedName(), 732 value : fieldValue, 733 required : it.isRequired() 734 ){helpText} 735 break 736 case 'TEXT': 737 inputElement = (renderType == 'element') ? 'textAreaElement' : 'textField' 738 out << "$inputElement"( 739 description : ucName, 740 name : prependName + it.escapedName(), 741 value : fieldValue, 742 required : it.isRequired() 743 ){helpText} 744 break 745 case 'STRINGLIST': 746 inputElement = (renderType == 'element') ? 'selectElement' : 'select' 747 if (!it.listEntries.isEmpty()) { 748 out << "$inputElement"( 749 description : ucName, 750 name : prependName + it.escapedName(), 751 from : it.listEntries, 752 value : fieldValue, 753 required : it.isRequired() 754 ){helpText} 755 } else { 756 out << '<span class="warning">no values!!</span>' 757 } 758 break 759 case 'ONTOLOGYTERM': 760 // @see http://www.bioontology.org/wiki/index.php/NCBO_Widgets#Term-selection_field_on_a_form 761 // @see ontology-chooser.js 762 inputElement = (renderType == 'element') ? 'termElement' : 'termSelect' 763 764 // override addDummy to always add the dummy... 765 addDummy = true 766 767 if (it.ontologies) { 768 out << "$inputElement"( 769 description : ucName, 770 name : prependName + it.escapedName(), 771 value : fieldValue.toString(), 772 ontologies : it.ontologies, 773 addDummy : addDummy, 774 required : it.isRequired() 775 ){helpText} 776 } else { 777 out << "$inputElement"( 778 description : ucName, 779 name : prependName + it.escapedName(), 780 value : fieldValue.toString(), 781 addDummy : addDummy, 782 required : it.isRequired() 783 ){helpText} 784 } 785 break 786 case 'ONTOLOGYTERM-old': 787 // @see http://www.bioontology.org/wiki/index.php/NCBO_Widgets#Term-selection_field_on_a_form 788 // @see ontology-chooser.js 789 inputElement = (renderType == 'element') ? 'textFieldElement' : 'textField' 790 out << "$inputElement"( 791 name : prependName + it.escapedName(), 792 value : fieldValue, 793 rel : 'ontology-all', 794 size : 100, 795 required: it.isRequired() 796 ) 797 out << hiddenField( 798 name: prependName + it.name + '-concept_id', 799 value: fieldValue 800 ) 801 out << hiddenField( 802 name: prependName + it.escapedName() + '-ontology_id', 803 value: fieldValue 804 ) 805 out << hiddenField( 806 name: prependName + it.escapedName() + '-full_id', 807 value: fieldValue 808 ) 809 break 810 case 'DATE': 811 inputElement = (renderType == 'element') ? 'dateElement' : 'textField' 812 813 // transform value? 814 if (fieldValue instanceof Date) { 815 if (fieldValue.getHours() == 0 && fieldValue.getMinutes() == 0) { 816 // transform date instance to formatted string (dd/mm/yyyy) 817 fieldValue = String.format('%td/%<tm/%<tY', fieldValue) 818 } else { 819 // transform to date + time 820 fieldValue = String.format('%td/%<tm/%<tY %<tH:%<tM', fieldValue) 821 } 822 } 823 824 // render element 825 out << "$inputElement"( 826 description : ucName, 827 name : prependName + it.escapedName(), 828 value : fieldValue, 829 rel : 'date', 830 required : it.isRequired() 831 ){helpText} 832 break 833 case ['RELTIME']: 834 inputElement = (renderType == 'element') ? 'textFieldElement' : 'textField' 835 out << "$inputElement"( 836 description : ucName, 837 name : prependName + it.escapedName(), 838 value : new RelTime( fieldValue ).toString(), 839 addExampleElement : true, 840 onBlur : 'showExampleReltime(this)', 841 required : it.isRequired() 842 ){helpText} 843 break 844 case ['FILE']: 845 inputElement = (renderType == 'element') ? 'fileFieldElement' : 'fileField' 846 out << "$inputElement"( 847 description : ucName, 848 name : prependName + it.escapedName(), 849 value : fieldValue ? fieldValue : "", 850 addExampleElement : true, 851 required : it.isRequired() 852 ){helpText} 853 break 854 case ['BOOLEAN']: 855 inputElement = (renderType == 'element') ? 'checkBoxElement' : 'checkBox' 856 out << "$inputElement"( 857 description : ucName, 858 name : prependName + it.escapedName(), 859 value : fieldValue, 860 required : it.isRequired() 861 ){helpText} 862 break 863 case ['TEMPLATE']: 864 inputElement = (renderType == 'element') ? 'templateElement' : 'templateSelect' 865 out << "$inputElement"( 866 description : ucName, 867 name : prependName + it.escapedName(), 868 addDummy : true, 869 entity : it.entity, 870 value : fieldValue, 871 required : it.isRequired() 872 ){helpText} 873 break 874 case ['MODULE']: 875 def from = [] 876 AssayModule.findAll().each { from[from.size()] = it.toString() } 877 878 inputElement = (renderType == 'element') ? 'selectElement' : 'select' 879 out << "$inputElement"( 880 description : ucName, 881 name : prependName + it.escapedName(), 882 from : from, 883 value : fieldValue.toString(), 884 required : it.isRequired() 885 ){helpText} 886 break 887 break 888 default: 889 // unsupported field type 890 out << '<span class="warning">!' + it.type + '</span>' 891 break 892 } 893 894 // output column closing element? 895 if (renderType == 'column') { 896 out << '</div>' 897 } 898 } 899 } 900 } 99 */ 901 100 902 101 def PublicationSelectElement = { attrs, body -> … … 1235 434 } 1236 435 1237 def showTemplateField = { attrs, body ->1238 def field = attrs.get( 'field' );1239 def entity = attrs.get( 'entity' );1240 def fieldName = '';1241 def fieldType = '';1242 def fieldUnit = '';1243 1244 if( entity ) {1245 if( field instanceof String ) {1246 fieldName = field;1247 fieldType = '';1248 fieldUnit = '';1249 } else if( field instanceof TemplateField ) {1250 fieldName = field.name1251 fieldType = field.type.toString();1252 fieldUnit = field.unit1253 } else {1254 return;1255 }1256 1257 def value = entity.getFieldValue( fieldName );1258 1259 // Show a link if the field is a FILE field1260 if( fieldType == 'FILE' && value != "" ) {1261 out << '<a href="' + g.createLink( controller: "file", action: "get", id: value ) + '">' + value + '</a>';1262 } else if ( fieldType == 'RELTIME' ) {1263 out << new RelTime( value ).toString()1264 } else {1265 out << value;1266 }1267 1268 // Show the unit (if a unit is present and a value was shown)1269 if( fieldUnit && value != null && value != "" )1270 out << " " + fieldUnit1271 1272 }1273 }1274 1275 436 } -
trunk/grails-app/views/importer/common/_missingproperties.gsp
r1430 r1461 55 55 <div class="firstColumn">#</div> 56 56 <div class="firstColumn"></div> 57 < wizard:templateColumnHeaders entity="${entity}" class="column" />57 <af:templateColumnHeaders entity="${entity}" class="column" /> 58 58 </div> 59 59 <input type="hidden" name="entity" value="${entity.getClass().getName()}"> … … 62 62 <div class="firstColumn">#</div> 63 63 <div class="firstColumn"></div> 64 < wizard:templateColumns id="${entity.hashCode()}" entity="${entity}" template="${entity.template}" name="entity_${entity.getIdentifier()}" class="column" subject="${entity.hashCode()}" addDummy="true" />64 <af:templateColumns id="${entity.hashCode()}" entity="${entity}" template="${entity.template}" name="entity_${entity.getIdentifier()}" class="column" subject="${entity.hashCode()}" addDummy="true" /> 65 65 </div> 66 66 </g:each> -
trunk/grails-app/views/importer/pages/_page_one.gsp
r1456 r1461 23 23 </td> 24 24 <td width="100px"> 25 < wizard:fileFieldElement name="importfile" value=""/>25 <af:fileFieldElement name="importfile" value=""/> 26 26 </td> 27 27 </tr> -
trunk/grails-app/views/query/common/_navigation.gsp
r1430 r1461 15 15 %> 16 16 <div class="navigation"> 17 <g:if test="${page>1 && page<pages.size}">< wizard:ajaxButton name="previous" value="« prev" url="[controller:'query',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()" class="prevnext" /></g:if>17 <g:if test="${page>1 && page<pages.size}"><af:ajaxButton name="previous" value="« prev" url="[controller:'query',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()" class="prevnext" /></g:if> 18 18 <g:if test="${page>1 && page<pages.size}"> | </g:if> 19 <g:if test="${page<pages.size}">< wizard:ajaxButton name="next" value="next »" url="[controller:'query',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()" class="prevnext" /></g:if>19 <g:if test="${page<pages.size}"><af:ajaxButton name="next" value="next »" url="[controller:'query',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()" class="prevnext" /></g:if> 20 20 </div> -
trunk/grails-app/views/query/common/_query.gsp
r1430 r1461 20 20 <g:hiddenField name="do" value="" /> 21 21 <div id="wizardPage"> 22 < wizard:ajaxFlowRedirect form="form#wizardForm" name="next" url="[controller:'query',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()" />22 <af:ajaxFlowRedirect form="form#wizardForm" name="next" url="[controller:'query',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()" /> 23 23 </div> 24 24 </g:form> -
trunk/grails-app/views/query/pages/_biomarker.gsp
r1430 r1461 1 < wizard:pageContent>1 <af:pageContent> 2 2 Biomarkers 3 </wizard:pageContent> 4 3 </af:pageContent> -
trunk/grails-app/views/query/pages/_group.gsp
r1430 r1461 1 < wizard:pageContent>1 <af:pageContent> 2 2 Group 3 </ wizard:pageContent>3 </af:pageContent> 4 4 -
trunk/grails-app/views/query/pages/_inputQuery.gsp
r1430 r1461 1 < wizard:pageContent>1 <af:pageContent> 2 2 <g:form url="[action:'results',controller:'query',params: 'q']"> 3 3 <input type="hidden" name="targetUri" value="${targetUri}" /> … … 6 6 <input type="submit" name="submit" value="Query"/> 7 7 </g:form> 8 </ wizard:pageContent>8 </af:pageContent> -
trunk/grails-app/views/query/pages/_result.gsp
r1430 r1461 1 < wizard:pageContent>1 <af:pageContent> 2 2 Results 3 </ wizard:pageContent>3 </af:pageContent> 4 4 -
trunk/grails-app/views/query/pages/_sample.gsp
r1430 r1461 1 < wizard:pageContent>1 <af:pageContent> 2 2 3 3 Select samples 4 </ wizard:pageContent>4 </af:pageContent> -
trunk/grails-app/views/query/pages/_study.gsp
r1430 r1461 1 < wizard:pageContent>1 <af:pageContent> 2 2 Study 3 </ wizard:pageContent>3 </af:pageContent> -
trunk/grails-app/views/setup/common/_wizard.gsp
r1430 r1461 18 18 <g:hiddenField name="do" value="" /> 19 19 <div id="wizardPage"> 20 < wizard:ajaxFlowRedirect form="form#wizardForm" name="next" url="[controller:'setup',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()" />20 <af:ajaxFlowRedirect form="form#wizardForm" name="next" url="[controller:'setup',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()" /> 21 21 </div> 22 22 </g:form> -
trunk/grails-app/views/study/show.gsp
r1456 r1461 100 100 <td> 101 101 <g:if test="${studyInstance.fieldExists(field.name)}"> 102 < wizard:showTemplateField field="${field}" entity="${studyInstance}"/>102 <af:showTemplateField field="${field}" entity="${studyInstance}"/> 103 103 </g:if> 104 104 <g:else> -
trunk/grails-app/views/study/show_events_table.gsp
r1456 r1461 130 130 <td class="templateFieldValue"><g:if test="${event}">${new RelTime( event.startTime ).toString()}</g:if></td> 131 131 <g:each in="${showProperties[ currentEventTemplate.name ]}" var="field"> 132 <td class="templateFieldValue">< wizard:showTemplateField field="${field}" entity="${event}" /></td>132 <td class="templateFieldValue"><af:showTemplateField field="${field}" entity="${event}" /></td> 133 133 </g:each> 134 134 </g:else> -
trunk/grails-app/views/study/show_samples.gsp
r1430 r1461 84 84 <td>${sample.parentEvent?.template?.name} at ${sample.parentEvent?.getStartTimeString()}</td> 85 85 <g:each in="${sample.giveDomainFields()}" var="field"> 86 <td>< wizard:showTemplateField field="${field}" entity="${sample}" /></td>86 <td><af:showTemplateField field="${field}" entity="${sample}" /></td> 87 87 </g:each> 88 88 … … 91 91 <g:if test="${sample.fieldExists(fieldname)}"> 92 92 <g:set var="field" value="${sample.getField(fieldname)}" /> 93 < wizard:showTemplateField field="${field}" entity="${sample}" />93 <af:showTemplateField field="${field}" entity="${sample}" /> 94 94 </g:if> 95 95 <g:else> -
trunk/grails-app/views/study/show_subjects.gsp
r1430 r1461 80 80 </g:if> 81 81 <g:each in="${subject.giveDomainFields()}" var="field"> 82 <td>< wizard:showTemplateField field="${field}" entity="${subject}" /></td>82 <td><af:showTemplateField field="${field}" entity="${subject}" /></td> 83 83 </g:each> 84 84 … … 87 87 <g:if test="${subject.fieldExists(fieldname)}"> 88 88 <g:set var="field" value="${subject.getField(fieldname)}" /> 89 < wizard:showTemplateField field="${field}" entity="${subject}" />89 <af:showTemplateField field="${field}" entity="${subject}" /> 90 90 </g:if> 91 91 <g:else> -
trunk/grails-app/views/studyWizard/pages/_assays.gsp
r1430 r1461 24 24 <% /* wizard:textFieldElement name="addNumber" description="Number of assays to add" error="addNumber" value="${values?.addNumber}" size="4" maxlength="4"> 25 25 The number of assays to add to your study 26 </ wizard:textFieldElement */ %>27 < wizard:templateElement name="template" description="Template" value="${assay?.template}" entity="${dbnp.studycapturing.Assay}" addDummy="true" ajaxOnChange="switchTemplate" afterSuccess="onPage()" >26 </af:textFieldElement */ %> 27 <af:templateElement name="template" description="Template" value="${assay?.template}" entity="${dbnp.studycapturing.Assay}" addDummy="true" ajaxOnChange="switchTemplate" afterSuccess="onPage()" > 28 28 Choose the type of assay you would like to add 29 </ wizard:templateElement>29 </af:templateElement> 30 30 <g:if test="${assay}"> 31 < wizard:templateElements entity="${assay}" />32 < wizard:ajaxButtonElement name="add" value="Add" afterSuccess="onPage()">33 </ wizard:ajaxButtonElement>31 <af:templateElements entity="${assay}" /> 32 <af:ajaxButtonElement name="add" value="Add" afterSuccess="onPage()"> 33 </af:ajaxButtonElement> 34 34 </g:if> 35 35 … … 44 44 <div class="header"> 45 45 <div class="firstColumn"></div> 46 < wizard:templateColumnHeaders class="column" entity="${assay}" />46 <af:templateColumnHeaders class="column" entity="${assay}" /> 47 47 </div> 48 48 </g:if> … … 52 52 <af:ajaxButton name="deleteAssay" src="${resource(dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam')}" alt="delete this assay" class="famfamfam" value="-" before="\$(\'input[name=do]\').val(${assay.getIdentifier()});" afterSuccess="onPage()"/> 53 53 </div> 54 < wizard:templateColumns class="column" entity="${assay}" name="assay_${assay.getIdentifier()}" />54 <af:templateColumns class="column" entity="${assay}" name="assay_${assay.getIdentifier()}" /> 55 55 </div> 56 56 </g:each> -
trunk/grails-app/views/studyWizard/pages/_confirmation.gsp
r1430 r1461 43 43 </ul> 44 44 </p> 45 Not right? Click < wizard:ajaxButton name="toStudy" value="here" afterSuccess="onPage()" class="prevnext" /> to go back to the study page and make corrections.45 Not right? Click <af:ajaxButton name="toStudy" value="here" afterSuccess="onPage()" class="prevnext" /> to go back to the study page and make corrections. 46 46 </div> 47 47 <h3><a href="#">Subjects</a></h3> … … 56 56 </g:each> 57 57 58 Not right? Click < wizard:ajaxButton name="toSubjects" value="here" afterSuccess="onPage()" class="prevnext" /> to go back to the subjects page and make corrections.58 Not right? Click <af:ajaxButton name="toSubjects" value="here" afterSuccess="onPage()" class="prevnext" /> to go back to the subjects page and make corrections. 59 59 </div> 60 60 <h3><a href="#">Events</a></h3> … … 76 76 </g:each> 77 77 78 Not right? Click < wizard:ajaxButton name="toEvents" value="here" afterSuccess="onPage()" class="prevnext" /> to go back to the events page and make corrections.78 Not right? Click <af:ajaxButton name="toEvents" value="here" afterSuccess="onPage()" class="prevnext" /> to go back to the events page and make corrections. 79 79 </div> 80 80 <h3><a href="#">Samples</a></h3> … … 89 89 </g:each> 90 90 91 Not right? Click < wizard:ajaxButton name="toSamples" value="here" afterSuccess="onPage()" class="prevnext" /> to go back to the subjects page and make corrections.91 Not right? Click <af:ajaxButton name="toSamples" value="here" afterSuccess="onPage()" class="prevnext" /> to go back to the subjects page and make corrections. 92 92 </div> 93 93 <h3><a href="#">Assays</a></h3> … … 102 102 </g:each> 103 103 104 Not right? Click < wizard:ajaxButton name="toAssays" value="here" afterSuccess="onPage()" class="prevnext" /> to go back to the subjects page and make corrections.104 Not right? Click <af:ajaxButton name="toAssays" value="here" afterSuccess="onPage()" class="prevnext" /> to go back to the subjects page and make corrections. 105 105 </div> 106 106 </div> -
trunk/grails-app/views/studyWizard/pages/_events.gsp
r1430 r1461 17 17 <af:page> 18 18 <g:if env="development"> 19 < wizard:ajaxButtonElement description="Development feature (clear events)" name="clear" value="clear events" afterSuccess="onPage()">19 <af:ajaxButtonElement description="Development feature (clear events)" name="clear" value="clear events" afterSuccess="onPage()"> 20 20 This functionality is only available in development mode for debugging purposes and will not show in test and production environments 21 </ wizard:ajaxButtonElement>21 </af:ajaxButtonElement> 22 22 </g:if> 23 23 … … 27 27 </span> 28 28 29 < wizard:radioElement name="eventType" description="Type" elements="['event','sample']" value="${values?.eventType}">29 <af:radioElement name="eventType" description="Type" elements="['event','sample']" value="${values?.eventType}"> 30 30 Type of event 31 </ wizard:radioElement>32 < wizard:templateElement name="eventTemplate" elementId="eventTemplate" description="Event Template" value="${event?.template}" entity="${dbnp.studycapturing.Event}" addDummy="true" ajaxOnChange="switchTemplate" afterSuccess="onPage()" >31 </af:radioElement> 32 <af:templateElement name="eventTemplate" elementId="eventTemplate" description="Event Template" value="${event?.template}" entity="${dbnp.studycapturing.Event}" addDummy="true" ajaxOnChange="switchTemplate" afterSuccess="onPage()" > 33 33 The template to use for this event 34 </ wizard:templateElement>35 < wizard:templateElement name="sampleTemplate" elementId="sampleTemplate" description="Sampling Event Template" value="${event?.template}" entity="${dbnp.studycapturing.SamplingEvent}" addDummy="true" ajaxOnChange="switchTemplate" afterSuccess="onPage()" >34 </af:templateElement> 35 <af:templateElement name="sampleTemplate" elementId="sampleTemplate" description="Sampling Event Template" value="${event?.template}" entity="${dbnp.studycapturing.SamplingEvent}" addDummy="true" ajaxOnChange="switchTemplate" afterSuccess="onPage()" > 36 36 The template to use for this sampling event 37 </ wizard:templateElement>37 </af:templateElement> 38 38 <g:if test="${event?.template}"> 39 39 <div id="${values?.eventType}TemplateFields"> 40 <g:if test="${event?.template}">< wizard:templateElements entity="${event}" /></g:if>41 <g:if test="${event?.template}">< wizard:buttonElement name="add" value="Add" afterSuccess="onPage()"/></g:if>40 <g:if test="${event?.template}"><af:templateElements entity="${event}" /></g:if> 41 <g:if test="${event?.template}"><af:buttonElement name="add" value="Add" afterSuccess="onPage()"/></g:if> 42 42 </div> 43 43 </g:if> … … 89 89 <af:ajaxButton name="addEventGroup" src="${resource(dir: 'images/icons', file: 'add.png', plugin: 'famfamfam')}" alt="add a new eventgroup" class="famfamfam" value="+" afterSuccess="onPage()" /> 90 90 </div> 91 < wizard:templateColumnHeaders class="column" entity="${event}" />91 <af:templateColumnHeaders class="column" entity="${event}" /> 92 92 </div> 93 93 </g:if> … … 109 109 <af:ajaxButton name="duplicate" src="${resource(dir: 'images/icons', file: 'application_put.png', plugin: 'famfamfam')}" alt="duplicate this event" class="famfamfam" value="-" before="\$(\'input[name=do]\').val(${event.getIdentifier()});" afterSuccess="onPage()" /> 110 110 </div> 111 < wizard:templateColumns class="column" entity="${event}" name="event_${event.getIdentifier()}" />111 <af:templateColumns class="column" entity="${event}" name="event_${event.getIdentifier()}" /> 112 112 </div> 113 113 -
trunk/grails-app/views/studyWizard/pages/_modify.gsp
r1430 r1461 21 21 </span> 22 22 23 < wizard:studyElement name="study" description="Study" error="study" value="">23 <af:studyElement name="study" description="Study" error="study" value=""> 24 24 The study you would like to load and edit 25 </ wizard:studyElement>25 </af:studyElement> 26 26 </af:page> -
trunk/grails-app/views/studyWizard/pages/_samples.gsp
r1430 r1461 18 18 19 19 <% /* g:if env="development"> 20 < wizard:ajaxButtonElement description="Development feature (regenerate samples)" name="regenerate" value="regenerate new samples" url="[controller:'wizard',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()">20 <af:ajaxButtonElement description="Development feature (regenerate samples)" name="regenerate" value="regenerate new samples" url="[controller:'wizard',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()"> 21 21 This functionality is only available in development mode for debugging purposes and will not show in test and production environments 22 </ wizard:ajaxButtonElement>22 </af:ajaxButtonElement> 23 23 </g:if */ %> 24 24 … … 31 31 <script type="text/javascript"> 32 32 function switchTemplate( element ) { 33 < wizard:ajaxSubmitJs functionName="switchTemplate" this="element" afterSuccess="onPage()"/>33 <af:ajaxSubmitJs functionName="switchTemplate" this="element" afterSuccess="onPage()"/> 34 34 } 35 35 </script> … … 77 77 </div> 78 78 <div class="column"> 79 < wizard:templateSelect name="template_${sample.getIdentifier()}" entity="${dbnp.studycapturing.Sample}" value="${sample.template}" tableEditorChangeEvent="switchTemplate(element);" addDummy="true" />79 <af:templateSelect name="template_${sample.getIdentifier()}" entity="${dbnp.studycapturing.Sample}" value="${sample.template}" tableEditorChangeEvent="switchTemplate(element);" addDummy="true" /> 80 80 </div> 81 81 <div class="column">${sample.name}</div> 82 < wizard:templateColumns name="sample_${sample.getIdentifier()}" class="column" id="1" entity="${sample}"/>82 <af:templateColumns name="sample_${sample.getIdentifier()}" class="column" id="1" entity="${sample}"/> 83 83 </div> 84 84 </g:if> … … 103 103 <div class="column">Subject</div> 104 104 <div class="column">Template</div> 105 < wizard:templateColumnHeaders entity="${sample}" class="column" columnWidths="[Name:250]"/>105 <af:templateColumnHeaders entity="${sample}" class="column" columnWidths="[Name:250]"/> 106 106 </div> 107 107 </g:if> … … 134 134 </div> 135 135 <div class="column"> 136 < wizard:templateSelect name="template_${sample.getIdentifier()}" entity="${dbnp.studycapturing.Sample}" value="${sample.template}" addDummy="true" tableEditorChangeEvent="switchTemplate(element);" />136 <af:templateSelect name="template_${sample.getIdentifier()}" entity="${dbnp.studycapturing.Sample}" value="${sample.template}" addDummy="true" tableEditorChangeEvent="switchTemplate(element);" /> 137 137 </div> 138 < wizard:templateColumns name="sample_${sample.getIdentifier()}" class="column" id="1" entity="${sample}"/>138 <af:templateColumns name="sample_${sample.getIdentifier()}" class="column" id="1" entity="${sample}"/> 139 139 </div> 140 140 </g:each> -
trunk/grails-app/views/studyWizard/pages/_samples_previous_warning.gsp
r1430 r1461 38 38 39 39 function goToPrevious() { 40 < wizard:ajaxSubmitJs name="previous" afterSuccess="onPage()" />40 <af:ajaxSubmitJs name="previous" afterSuccess="onPage()" /> 41 41 } 42 42 </script> -
trunk/grails-app/views/studyWizard/pages/_study.gsp
r1430 r1461 23 23 </span> 24 24 25 < wizard:templateElement name="template" description="Template" value="${study?.template}" entity="${dbnp.studycapturing.Study}" addDummy="true" ajaxOnChange="switchTemplate" afterSuccess="onPage()">25 <af:templateElement name="template" description="Template" value="${study?.template}" entity="${dbnp.studycapturing.Study}" addDummy="true" ajaxOnChange="switchTemplate" afterSuccess="onPage()"> 26 26 Choose the type of study you would like to create. 27 27 Depending on the chosen template specific fields can be filled out. If none of the templates contain all the necessary fields, a new template can be defined (based on other templates). 28 </ wizard:templateElement>28 </af:templateElement> 29 29 <g:if test="${study}"> 30 < wizard:templateElements entity="${study}"/>31 < wizard:publicationSelectElement name="publication" value="${study?.publications}"/>32 < wizard:contactSelectElement name="contacts" value="${study?.persons}"/>30 <af:templateElements entity="${study}"/> 31 <af:publicationSelectElement name="publication" value="${study?.publications}"/> 32 <af:contactSelectElement name="contacts" value="${study?.persons}"/> 33 33 <br/> 34 34 <div class="element"> … … 37 37 </div> 38 38 39 < wizard:userSelectElement name="readers" description="Readers" value="${study?.readers}"/>40 < wizard:userSelectElement name="writers" description="Writers" value="${study?.writers}"/>39 <af:userSelectElement name="readers" description="Readers" value="${study?.readers}"/> 40 <af:userSelectElement name="writers" description="Writers" value="${study?.writers}"/> 41 41 </g:if> 42 42 </af:page> -
trunk/grails-app/views/studyWizard/pages/_subjects.gsp
r1430 r1461 25 25 </span> 26 26 27 < wizard:textFieldElement name="addNumber" description="Number of subjects to add" error="addNumber" value="${values?.addNumber}" size="4" maxlength="4">27 <af:textFieldElement name="addNumber" description="Number of subjects to add" error="addNumber" value="${values?.addNumber}" size="4" maxlength="4"> 28 28 The number of subjects to add to your study 29 </ wizard:textFieldElement>30 < wizard:termElement name="species" description="of species" value="${values?.species}" ontologies="1132" addDummy="true">29 </af:textFieldElement> 30 <af:termElement name="species" description="of species" value="${values?.species}" ontologies="1132" addDummy="true"> 31 31 The species of the subjects you would like to add to your study 32 </ wizard:termElement>33 < wizard:templateElement name="template" description="with template" value="${values?.template}" error="template" entity="${dbnp.studycapturing.Subject}" ontologies="1132" addDummy="true">32 </af:termElement> 33 <af:templateElement name="template" description="with template" value="${values?.template}" error="template" entity="${dbnp.studycapturing.Subject}" ontologies="1132" addDummy="true"> 34 34 The template to use for these subjects 35 </ wizard:templateElement>36 < wizard:ajaxButtonElement name="add" value="Add" afterSuccess="onPage()">37 </ wizard:ajaxButtonElement>35 </af:templateElement> 36 <af:ajaxButtonElement name="add" value="Add" afterSuccess="onPage()"> 37 </af:ajaxButtonElement> 38 38 39 39 <g:if test="${study.subjects}"> … … 47 47 <div class="header"> 48 48 <div class="firstColumn"></div> 49 < wizard:templateColumnHeaders class="column" entity="${subject}" columnWidths="[Name:200, Species: 150]" />49 <af:templateColumnHeaders class="column" entity="${subject}" columnWidths="[Name:200, Species: 150]" /> 50 50 </div> 51 51 </g:if> … … 54 54 <af:ajaxButton name="delete" src="${resource(dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam')}" alt="delete this subject" class="famfamfam" value="-" before="\$(\'input[name=do]\').val(${subject.getIdentifier()});" afterSuccess="onPage()" /> 55 55 </div> 56 < wizard:templateColumns class="column" entity="${subject}" name="subject_${subject.getIdentifier()}" />56 <af:templateColumns class="column" entity="${subject}" name="subject_${subject.getIdentifier()}" /> 57 57 </div> 58 58 </g:each>
Note: See TracChangeset
for help on using the changeset viewer.