- Introduction
- Install using SBT
- Initialize Combobox Module in Lift
- Single-Value ComboBox
- Multiple-Value ComboBox (Tagging)
This is a Lift web framework module that let you create a jQuery-based select2 combox using Scala code.
Lift Combobox support both signle-value drop-down style select field, or multiple-value field like tagging system you found on most Web 2.0 application.
Here is the full ScalaDoc API about this module.
- SBT
- Scala 2.10.0 or above
- Lift 2.5-RC2 or above
Lift Combobox module is published as JAR file, you could using the following setting in your SBT build.sbt
file, it will fetch / update the JAR files you need when you build your project.
scalaVersion := "2.10.0"
resolvers += "bone" at "http://bone.twbbs.org.tw/ivy"
libraryDependencies += "net.liftmodules" %% "combobox" % "2.5-RC2-0.6"
You need initialize lift-combox module in Boot.scala
, so that it includes necessary JavaScript and CSS file to your website.
This is quite easily, just call net.liftmodules.combobox.Combobox.init
in your Boot
class.
package bootstrap.liftweb
import net.liftmodules.combobox.ComboBox
class Boot
{
def boot
{
// ......
ComboBox.init // Initial lift-combobx module
}
}
Currently Lift ComboBox module support both OO-style and functional-style to create single-value drop-down combobox.
Both of them are easy to use, you could choose the method according to your taste about how to code.
When you prefer OO style to coding, you just create a object that extends from net.liftmodules.combobox.ComboBox
class, and override the following method:
onSearching(term: String): List[ComboItem]
This method accept an arguement called term
, which is what user input into the combobox. The return value is a List[ComboItem]
, which will shows when the combobox is opened.
You could also override the following method to to provide the behavior when user selected an item / canceled the selection or added new item directly, the returned JsCmd will be executed in client's browser.
onItemSelected(selected: Option[ComboItem]): JsCmd
onItemAdded(text: String): JsCmd
The following is the working example of a combobox that shows five ice-cream flavor in a drop-down menu, while user could enter custom text to add new item to combobox.
import net.liftweb.http.js.JE.Str
import net.liftweb.http.js.JsCmd
import net.liftweb.http.js.JsCmds.Alert
import net.liftmodules.combobox.ComboItem
import net.liftmodules.combobox.ComboBox
// The options passed to select2, please consult the select2's document to
// know what options you could set.
val options = ("placeholder" -> Str("Choice the flavor your like")) :: Nil
val comboBox = new ComboBox(
default = None, // The default value of this combo box.
allowCreate = true, // Is user allowed to create item that does not exist?
jsonOptions = options // The options of select2 combobox.
) {
// This is where you build your combox suggestion
override def onSearching(term: String): List[ComboItem] = {
val flavor = List(
ComboItem("f1", "Valina"), ComboItem("f2", "Fruit"),
ComboItem("f3", "Banana"), ComboItem("f4", "Apple"),
ComboItem("f5", "Chocolate")
)
flavor.filter(_.text.contains(term))
}
// What you want to do when user selected or cancel an item.
//
// If user cancel selection by the X button in the combbox,
// selected will be None, otherwise it will be Some[ComboItem].
override def onItemSelected(selected: Option[ComboItem]): JsCmd = {
println("selected:" + selected)
// The returned JsCmd will be executed on client side.
Alert("You selected:" + selected)
}
// What you want to do if user added an item that
// does not exist when allowCreate = true.
override def onItemAdded(text: String): JsCmd = {
// save this item to database or anything you want to do
println("user added " + text)
// The returned JsCmd will be executed on client side.
Alert("Saved " + text + " to database")
}
}
After you have created ComboBox object, just binding comboBox
to where you want the combobox to display using Lift's CSS binding feature in your snippet.
"class=flavorInput" #> comboBox.comboBox
Now you should able to see an combo box when you browse the page.
If you prefer functional style and high-order function, there is an factory method in ComboBox
object for you.
There are two groups of factory function, one for ComboBox that allowed user add new item on the fly, and the one that does not allowd.
The following is the factory method that allows user to added new item in combobox.
// Using this group of functions when you want user is allowed to added new item.
def apply(searching: (String) ⇒ List[ComboItem], itemSelected: (Option[ComboItem]) ⇒ JsCmd, itemAdded: (String) ⇒ JsCmd): ComboBox
def apply(default: Option[ComboItem], searching: (String) ⇒ List[ComboItem], itemSelected: (Option[ComboItem]) ⇒ JsCmd, itemAdded: (String) ⇒ JsCmd): ComboBox
def apply(default: Option[ComboItem], searching: (String) ⇒ List[ComboItem], itemSelected: (Option[ComboItem]) ⇒ JsCmd, itemAdded: (String) ⇒ JsCmd, jsonOptions: List[(String, JsExp)]): ComboBox
The following is the factor method that generate read-only combobox.
// Using this group of functions when you want user is not allowed to added new item.
def apply(searching: (String) ⇒ List[ComboItem], itemSelected: (Option[ComboItem]) ⇒ JsCmd): ComboBox
def apply(default: Option[ComboItem], searching: (String) ⇒ List[ComboItem], itemSelected: (Option[ComboItem]) ⇒ JsCmd): ComboBox
def apply(default: Option[ComboItem], searching: (String) ⇒ List[ComboItem], itemSelected: (Option[ComboItem]) ⇒ JsCmd, jsonOptions: List[(String, JsExp)]): ComboBox
The usage is pretty much the same with using OO-style.
import net.liftweb.http.js.JE.Str
import net.liftweb.http.js.JsCmd
import net.liftweb.http.js.JsCmds.Alert
import net.liftmodules.combobox.ComboItem
import net.liftmodules.combobox.ComboBox
val options = ("placeholder" -> Str("Choice the flavor your like")) :: Nil
// This is where you build your combox suggestion
def onSearching(term: String): List[ComboItem] = {
val flavor = List(
ComboItem("f1", "Valina"), ComboItem("f2", "Fruit"),
ComboItem("f3", "Banana"), ComboItem("f4", "Apple"),
ComboItem("f5", "Chocolate")
)
flavor.filter(_.text.contains(term))
}
// What you want to do when user selected or cancel an item.
//
// If user cancel selection by the X button in the combbox,
// selected will be None, otherwise it will be Some[ComboItem].
def onItemSelected(selected: Option[ComboItem]): JsCmd = {
println("selected:" + selected)
// The returned JsCmd will be executed on client side.
Alert("You selected:" + selected)
}
// What you want to do if user added an item that
// does not exist when allowCreate = true.
def onItemAdded(text: String): JsCmd = {
// save this item to database or anything you want to do
println("user added " + text)
// The returned JsCmd will be executed on client side.
Alert("Saved " + text + " to database")
}
val comboBox = ComboBox(None, onSearching _, onItemSelected _, onItemAdded _, options)
And binding comboBox.comboBox
to template in your snippet.
"class=flavorInput" #> comboBox.comboBox
Lift combobox module also support for multiple-value combobox, which is tagging system you will find in most Web 2.0 website.
There are also OO-style version and functional-style version to create mutlitple-value combobox.
To create multiple-value combobox, you also create a object extened from ComboBox
, but will the following extra steps:
- Add
"multiple" -> JsTrue
tojsonOptions
in constructor. - Override the
def onMultiItemSelected(items: List[ComboItem]): JsCmd
method.
The following is code example that create a multiple-value combobox:
import net.liftweb.http.js.JE.Str
import net.liftweb.http.js.JE.JsTrue
import net.liftweb.http.js.JsCmd
import net.liftweb.http.js.JsCmds.Alert
import net.liftmodules.combobox.ComboItem
import net.liftmodules.combobox.ComboBox
val options = List(
"placeholder" -> Str("Choice the flavor your like"),
"multiple" -> JsTrue // We want to create multiple-value combobox.
)
val comboBox = new ComboBox(
default = None, // The default value of this combo box.
jsonOptions = options // The options of select2 combobox.
) {
// This is where you build your combox suggestion
override def onSearching(term: String): List[ComboItem] = {
val flavor = List(
ComboItem("f1", "Valina"), ComboItem("f2", "Fruit"),
ComboItem("f3", "Banana"), ComboItem("f4", "Apple"),
ComboItem("f5", "Chocolate")
)
flavor.filter(_.text.contains(term))
}
override def onMultiItemSelected(items: List[ComboItem]): JsCmd = {
// Do the server-side work.
println("selected:" + items)
Alert("selected:" + items)
}
}
If you want create multiple-value combobox with functional-style, you could use the following factory method in ComboBox
:
def apply(
searching: (String) ⇒ List[ComboItem],
itemsSelected: (List[ComboItem]) ⇒ JsCmd,
allowCreate: Boolean,
jsonOptions: List[(String, JsExp)]
): ComboBox
The following is a working example equivalent to the OO-style code:
import net.liftweb.http.js.JE.Str
import net.liftweb.http.js.JE.JsTrue
import net.liftweb.http.js.JsCmd
import net.liftweb.http.js.JsCmds.Alert
import net.liftmodules.combobox.ComboItem
import net.liftmodules.combobox.ComboBox
val options = List(
"placeholder" -> Str("Choice the flavor your like"),
"multiple" -> JsTrue
)
// This is where you build your combox suggestion
def onSearching(term: String): List[ComboItem] = {
val flavor = List(
ComboItem("f1", "Valina"), ComboItem("f2", "Fruit"),
ComboItem("f3", "Banana"), ComboItem("f4", "Apple"),
ComboItem("f5", "Chocolate")
)
flavor.filter(_.text.contains(term))
}
// What you want to do when user selected or cancel an item.
//
// If user cancel selection by the X button in the combbox,
// selected will be None, otherwise it will be Some[ComboItem].
def onItemsSelected(itmes: List[ComboItem]): JsCmd = {
println("selected:" + items)
Alert("You selected:" + items)
}
val comboBox = ComboBox(onSearching _, onItemsSelected _, options)