select
用途
创建一个HTML的 selects 标签.
示例
// create a select from a range
<g:select name="user.age" from="${18..65}" value="${age}"
noSelection="['':'-Choose your age-']"/>// use a no selection with a nullable Object property (use 'null' as key)
<g:select id="type" name='type.id' value="${person?.type?.id}"
noSelection="${['null':'Select One...']}"
from='${PersonType.list()}'
optionKey="id" optionValue="name"></g:select>// create select from a list of companies
// note the 'optionKey' is set to the id of each company element
<g:select name="user.company.id"
from="${Company.list()}"
value="${user?.company.id}"
optionKey="id" />// create select with internationalized labels (this is useful for small static lists and the inList constraint)
// expected properties in messages.properties:
// book.category.M=Mystery
// book.category.T=Thriller
// book.category.F=Fantasy
<g:select name="book.category" from="${['M', 'T', 'F']}" valueMessagePrefix="book.category" />
仅仅作为一个方法在GSP中调用:
${select(from:aList,value:aValue)}
描述
属性
from
(必需) - select 的范围
value
(可选) - 并在from范围的内,当前的选择值.
optionKey
(可选) -每一个<option>元素的默认属性都是一个 "toString()" .在list里设置这个,允许值作为一个bean属性.
optionValue
(可选) - 每一个<option>元素的默认body,是from属性里的元素"toString()" . 允许值作为一个bean属性.
keys
(可选) - valuet值的list,被用于获取每个<option>元素的值属性.
noSelection
(可选) - 单例 map 处理 key 和 value 的对应,用于在选择框中没有这个选择项. 如果当前没有选择项,作为第一个list将被显示, 并且如果带这个选择提交,你提供的key将被提交. 通常这个是一个空.你也可以用"null"传递对象的ID.
valueMessagePrefix
(可选) - 默认"option"元素的每个值是from属性list中每个元素的 "toString()" .设置这个属性,可以在I18n 中解决. ('.')valueMessagePrefixwill 将被作为后缀.option的属性值解决消息. 如果消息不被指定,值勤将被提供.
值得一提的是 <g:select>
的 optionKey
和 optionValue
属性,在<select>标签的结果中,允许控制向用户显示的内容,则值是form表单提交的.默认的行为是调用from属性里每个元素的toString()
, 但如如果在Book
domain 类是有个list,这个行为的用处不是很大.
下面一个例子 <g:select>
用optionKey
属性解决每个Book
的id属性,作为每个
<option>
标签value属性的值.用<g:select>的optionValue
属性显示每个Book
的 title
属性给用户:
<g:select optionKey="id" optionValue="title" name="book.title" from="${bookList}" />
如果你需要更多的控制,可以在optionValue
属性中用闭包做个转换,再把每个<option>
元素给用户. 下面一个例子, 把Book
的title属性值转换为大写:
<g:select optionKey="id" optionValue="${{it.title?.toUpperCase()}}" name="book.title" from="${bookList}" />
来源
Show Source
def select = {attrs ->
def messageSource = grailsAttributes.getApplicationContext().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 (optionValue) {
if (optionValue instanceof Closure) {
writer << optionValue(el).toString().encodeAsHTML()
}
else {
writer << el[optionValue].toString().encodeAsHTML()
}
}
else if (valueMessagePrefix) {
def message = messageSource.getMessage("${valueMessagePrefix}.${keyValue}", null, null, locale)
if (message != null) {
writer << message.encodeAsHTML()
}
else if (keyValue) {
writer << keyValue.encodeAsHTML()
}
else {
def s = el.toString()
if (s) writer << s.encodeAsHTML()
}
}
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" '
}
}