Changeset 1461 for trunk/grails-app/taglib
- Timestamp:
- Feb 1, 2011, 2:36:57 PM (10 years ago)
- Location:
- trunk/grails-app/taglib/dbnp
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
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 }
Note: See TracChangeset
for help on using the changeset viewer.