开发者

How can I change the content of a combo box based on the content of the previous one?

开发者 https://www.devze.com 2023-04-12 19:13 出处:网络
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开发者_如何转开发hang

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 IModels to get the choices of both DropDownChoices. 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号