[286] | 1 | |
---|
| 2 | /** |
---|
| 3 | * General use custom tags. |
---|
| 4 | * Some are taken from http://www.grails.org/Contribute+a+Tag#checkBoxList |
---|
| 5 | */ |
---|
| 6 | class CustomTagLib { |
---|
| 7 | static namespace = 'custom' |
---|
| 8 | |
---|
| 9 | def resources = { attrs -> |
---|
| 10 | ///@todo: should include our javascript and do setup here. |
---|
| 11 | } |
---|
| 12 | |
---|
| 13 | /** |
---|
| 14 | * Checkbox list that can be used as a more user-friendly alternative to a multiselect list box. |
---|
| 15 | * Usage: |
---|
| 16 | * To map the selected ids to corresponding domain objects, |
---|
| 17 | * an additional set method is required in the containing domain class: |
---|
| 18 | * // This additional setter is used to convert the checkBoxList string |
---|
| 19 | * // of ids selected to the corresponding domain objects. |
---|
| 20 | * public void setAssetSubItemsFromCheckBoxList(ids) { |
---|
| 21 | * def idList = [] |
---|
| 22 | * ids.each() { |
---|
| 23 | * if(it.isInteger()) |
---|
| 24 | * idList << it.toInteger() |
---|
| 25 | * } |
---|
| 26 | * this.assetSubItems = idList.collect { AssetSubItem.get( it ) } |
---|
| 27 | * } |
---|
[303] | 28 | * |
---|
[286] | 29 | * Then a line in the controller: |
---|
| 30 | * assetInstance.setAssetSubItemsFromCheckBoxList(params.assetSubItems) |
---|
[303] | 31 | * |
---|
| 32 | * Fields: |
---|
| 33 | * name - the property name. |
---|
| 34 | * from - the list to select from. |
---|
| 35 | * value - the current value. |
---|
| 36 | * optionKey - the key to use. |
---|
| 37 | * displayFields - (optional) available options are 'id' and 'name', defaults to the objects toString(). |
---|
| 38 | * linkController - (optional, requires linkAction.) the controller to use for a link to the objects in the checkBoxList. |
---|
| 39 | * linkAction - (optional, requires linkController.) the action to use for a link to the objects in the checkBoxList. |
---|
| 40 | * |
---|
| 41 | * Example: |
---|
| 42 | * <!-- |
---|
| 43 | * <custom:checkBoxList name="assetSubItems" |
---|
| 44 | * from="${AssetSubItem.list()}" |
---|
| 45 | * value="${assetInstance?.assetSubItems.collect{it.id}}" |
---|
| 46 | * optionKey="id" |
---|
| 47 | * displayFields="['id', 'name']" |
---|
| 48 | * linkController="assetSubItemDetailed" |
---|
| 49 | * linkAction="show"/> |
---|
| 50 | * --> |
---|
| 51 | * |
---|
[286] | 52 | */ |
---|
[303] | 53 | |
---|
[286] | 54 | def checkBoxList = {attrs, body -> |
---|
| 55 | |
---|
| 56 | def from = attrs.from |
---|
| 57 | def value = attrs.value |
---|
| 58 | def cname = attrs.name |
---|
| 59 | def isChecked, ht, wd, style, html |
---|
| 60 | |
---|
[290] | 61 | def displayFields = attrs.displayFields |
---|
[303] | 62 | def linkController = attrs.linkController |
---|
| 63 | def linkAction = attrs.linkAction |
---|
[290] | 64 | |
---|
| 65 | def displayValue = " " |
---|
| 66 | |
---|
[286] | 67 | // sets the style to override height and/or width if either of them |
---|
| 68 | // is specified, else the default from the CSS is taken |
---|
| 69 | style = "style='" |
---|
| 70 | if(attrs.height) |
---|
| 71 | style += "height:${attrs.height};" |
---|
| 72 | if(attrs.width) |
---|
| 73 | style += "width:${attrs.width};" |
---|
| 74 | if(style.length() == "style='".length()) |
---|
| 75 | style = "" |
---|
| 76 | else |
---|
| 77 | style += "'" // closing single quote |
---|
| 78 | |
---|
| 79 | html = "<ul class='CheckBoxList' " + style + ">" |
---|
| 80 | |
---|
| 81 | out << html |
---|
| 82 | |
---|
| 83 | from.each { obj -> |
---|
| 84 | |
---|
[290] | 85 | displayValue = " " |
---|
| 86 | |
---|
[303] | 87 | if( displayFields?.contains("id") ) |
---|
[290] | 88 | displayValue += obj.id + " - " |
---|
| 89 | |
---|
[303] | 90 | if(linkController && linkAction) |
---|
| 91 | displayValue += "<a href=\"${createLink(controller: linkController, action: linkAction, id: obj.id).encodeAsHTML()}\">" |
---|
| 92 | |
---|
[290] | 93 | if(displayFields?.contains("name")) { |
---|
| 94 | displayValue += obj.name |
---|
| 95 | } |
---|
| 96 | else displayValue += obj |
---|
| 97 | |
---|
[303] | 98 | if(linkController && linkAction) |
---|
| 99 | displayValue += '</a>' |
---|
| 100 | |
---|
[286] | 101 | // if we wanted to select the checkbox using a click anywhere on the label (also hover effect) |
---|
| 102 | // but grails does not recognize index suffix in the name as an array: |
---|
| 103 | // cname = "${attrs.name}[${idx++}]" |
---|
| 104 | // and put this inside the li: <label for='$cname'>...</label> |
---|
| 105 | |
---|
| 106 | isChecked = (value?.contains(obj."${attrs.optionKey}"))? true: false |
---|
| 107 | |
---|
[290] | 108 | out << "<li>" << checkBox(name:cname, value:obj."${attrs.optionKey}", checked: isChecked) << displayValue << "</li>" |
---|
[286] | 109 | } |
---|
| 110 | |
---|
| 111 | out << "</ul>" |
---|
| 112 | |
---|
| 113 | } // checkBoxList |
---|
| 114 | |
---|
| 115 | } // end class |
---|