GWT实现可搜索的combobox(自动提示下拉框)

这里说的“可搜索的ComboBox”,是在基本的combobox基础上,增加搜索的功能,随着用户输入内容的变化,过滤下拉选框中的内容。

首先需要明确的问题是:下拉选框中的内容是固定的,还是会发生变化?换句话说,选项是本地固定写好的,还是要从服务端(数据库,webservice等)读取的?

情况一:选项是本地写好的。固定的选项。这是相对简单的一种情况。这种情况下有两种实现方式:

实现A:使用SuggestBox。

   MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();  
   oracle.add("Cat");
   oracle.add("Dog");
   oracle.add("Horse");
   oracle.add("Canary");
   
   SuggestBox box = new SuggestBox(oracle);

效果是这样的:



SuggestBox的API见这里


实现B:在store上加storeFilter

步骤:1-创建StoreFilterField的实例,重写doSelect方法

2-将StoreFilterField变量bind到store上

        StoreFilterField<ModelData> filterField = new StoreFilterField<ModelData>() {

            @Override
            protected boolean doSelect(Store<ModelData> store, ModelData parent, ModelData record, String property, String filter) {
                String name = record.get("key").toString();
                name = name.toLowerCase();
                if (name.startsWith(filter.toLowerCase())) {
                    return true;
                }
                return false;
            }
        };

        ComboBox<ModelData> daysBox = new ComboBox<ModelData>();
        ListStore<ModelData> store = new ListStore<ModelData>();
        store.add(getDateRage());
        daysBox.setStore(store);
        daysBox.setDisplayField("key");

        filterField.bind(store);

    private List<ModelData> getDateRage() {

        List<ModelData> list = new ArrayList<ModelData>();
        list = new ArrayList<ModelData>();
        ModelData bm = new BaseModelData();
        bm.set("value", "1");
        // bm.set("key", "1 day");
        bm.set("key", "1");
        list.add(bm);
        bm = new BaseModelData();
        bm.set("value", "2");
        // bm.set("key", "2 days");
        bm.set("key", "2");
        list.add(bm);
        bm = new BaseModelData();
        bm.set("value", "10");
        // bm.set("key", "10 days");
        bm.set("key", "10");
        list.add(bm);
        bm = new BaseModelData();
        bm.set("value", "30");
        // bm.set("key", "30 days");
        bm.set("key", "30");
        list.add(bm);
        bm = new BaseModelData();
        bm.set("value", "90");
        // bm.set("key", "90 days");
        bm.set("key", "90");
        list.add(bm);
        bm = new BaseModelData();
        bm.set("value", "All");
        bm.set("key", "All");
        list.add(bm);
        return list;

    }

很简单。还有一种实现方法和这个类似,具体参考文章末尾相关链接的第三条链接。


情况二:需要从服务端读取选项的。

实现:需要在服务器端做过滤。涉及到三个类:

ListStore  下拉框的备选项集合
ListLoader   数据源的loader
RpcProxy   Rpc代理对象,用于和服务器进行交互


先解释一下loader自动加载选项的原理:

1. 在下拉框中敲下3个及以上字符,触发loader的load方法。
2. loader使用proxy来加载数据。
3. proxy被执行,service方法被调用,和服务器进行交互。
4. RpcProxy返回数据加载进loader,触发loader的load event
5. store监听loader的event,从而添加新的数据。

实现的代码为:

import java.util.List;

import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.BasePagingLoadConfig;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.form.ComboBox;


public abstract class QueryableComboBox<T> extends ComboBox<ModelData> {

    private static final int MIN_INPUT_CHAR = 3;//输入3个或3个以上字符触发loader的load方法

    protected RpcProxy<List<T>> proxy;


    public QueryableComboBox() {
        super();
        init();
    }

    protected void init() {
        initLoader();
        ListStore<ModelData> store = new ListStore<ModelData>(initLoader());
        setStore(store);
        setMinChars(MIN_INPUT_CHAR);
        setTypeAhead(true);//
        setTriggerAction(TriggerAction.ALL);
        setAllowBlank(false);
        setForceSelection(true);
        setEditable(true);
        setUseQueryCache(false);
    }

    protected ListLoader<ListLoadResult<ModelData>> initLoader() {
        proxy = initProxy();
        ListLoader<ListLoadResult<ModelData>> loader = new BaseListLoader<ListLoadResult<ModelData>>(proxy, new BeanModelReader()) {

            @Override
            protected Object newLoadConfig() {
                return new BasePagingLoadConfig();
            }
        };
        return loader;
    }

    public void setValueRapidly(ModelData md) {
        getStore().removeAll();
        getStore().add(md);
        setValue(md);
        lastQuery = (String) md.get(getDisplayField());
    }

    public abstract RpcProxy<List<T>> initProxy();
}

使用的时候实现一下initProxy方法就可以了。


总结:gwt中实现各种形式的filter功能时,都要先考虑一下,是本地的filter还是远程的filter?之后具体问题具体分析。呵呵。



一些相关链接:

GWT的自动提示下拉框

stackoverflow: combobox auto-complete

Change default behaivior of typeAhead in a Ext-Gwt Combobox



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值