Saturday, January 8, 2011

Change default behaivior of typeAhead in a Ext-Gwt Combobox

Recently I encountered with a incident where I had to filter the list of a Ext-Gwt combo box so that the list get fetched with the options which 'contains' the typed characters. Typeahead in Ext-Gwt combo box can be enabled by setting typeahead attribute true.
combo.setTypeAhead(boolean typeAhead);
But the default behaviour of the typeahead is to fetch the combo box list with the options which 'starting' with the typed characters. I had to get my brain troubled in searching the resources on the internet over few hours. but I couldn't find the solution.

Later, Hasith Yaggahavita; the team leader found the solution by going through the Gwt combo box source. What he had done was to extend the Gwt combo box component and to override the protected method onTypeAhead() to do nothing. Then he had written a custom StoreFilter with the logic to filter options which 'contains' the typed characters.

A sample code for the above implementation would be as follows

import com.gwtext.client.widgets.form.ComboBox
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.store.StoreFilter;

public class ContainsTypeAheadComboBox extends ComboBox {

    public ContainsTypeAheadComboBoxComponent() {
        setMinChars(1);
        setQueryDelay(300);
        setTriggerAction(TriggerAction.ALL);
    }

    public void setRpcProxy(RpcProxy> proxy) {
        ListLoader> loader = new BaseListLoader>(proxy);
        ListStore listStore = new ListStoreExt(loader);
        listStore.addFilter(new ContainsStoreFilter());
        setStore(listStore);
    }

    @Override
    protected void onTypeAhead() {
        //this method is overriden to avoid typeahead
        //feature selecting the first data item in to combo box text field
    }

    /**
     * The Class extending ListStore to ignore the 'beginsWith' behavior
     */
    class ListStoreExt extends ListStore {     

        public ListStoreExt(ListLoader> loader) {
            super(loader);
            this.filtersEnabled = true;
        }

        @Override
        public void filter(String property, String beginsWith)
        {
            // ignore the 'beginsWith' string since we filter for 'contains'
            super.filter(property);
        }
    }
  
    /**
     * The Class that filter according to 'contains' instead of 'beginswith'
     */
    class ContainsStoreFilter implements StoreFilter {

        public boolean select(Store store, ComboBox parent, ComboBox item, String property) {
            String v = getRawValue();
            if ( v == null || "".equals(v)) {
                return true;
            }
            if (item != null && item.getText() != null) {
                return item.getText().toLowerCase().indexOf(v.toLowerCase()) >= 0;
            }
            return false;
        }
    }
}

Reference Ext-Gwt combo box:
http://gwt-ext.com/docs/2.0.4/com/gwtext/client/widgets/form/ComboBox.html

1 comment:

Unknown said...

Code is corrupted. Can you wrap code with tag "pre"?