How can I change the content of a combo box based on the content of the previous one?
I have a page containing two combo boxes. I want to make them in a way that when I change the first combo box the content of the second combo box, which is got from database, is c开发者_如何转开发hanged. How can I do it?
The usual way to perform this kind of operations is through AJAX. You can easily add an AJAX Behavior to the first DropDownChoice
in order to populate/refresh the choices of the second DropDownChoice
.
Let's say you are using IModel
s to get the choices of both DropDownChoice
s. The IModel
that gets the choices for the second DropDownChoice
would be using the first DropDownChoice
's ModelObject (because it is dependent).
private DropDownChoice ddcCountry;
private DropDownChoice ddcCity;
//...
IModel countriesModel = new LoadableDetachableModel(){
@Override
protected Object load() {
return myService.getCountries();
}
};
IModel citiesModel = new LoadableDetachableModel(){
@Override
protected Object load() {
if (ddcCountry.getModelObject() != null){
return myService.getCities(ddcCountry.getModelObject());
}
else { return new ArrayList(); }
}
};
ddcCountry = new DropDownChoice("country", null, countriesModel);
ddcCity = new DropDownChoice("city", null, citiesModel);
You can attach an AjaxFormComponentUpdatingBehavior
to the first DropDownChoice
. That will output an onchange
HTML event handler on the <select>
tag, such that it will update that DropDownChoice
's model object with the selected value, and then will call your Behavior's onUpdate()
. In the onUpdate()
method, you will only have to add the second DropDownChoice
to the AjaxRequestTarget
to write it back through the ajax response with the updated options. Remember to use setOutputMarkupId(true)
on all components you'll be adding to the AjaxRequestTarget
.
For instance, for 2 dependent selects with countries and cities:
ddcCity.setOutputMarkupId(true);
ddcCountry.add(new AjaxFormComponentUpdatingBehavior(){
@Override
protected void onUpdate(AjaxRequestTarget target) {
// here, ddcCountry's ModelObject has been already updated.
ddcCity.setModelObject(null); // clear selection
if (target != null) {
// Adding the ddc to the AjaxRequestTarget will write
// it back to the ajax response with new options pulled
// from the choices model.
target.addComponent(ddcCity);
}
}
}
In case you're not using IModels
for your choices (i.e. using List
objects in the constructors), you'd just need to get the new List
in the onUpdate
method, and set it to ddcCity
with setChoices()
. You can get the Component
the Behavior is bounded to with the getComponent()
method.
protected void onUpdate(AjaxRequestTarget target) {
// here, ddcCountry's ModelObject has been already updated.
List cities = myService.getCities(getComponent().getModelObject());
ddcCity.setChoices(cities);
ddcCity.setModelObject(null); // clear selection
if (target != null) {
target.addComponent(ddcCity);
}
}
In case you want to support users without javascript, you should add a submit button (maybe in a <noscript>
tag?) with default from processing disabled, and perform that same logic in the button's onSubmit
.
For additional reference, see this DropDownChoice Examples Wicket wiki page, you might find the "Ajax" section interesting.
精彩评论