Extjs Combobox

extjs

http://skirtlesden.com/articles/extjs-comboboxes-part-1
http://skirtlesden.com/articles/extjs-comboboxes-part-3
http://dev.sencha.com/deploy/ext/docs/output/Ext.form.ComboBox.html
http://dev.sencha.com/deploy/dev/examples/form/combos.html
http://stackoverflow.com/questions/1313025/how-would-one-do-html-input-tag-autocomplete-in-ext-js
http://dev.sencha.com/deploy/dev/examples/form/forum-search.html
http://www.sencha.com/learn/Tutorial:Linked_Combos_Tutorial_for_Ext_2
https://forums.ext.net/showthread.php?60272-FIXED-932-3-2-1-Combobox-forceselection-true-state-clear-issue
https://www.sencha.com/forum/showthread.php?301954-How-to-add-event-listeners-to-components-from-controller-and-how-to-call-data-json
https://stackoverflow.com/questions/46610336/ext-js-attach-event-handler-in-parent-container-to-its-child-item

  1. How can we add an onblur event handler to all combo-box on a page?
comboselect: function (combo,record) {
    alert(combo.rawValue);
}
Ext.override(Ext.form.ComboBox, {
    forceSelection: true,
    onBlur: function() {
    }
});
Ext.override(Ext.form.ComboBox, {
    forceSelection: true,
});

Ext.override(Ext.ux.qcombobox, {
    forceSelection: true,
    comboConfig: {
        forceSelection: true,
    }
});

What is the purpose of the getRawValue method?

Returns the raw data value which may or may not be a valid, defined value. To return a normalized value see getValue. I think that we can use the getRawValue method to return the display value, if the user has selected a value from the combo box. If we have a combo box where the user is allowed to type into the combo box, the getRawValue method may return whatever value that the user had typed, which is not what we want. We may also want to use combo.rawValue, which may be the equivalent version of the getRawValue method for some version of Ext JS.

How can we determine the "display value" that is corresponding to the selected value?

Use the value to get the record out of the store, and get the display value from there. Abstractly, you can use this code, but you might substitute some of the variables for known values to make it more readable:

getComboDisplay = function(combo) {
    var value = combo.getValue();
    var valueField = combo.valueField;
    var record;
    combo.getStore().each(function(r){
        if(r.data[valueField] == value){
            record = r;
            return false;
        }
    });

    return record ? record.get(combo.displayField) : null;
}

In ExtJS 4 there is a built-in findRecord() method that does the searching that BigSean suggested above, so you don't have to write all that code:

Ext.override(Ext.form.field.ComboBox, {
    getDisplayedValue: function() {     // getDisplayValue() already exists but is a private method
        var me = this,
            value = me.value,
            record = null;
        if(value) {
            record = me.getStore().findRecord(me.valueField, value);
        }
        if(record) {
            return record.get(me.displayField);
        }
        return null;
    }
});

How can we make ExtJS send the value field instead of the display field?

Use the hiddenName config property. A ComboBox works in a similar manner to a traditional HTML <select> field. The difference is that to submit the valueField, you must specify a hiddenName to create a hidden input field to hold the value of the valueField. The displayField is shown in the text field which is named according to the name.

How can we do something when the user use the mouse to select an option from the drop-down?

The combo box has a 'select' event. I had an editor grid. When the user use the keyboard to select an option and he tab to another field (just like Excel), the 'select' event from the combo box is triggered first, and then the edit event on the grid is trigger, and everything work fine. However, when the user use a mouse to select an option from the combo box, the edit event from the grid is not triggered. I need a way to determine if the user is using the keyboard or the mouse. I've done this by:

select: function(combo, records, eOpts) {
    if (readOnlyOrEditOption == 'edit') {
        Ext.getCmp('saveAsDraftBtn').enable();
        Ext.getCmp('cancelBtn').enable();
        console_log("select event detected");

        /*
        If the user press a number to select an option and press the tab key to go to the next question, 
        everything works fine.  However, if the user use the mouse and select an option, the edit event
        isn't triggered until the user tab to the next question.  This event is triggered in either case which
        make things more complicated.  If the user uses the mouse and make a selection, we want to see the
        edit event being triggered, but first we need a way to determine if the user is using the mouse or keyboard
        and we need to test both scenarios.
        */
        var activeElement = Ext.Element.getActiveElement();
        var el = this.getEl();
        if (el.dom.id.search(/combobox/) > -1) {
            console_log("Attempting to blur");
            var liTagCount = countLI(activeElement.innerHTML);
            console_log("li count:" + liTagCount);
            if (liTagCount > 1) {
                // The user is using the mouse
                webformEditing.completeEdit();
            }
        }
        //webformEditing.completeEdit();
    }

function countLI(html) {
    var found = 0;
    while (true) {
        if (html.search(/\<li/i) == -1) {
            break;
        } else {
            found = found + 1;
            html = html.replace(/\<li.*\<\/li>/i,'');
        }
    }
    return found;
}

In the above code, I called webformEditing.completeEdit() from the grid. The combo box is also an editor. It also has it own completeEdit( [remainVisible] ) method. Perhaps, we can can use the completeEdit method from the combo box editor if we have access to the editor of the combo box.

How can we set a default value for a combo box?

Obviously, use the 'value' configuration setting. Alternatively, we can use the setValue method.

How can we select a particular option for a combo box?

Use the setValue method.

When should we use a ArrayStore? When should we use a JsonStore?

Use JsonStore when we have an array of JSON objects. Use the ArrayStore when we have an array of arrays.

<script type='text/javascript'>
    var store = new Ext.data.JsonStore({
        url: '/srm/ot_search.jsp',
        root: 'data',
        idProperty: 'id',
        fields: ['id', 'value']
    });
    /*
    var auto_search = new Ext.form.ComboBox({
        store: store,
        displayField: 'value',
        typeAhead: true,
        mode: 'remote',
        triggerAction: 'all',
        emptyText: 'Type to activate search',
        selectOnFocus: true,
        hideTrigger: true,
        width: 250,
        renderTo: 'OTDETAIL',
    });
    */
</script>

What features does ExtJS Combobox support?

A combobox control with support for autocomplete, remote-loading, paging and many other features.

How does an ExtJS Combobox differ from the standard select element?

A ComboBox works in a similar manner to a traditional HTML <select> field. The difference is that to submit the valueField, you must specify a hiddenName to create a hidden input field to hold the value of the valueField.

What is the purpose of the displayField configuration options?

The displayField is shown in the text field which is named according to the name. displayField: (String) The underlying data field name to bind to this ComboBox (defaults to undefined if mode = 'remote' or 'field1' if transforming a select or if the field name is autogenerated based on the store configuration). If using a ComboBox in an Editor Grid, a renderer will be needed to show the displayField when the editor is not active.

What is the purpose of the valueField configuration option?

valueField: (String) The underlying data value name to bind to this ComboBox (defaults to undefined if mode = 'remote' or 'field2' if transforming a select or if the field name is autogenerated based on the store configuration). Use of a valueField requires the user to make a selection in order for a value to be mapped.

What is the purpose of the value configuration option?

value: (Mixed) A value to initialize this field with (defaults to undefined).

What is the purpose of the hiddenId configuration option?

hiddenId: (String) If hiddenName is specified, hiddenId can also be provided to give the hidden field a unique id (defaults to the hiddenName). The hiddenId and combo id should be different, since no two DOM nodes should share the same id.

What is the purpose of the hiddenName configuration option?

hiddenName: (String) If specified, a hidden form field with this name is dynamically generated to store the field's data value (defaults to the underlying DOM element's name). Required for the combo's value to automatically post during a form submission. The hidden field's id will also default to this name if hiddenId is not specified. The ComboBox id and the hiddenId should be different, since no two DOM nodes should share the same id. So, if the ComboBox name and hiddenName are the same, you should specify a unique hiddenId.

What is the purpose of the hiddenValue configuration option?

hiddenValue: (String) Sets the initial value of the hidden field if hiddenName is specified to contain the selected valueField, from the Store. Defaults to the configured value.

What is the purpose of the applyTo configuration option?

applyTo: (Mixed) Specify the id of the element, a DOM element or an existing Element corresponding to a DIV that is already present in the document that specifies some structural markup for this component. When applyTo is used, constituent parts of the component can also be specified by id or CSS class name within the main element, and the component being created may attempt to create its subcomponents from that markup if applicable. When using this config, a call to render() is not required. If applyTo is specified, any value passed for renderTo will be ignored and the target element's parent node will automatically be used as the component's container.

What is the purpose of the renderTo configuration option?

renderTo: (Mixed) Specify the id of the element, a DOM element or an existing Element that this component will be rendered into. Do not use this option if the Component is to be a child item of a Container. It is the responsibility of the Container's layout manager to render and manage its child items. When using this config, a call to render() is not required.

name: The field's HTML name attribute (default to ''). This property must be set if this field is to be automatically included with form submit.

pageSize: (Number) If greater than 0, a Ext.PagingToolbar is displayed in the footer of the dropdown list and the filter queries will execute with page start and limit parameters. Only applies when mode = 'remote' (defaults to 0).

queryDelay: (Number) The length of time in milliseconds to delay between the start of typing and sending the query to filter the dropdown list (defaults to 500 if mode = 'remote' or 10 if mode = 'local')

queryParam: (String) Name of the query (baseParam name for the store) as it will be passed on the querystring (defaults to 'query')

lastQuery: (String) The value of the match string used to filter the store. Delete this property to force a requery. To make sure the filter in the store is not cleared the first time the ComboBox trigger is used configure the combo with lastQuery=''….

allQuery: (String) The text query to send to the server to return all records for the list with no filtering (defaults to '')

anchor: (String) this config is only used when this Component is rendered by a Container which has been configured to use an AnchorLayout (or subclass thereof). based layout manager. For example:

  • Ext.form.FormPanel
  • specifying layout: 'anchor' // or 'form', or 'absolute'

See Ext.layout.AnchorLayout.anchor

autoCreate: (String/Object) A DomHelper element spec, or true for a default element spec. Used to create the Element which will encapsulate this Component. See autoEl for details. Defaults to: {tag: "input", type: "text", size: "24", autocomplete: "off"}

autoEl: (Mixed) A tag name or DomHelper spec used to create the Element which will encapsulate this Component. You do not normally need to specify this. For the base classes Ext.Component, Ext.BoxComponent, and Ext.Container, this defaults to 'div'. The more complex Ext classes use a more complex DOM structure created by their own onRender methods. This is intended to allow the developer to create application-specific utility Components encapsulated by different DOM elements ….

data: The initial set of data to apply to the tpl to update the content area of the Component.

store: (Ext.data.Store / Array) The data source to which this combo is bound (defaults to undefined). Acceptable values for this property are

  • any Store subclass
  • an Array : Arrays will be converted to a Ext.data.ArrayStore internally, automatically generating field names to work with all data components. 1-dimensional array : (e.g., ['Foo','Bar']) A 1-dimensional array will automatically be expanded (each array item will be used for both the combo valueField and displayField). 2-dimensional array : (e.g., [['f','Foo'],['b','Bar']]) For a multi-dimensional array, the value in index 0 of each item will be assumed to be the combo valueField, while the value at index 1 is assumed to be the combo displayField.

html: (String/Object) An HTML fragment, or a DomHelper specification to use as the layout element content (default to ''). The HTML content is added after the component is rendered, so the document will not contain this HTML at the time the 'render' event is fired. This content is inserted into the body before any configured contentEl is appended.

itemSelector: A simple CSS selector (e.g. div.some-class or span:first-child) that will be used to determine what nodes the Ext.DataView which handles the dropdown display will be working with. This setting is required if custom XTemplate has been specified in tpl which assigns a class other than x-combo-list-item to dropdown list items.

emptyText: (String) The default text to place into an empty field (defaults to null). Note that this value will be submitted to the server if this field is enabled and configured with a name. We may want to initialize the combo box so that it is disabled initially, but get activated with a click.

forceSelection: (Boolean) true to restrict the selected value to one of the values in the list. false to allow the user to set arbitrary text into the field (default to false)

hideTrigger: (Boolean) true to hide the trigger element and display only the base text field (defaults to false)

minChars: (Number) The minimum number of characters the user must type before autocomplete or typeAhead is activated (default to 4 if mode='remote', or 0 if mode='local'). Does not apply if editable=false

mode: (String) Acceptable values are 'remote' (default), or 'local'. The 'remote' mode loads the store the first time the trigger is clicked. If you do not want the store to be automatically loaded the first time the trigger is clicked, set to 'local', and manually load the store. To force a re-query of the store every time the trigger is clicked, see lastQuery. The 'local' mode load local data. …

submitValue: (Boolean) False to clear the name attribute on the field so that it is not submitted during a form post. If a hiddenName is specified, setting this to true will cause both the hidden field and the element to be submitted. Defaults to undefined.

tpl: (String/Ext.XTemplate) The template string, or Ext.XTemplate instance to use to display each item in the dropdown list. The dropdown list is displayed in a DataView. The default template string is '<tpl for="."><div class="x-combo-list-item">{' + this.displayField + '}</div></tpl>'. Override the default value to create custom UI layouts for items in the list. For example: '<tpl for="."><div ext:qtip="{state}. {nick}" class="x-combo-list-item">{state}</div></tpl>'. The template must contain one or more substitution parameters using field names from the Combo's Store. In the example above an ext:qtip attribute is added to display other fields from the Store. To preserve the default visual look of list items, add the CSS class name x-combo-list-item to the template's container element.

tplWriteMode: (String) The Ext.(X)Template method to use when updating the content area of the Component. Defaults to 'overwrite' (see Ext.XTemplate.overwrite).

triggerAction: (String) The action to execute when the trigger is clicked. The value 'query' (default) run the query using raw value. The value 'all' run the query specified by the allQuery config option. See queryParam.

bubbleEvents: (Array) An array of events that, when fired, should be bubbled to any parent container. See Ext.util.Observable.enableBubble. Defaults to []

Events:

How can we do something when an option is selected in the ComboBox?

Configure the select event handler:

var cb = new Ext.form.ComboBox({
    // all of your config options
    listeners:{
         scope: yourScope,
         'select': yourFunction
    }
});

// Alternatively, you can assign events after the object is created:
var cb = new Ext.form.ComboBox(yourOptions);
cb.on('select', yourFunction, yourScope);
// simple array store
var store = new Ext.data.ArrayStore({
    fields: ['abbr', 'state'],
    data : exampleData
});
var combo = new Ext.form.ComboBox({
    store: store,
    displayField:'state',
    typeAhead: true,
    mode: 'local',
    triggerAction: 'all',
    emptyText:'Select a state...',
    selectOnFocus:true,
    applyTo: 'local-states'
});

// simple array store (using template for displaying)
// simple array store
var store = new Ext.data.ArrayStore({
    fields: ['abbr', 'state', 'nick'],
    data : exampleData
});
var comboWithTooltip = new Ext.form.ComboBox({
    tpl: '<tpl for="."><div ext:qtip="{state}. {nick}" class="x-combo-list-item">{state}</div></tpl>',
    store: store,
    displayField:'state',
    typeAhead: true,
    mode: 'local',
    triggerAction: 'all',
    emptyText:'Select a state...',
    selectOnFocus:true,
    applyTo: 'local-states-with-qtip'
});

Your 'select' listener function should have 3 parameters. The first parameter represent the ComboBox. The second parameter represent the Record. The third parameter is a number representing the index into the data store. Because you have the Record object, you know the record object that was select, and because each record object is a JSON, you can retrieve the properties of this JSON:

var semVersion = record.get('SEM_VERSION_NAME');

and based on this, you can do whatever you want. Alternatively, you know the ID of the combo box, you can get the combo box component, get the selected value from there:

var cmp = Ext.getCmp('ID of the combo box component');
var value = cmp.getValue();

How can we add extra parameters to the auto-complete combo box? Use the beforeload event:

var store = new Ext.data.JsonStore({
    url: url+"&row="+rownum+"&elemIDs="+ids+"&sfield="+deColName+"&paramList="+paramList+"&entitytypeid="+vEntityTypeId+"&time="+curr_msec + "&test=1",
    root: 'data',
    idProperty: 'ROWNUM',
    method: 'GET',
    fields: ['QSUB_NATURES_ID', 'OT_ID', 'QSUBNATURESLABEL', 'LABEL', 'PROJECTSID','AP_CATEGORY_ID','OT_CATEGORY_ID','ENTITYTYPEID','NATUREDETAIL','ROWNUM','QNATURESLABEL','QNATURES_ID','OTLABEL','DATA4CALL_SET_HREF_VALUE','score']
});
store.on('beforeload', function(st, options) {
    // The first argument is the store object itself
    // The second argument is the options object
    options.params.qcolSIS_NEARMISS = document.getElementById("qcolSIS_NEARMISS").value;
    options.params.qcolNAP_CATEGORY_ID = document.getElementById("qcolNAP_CATEGORY_ID").value;
});
// Previously we were using 'Type to activate search' as emptyText, but when editing an event,
// we are supposed to show the combination of nature + sub_nature
var defaultText = document.getElementById('OTDETAIL').value;
if (defaultText.search(/\S/) == -1) {
    defaultText = 'Type to activate search';
}
var cb = new Ext.form.ComboBox({
    tpl: '<tpl for="."><div class="x-combo-list-item" style="padding:0px; border-top: 0px; border-bottom: 0px; border-right:0px"><table width="600px" style="margin:0px; border: 0px; padding:0px"><tbody style="margin:0px; padding:0px; border:0px"><tr style="font:normal 11px Verdana; margin:0px; padding:0px; border:0px"><td width="240px" bgcolor="#F4F8FC" style="margin:0px; border:0px; padding:3px 1px">{QNATURESLABEL}</td><td width="240px" bgcolor="#FDFDDD" style="margin:0px; border:0px; padding:3px 1px">{QSUBNATURESLABEL}</td><td width="120px" bgcolor="#F4F8FC" style="margin:0px; border:0px; padding:3px 1px">{OTLABEL}</td></tr></tbody></table></div></tpl>',
    store: store,
    displayField: 'NATUREDETAIL',
    mode: 'remote',
    triggerAction: 'all',
    emptyText: defaultText,
    selectOnFocus: true,
    hideTrigger: true,
    width: 398,
    listWidth: 620,
    minChars: 3,
    forceSelection: true,
    applyTo: 'OTDETAIL'
});
cb.on('select',function(box, record, index) {
    var data = record.get('DATA4CALL_SET_HREF_VALUE');
    callsetHrefValue(data);
});
 var storeDiagnostico= getStore(); // Ext.create('store.odon.DiagnosticoStore');
        storeDiagnostico.getProxy().setExtraParam("idOdontologia", value);
        storeDiagnostico.load();
 Ext.create('Ext.data.Store', {
    ...
    listeners:{
        beforeload: function(store){
            var filterText = Ext.getCmp('filterText').value;
            store.getProxy().setExtraParam("filterText", filterText);
        }
    },
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License