Last updated by cazacugmihai
4 years ago
Select Tag
description
This is an enhanced version of <g:select> tag.h4 how to use Like the <g:select> tag +<select:select optionKey="id" from="${UserGroup.list()}" name="userGroup.id" value="${userGroupPermission?.userGroup?.id}" optionValue="name" valueMessagePrefix="label.constant.defaultUserGroup"/>
import org.springframework.beans.SimpleTypeConverterimport org.springframework.web.servlet.support.RequestContextUtils as RCU import org.codehaus.groovy.grails.commons.DomainClassArtefactHandlerclass SelectTagLib { static namespace = 'select' def out // to facilitate testing /** * A helper tag for creating HTML selects * * Examples: * <g:select name="user.age" from="${18..65}" value="${age}" /> * <g:select name="user.company.id" from="${Company.list()}" value="${user?.company.id}" optionKey="id" /> */ def select = {attrs -> def messageSource = grailsAttributes.applicationContext.getBean('messageSource') def locale = RCU.getLocale(request) def writer = out attrs.id = attrs.id ? attrs.id : attrs.name def from = attrs.remove('from') def keys = attrs.remove('keys') def optionKey = attrs.remove('optionKey') def optionValue = attrs.remove('optionValue') def value = attrs.remove('value') if (value instanceof Collection && attrs.multiple == null) { attrs.multiple = 'multiple' } def valueMessagePrefix = attrs.remove('valueMessagePrefix') def noSelection = attrs.remove('noSelection') if (noSelection != null) { noSelection = noSelection.entrySet().iterator().next() } def disabled = attrs.remove('disabled') if (disabled && Boolean.valueOf(disabled)) { attrs.disabled = 'disabled' } writer << "<select name="${attrs.remove('name')}" " // process remaining attributes outputAttributes(attrs) writer << '>' writer.println() if (noSelection) { renderNoSelectionOption(noSelection.key, noSelection.value, value) writer.println() } // create options from list if (from) { from.eachWithIndex {el, i -> def keyValue = null writer << '<option ' if (keys) { keyValue = keys[i] writeValueAndCheckIfSelected(keyValue, value, writer) } else if (optionKey) { if (optionKey instanceof Closure) { keyValue = optionKey(el) } else if (el != null && optionKey == 'id' && grailsApplication.getArtefact(DomainClassArtefactHandler.TYPE, el.getClass().name)) { keyValue = el.ident() } else { keyValue = el[optionKey] } writeValueAndCheckIfSelected(keyValue, value, writer) } else { keyValue = el writeValueAndCheckIfSelected(keyValue, value, writer) } writer << '>' if (valueMessagePrefix) { def optionValueStr = optionValueToString(el, optionValue) def messageArgs = optionValue ? optionValueStr : keyValue def message = messageSource.getMessage("${valueMessagePrefix}.${messageArgs}", null, null, locale) if (message != null) { writer << message.encodeAsHTML() } else if (optionValue) { writer << optionValueStr } else if (keyValue) { writer << keyValue.encodeAsHTML() } else { def s = el.toString() if (s) writer << s.encodeAsHTML() } } else if (optionValue) { writer << optionValueToString(el, optionValue) } else { def s = el.toString() if (s) writer << s.encodeAsHTML() } writer << '</option>' writer.println() } } // close tag writer << '</select>' } def typeConverter = new SimpleTypeConverter() private writeValueAndCheckIfSelected(keyValue, value, writer) { boolean selected = false def keyClass = keyValue?.getClass() if (keyClass.isInstance(value)) { selected = (keyValue == value) } else if (value instanceof Collection) { selected = value.contains(keyValue) } else if (keyClass && value) { try { value = typeConverter.convertIfNecessary(value, keyClass) selected = (keyValue == value) } catch (Exception) { // ignore } } writer << "value="${keyValue}" " if (selected) { writer << 'selected="selected" ' } } /** * Dump out attributes in HTML compliant fashion */ void outputAttributes(attrs) { attrs.remove('tagName') // Just in case one is left attrs.each {k, v -> out << k << "="" << v.encodeAsHTML() << "" " } } def renderNoSelectionOption = {noSelectionKey, noSelectionValue, value -> // If a label for the '--Please choose--' first item is supplied, write it out out << '<option value="' << (noSelectionKey == null ? "" : noSelectionKey) << '"' if (noSelectionKey.equals(value)) { out << ' selected="selected" ' } out << '>' << noSelectionValue.encodeAsHTML() << '</option>' } private String optionValueToString(def el, def optionValue) { if (optionValue instanceof Closure) { return optionValue(el).toString().encodeAsHTML() } el[optionValue].toString().encodeAsHTML() }}