Full featured Option/Select in SHtml
(That follows a thread in the mailing list http://groups.google.com/group/liftweb/browse_frm/thread/992a7c1d326d3094/2047dbc3cf4637d0?tvc=1&q=optgroup#2047dbc3cf4637d0 )
A far as can I see, SHtml doesn't allow to create some things for select/option tags. We can't add attribute to option tags, nor group option thanks to optgroup.
I would like to purpose this starting point as a "full featured" select/option API. I think it covers almost every thing "select" related, but I don't know Lift internal to know if it's somewhat realistic.
8<-----------
A far as can I see, SHtml doesn't allow to create some things for select/option tags. We can't add attribute to option tags, nor group option thanks to optgroup.
I would like to purpose this starting point as a "full featured" select/option API. I think it covers almost every thing "select" related, but I don't know Lift internal to know if it's somewhat realistic.
8<-----------
case class OptionModel[T](value:T, label:String, disabled:Boolean, attrs:(String,String)*)
case class OptionGroupModel[T](label:String, options:Seq[OptionModel[T]], disabled:Boolean, attrs:(String,String)*) {
def values = options map( _.value )
}
case class SelectOptions[T](options:Seq[OptionModel[T]],groups:Seq[OptionGroupModel[T]]) {
def values = (options map( _.value)) ++ (groups map( _.values))
}
object SHtml {
// ....
private def selected(in: Boolean) = if (in) new UnprefixedAttribute("selected", "selected", Null) else Null
// ....
private def disabled(in: Boolean) = if (in) new UnprefixedAttribute("disabled", "true", Null) else Null
def select_*(opts: SelectOptions[String], deflt: Box[String], func: AFuncHolder, attrs: (String, String)*): Elem = {
//build an <option> from an option model
def buildOption(option:OptionModel[String]) = {
option.attrs.foldLeft(
<option value={option.value}>{option.label}</option> % disabled(option.disabled) % selected(deflt.exists(_ == option.value))
)(_ % _)
}
val testFunc = LFuncHolder(in => in.filter(v => opts.values.contains(v)) match {case Nil => false case xs => func(xs)}, func.owner)
attrs.foldLeft(fmapFunc(testFunc)(fn => <select name={fn}>{
//start with groups
opts.groups.flatMap { group =>
group.attrs.foldLeft(<optgroup label={group.label}>{
//each option in a groups, with its attributes
group.options.flatMap { buildOption(_) }
}</optgroup> % disabled(group.disabled) )(_ % _)
} ++
//now, option that are not in a group
opts.options.flatMap { buildOption(_) }
}</select>))(_ % _)
}
}
Leave a comment
on 2010-02-06 19:52 *
By github.importer
Imported from GitHub: http://github.com/dpp/liftweb/issues/312/find