Dynamic bind in Lift framework
I am newbie to Lift and I have a question on using bind, Ajax in Lift.
I want to create three dropdown menus using Ajax in a dynamic fashion. I use "Address" as an example to describe what I am trying to achieve. At fist, I only have to display "Country" menu with default set to "None". The user at this point can choose to submit if she wishes to and the address is taken as default. If not, she can provide the precise address. Once she se开发者_如何学编程lects the country, the "State" menu should get displayed, and once she selects "State", the "County" menu should be displayed.
With the help of lift demo examples, I tried to create static menus as follow. I created three snippets <select:country/>, <select:state/>, <select:county/>
in my .html file and in the scala code, I bind as follows:
bind("select", xhtml,
"system" -> select(Address.countries.map(s => (s,s)),
Full(country), s => country = s, "onchange" -> ajaxCall(JE.JsRaw("this.value"),s => After(200, replaceCounty(s))).toJsCmd),
"state" -> stateChoice(country) % ("id" -> "state_select"),
"county" -> countyChoice(state) % ("id" -> "county_select"),
"submit" -> submit(?("Go!"),()=>Log.info("Country: "+country+" State: "+state + " County: "+ county)
The corresponding replaceCounty, stateChoice, countyChoice are all defined in my class. However, when the country is selected, only the state is refreshed through Ajax call and not the county.
Q1) Is there a way to refresh both the menus based on the country menu?
Q2) How to create the menu's dynamically as I explained earlier?
There is an excellent example code that does just this available at:
http://demo.liftweb.net/ajax-form
If you want to update multiple dropdowns as a result of an AJAX update, you'll want to return something like:
ReplaceOptions(...) & ReplaceOptions(...)
Use SHtml.ajaxSelect
for your first select, and static elements for the other two. When the first select changes, you'll return javascript to populate the next select with the result of another SHtml.ajaxSelect call.
def countrySelect : NodeSeq = {
val countryOptions = List(("",""),("AR","AR"))
SHtml.ajaxSelect(countryOptions, Empty, { selectedCountry =>
val stateOptions = buildStateOptions(selectedCountry)
SetHtml("state-select", SHtml.ajaxSelect(stateOptions, Empty, { selectedState =>
// setup the county options here.
}))
})
}
bind(namespace, in,
"country" -> countrySelect,
"state" -> <select id="state-select"/>,
"county" -> <select id="county-select"/>)
In the callbacks for #ajaxSelect you'll probably want to save the values of whatever has been selected, but this is the general approach I'd take.
精彩评论