1. #1
    Sencha User
    Join Date
    Jul 2011
    Posts
    4
    Vote Rating
    0
    lanevska is on a distinguished road

      0  

    Default Answered: Selection the first item instead of selected one. ComboBox Autocomplete

    Answered: Selection the first item instead of selected one. ComboBox Autocomplete


    Hi,
    I am newbie to Extjs development and I am coding the MVC application. There is a combobox switching from localstorage which contains a search history with autocomplete to remote store. I encountered the following problem: when I enter a query and press Enter it always selects the first item in the drop-down list and sends it as a query parameter plquery via Ajax request. If I click on the trigger, it sends a correct one.

    Here i post a code of my search component using ComboBox:

    Code:
    Ext.define('SWIP.view.search.SearchBar', {
        extend   : 'Ext.form.ComboBox',
        alias    : 'widget.searchbar',
        store    : 'HistoryRecords',
        fieldLabel: 'Search',
        labelWidth: 50,
        trigger1Cls: Ext.baseCSSPrefix + 'form-clear-trigger',
        trigger2Cls: Ext.baseCSSPrefix + 'form-search-trigger',
        hasSearch : false,
        paramName : 'plquery',
        displayField: 'query',
        autoSelect: true,
        selectOnFocus:true,
        typeAhead: true,
        queryMode: 'local',
        triggerAction: 'query',
        disableKeyFilter:'true',
    
        minChars:           1,
        listConfig: {
            getInnerTpl: function() {
                return '<div class="search-item-combo" ><h3>{query}<span>{[Ext.Date.format(values.searchDate, "l, F d, Y g:i:s A")]}<br /></span></h3></div>';
            }
        },
        
     
        initComponent : function() {
            this.callParent(arguments);
            this.addEvents('trigger1click', 'trigger2click');
            this.on('specialkey', function(f, e){
                if(e.getKey() == e.ENTER){
                    this.onTrigger2Click();
                }
            }, this);
        },
        
        onTrigger1Click : function(){
            
            this.fireEvent('trigger1click',this);
        },
    
        onTrigger2Click : function(){
            this.fireEvent('trigger2click',this);
        }
    });
    Model
    Code:
    Ext.define('SWIP.model.HistoryRecord', {
        extend   : 'Ext.data.Model',
        fields: 
            [{
                name: 'query',
                mapping: 'query'
           },{ 
                name: 'searchDate', 
                type: 'date', 
                dateFormat: 'c',
                mapping: 'searchDate'
            }]
    });

    Localstorage:
    Code:
    Ext.define('SWIP.store.HistoryRecords', {
        extend    : 'Ext.data.Store',
        model     : 'SWIP.model.HistoryRecord',
        storeId   : 'HistoryRecords',
        autoLoad  : true,
        autoSync  : false,
        proxy     : {
                        type: 'localstorage',
                        id : 'local-id'
                    },
        constructor : function() {
            this.callParent(arguments);
       
        }
    });
    Controller
    Code:
        onSearchBarTrigger2Click : function(){
            var recordIndex = -2;
            var me = this.getSearchbar(),
            store = this.getResultsStore(),
            proxy = store.getProxy(),
            value = me.getValue();
                
            if (value.length < 1) {
                this.onSearchBarTrigger1Click();
                return;
            }
            
            proxy.extraParams[me.paramName] = value;
         
            store.load();
            me.hasSearch = true;
            me.triggerEl.item(0).setDisplayed('block');
            me.doComponentLayout();
           
          
            this.getSearchbar().store = this.getHistoryRecordsStore();      
            recordIndex = this.getSearchbar().store.findBy(    
          
                function(record, id){
                    console.log('record.get' +record.get('query') + ' id = '+id);
                    if(record.get('query') == value){
                        return true;  // a record with this data exists
                    }
                    return false;  // there is no record in the store with this data
                }
                );
               
            if (recordIndex > -1){
                model =  this.getSearchbar().store.getAt(recordIndex);
            }
            else if (recordIndex == -1)
            {
                model = Ext.ModelMgr.create({
                    query: value, 
                    searchDate: new Date()
                }, 'SWIP.model.HistoryRecord');
                
                
                this.getSearchbar().store.add(model);
                this.getSearchbar().store.sync();
            }  
        }    
    });


    After 2 days of searching on the forums I didn't find the way to fix it and I really count on your help.


    Regards,

    Anna Lanevska

  2. You've posted a lot of sections of code but I'm afraid they are both too long and incomplete.

    What I suggest you do is extract the combobox to a small example. Remove all of the bits that aren't relevant to demonstrating the problem. This will have two benefits. Firstly, you may find the solution to your problem during this reduction process. Secondly, it will allow us to reproduce your problem. Generally problems like this can't be solved just by someone looking at your code, we need to be able to drop it into an HTML page and run it ourselves.

  3. #2
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,592
    Answers
    541
    Vote Rating
    323
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    You've posted a lot of sections of code but I'm afraid they are both too long and incomplete.

    What I suggest you do is extract the combobox to a small example. Remove all of the bits that aren't relevant to demonstrating the problem. This will have two benefits. Firstly, you may find the solution to your problem during this reduction process. Secondly, it will allow us to reproduce your problem. Generally problems like this can't be solved just by someone looking at your code, we need to be able to drop it into an HTML page and run it ourselves.

  4. #3
    Sencha User
    Join Date
    Jul 2011
    Posts
    4
    Vote Rating
    0
    lanevska is on a distinguished road

      0  

    Default


    I've tried to reduce un amount of code but I still have the same problem: when I click Enter it always selects the first record in the Combobox instead of the right one. However, mouseclick doesn't evoke this issue.

    Combobox
    Code:
    Ext.define('SWIP.view.search.SearchBar', {
        extend   : 'Ext.form.ComboBox',
        alias    : 'widget.searchbar',
        store    : 'HistoryRecords', 
        fieldLabel: 'Search',
        labelWidth: 50,
        trigger2Cls: Ext.baseCSSPrefix + 'form-search-trigger',
        hasSearch : false,
        displayField: 'query',
        typeAhead: true,
        queryMode: 'local',
        minChars:           1,
        listConfig: {
            getInnerTpl: function() {
                return '<div class="search-item-combo"  ><h3>{query}<span>{[Ext.Date.format(values.searchDate,  "l, F d, Y g:i:s A")]}<br /></span></h3></div>';
            }
        },
    
        initComponent : function() {
           this.callParent(arguments);
           this.on('specialkey', function(f, e){
                if(e.getKey() == e.ENTER){
                    this.onTrigger2Click();
                }
            }, this); 
        },
         
        onTrigger2Click : function(){
            var me = this,
            store = this.store,
            proxy = store.getProxy(),
            value = me.getValue();
            console.log('Entered value is '+value);
            me.hasSearch = true;
            me.triggerEl.item(0).setDisplayed('block');
            me.doComponentLayout();
            recordIndex = store.findBy(
                function(record, id){
                    if(record.get('query') == value){
                        return true;  // a record with this data exists
                    }
                    return false;  // there is no record in the store with this data
                }
                );
            if (recordIndex > -1){
                model =  store.getAt(recordIndex);
                console.log('Query'+ model.get('query') + ' '+ 'searchDate = '+model.get('searchDate')+' Index = '+ recordIndex);
            }
            else if (recordIndex == -1)
            {
                console.log('new model'+value);
                console.log(new Date());
                model = Ext.ModelMgr.create({
                    query: value, 
                    searchDate: new Date()
                }, 'SWIP.model.HistoryRecord'); 
                store.add(model);
                store.sync();
            }  
        }    
    });


    Model
    Code:
    Ext.define('SWIP.model.HistoryRecord', {
        extend   : 'Ext.data.Model',
        fields: 
            [{
                name: 'query',
                mapping: 'query'
           },{ 
                name: 'searchDate', 
                type: 'date', 
                dateFormat: 'c',
                mapping: 'searchDate'
            }]
    });
    Store
    Code:
    Ext.define('SWIP.store.HistoryRecords', {
        extend    : 'Ext.data.Store',
        model     : 'SWIP.model.HistoryRecord',
        storeId   : 'HistoryRecords',
        autoLoad  : true,
        autoSync  : false,
        proxy     : {
                        type: 'localstorage',
                        id : 'local-id'
                    },
        constructor : function() {
            this.callParent(arguments);
        }
    });

  5. #4
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,592
    Answers
    541
    Vote Rating
    323
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    I'm afraid that's still far from a minimal test case. To help give you an idea for future reference, this is my attempt at reducing your example down to a minimum:

    Code:
    Ext.define('SWIP.view.search.SearchBar', {
        alias: 'widget.searchbar',
        extend: 'Ext.form.field.ComboBox',
    
        store: ['Red', 'Blue', 'Black', 'Brown'],
        trigger2Cls: Ext.baseCSSPrefix + 'form-search-trigger',
        typeAhead: true,
    
        listeners: {
            specialkey: function(combo, ev) {
                if (ev.getKey() === ev.ENTER){
                    combo.onTrigger2Click();
                }
            }
        },
    
        onTrigger2Click: function() {
            console.log('Entered value is ' + this.getValue());
        }
    });
    I'm still a little unclear about what it is you want. Try the following settings:

    Code:
    autoSelect: false,
    typeAhead: false, // or just remove your current setting, typeAhead: true
    Compare how this behaves to the behaviour you're currently seeing. Try experimenting with various combinations of true and false for both settings. If none of them gives you exactly what you want then please let us know exactly what your expected behaviour is and how it varies from what you get with those settings.

  6. #5
    Sencha User
    Join Date
    Jul 2011
    Posts
    4
    Vote Rating
    0
    lanevska is on a distinguished road

      0  

    Default


    Thank you for a quick response. I tried to play a bit with different values of typeAhead and autoSelection in the test example and it really reproduces my problem.

    I had the following results:

    typeAhead:
    false
    autoSelection: false/true
    Test 1: if we type 'B' and then select 'Brown' in the list by pressing Enter it returns 'B' as a value.

    typeAhead: true
    autoSelection: false/true
    Test 2: if we type 'B' and then select 'Brown' in the list by pressing Enter it returns 'Blue' as a entered value. (Blue is the first value in the list that starts from B, so the autocompletion puts the value 'Blue').

    What I need is by pressing Enter to select the right item from the dropdown list (not the first one all the time as it does in the test 2). This problem concerns only Enter click, not a mouse click.

    I hope it is clear this time and you can help me to fix it.

  7. #6
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,592
    Answers
    541
    Vote Rating
    323
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    OK, I think I've managed to piece together what it is you want.

    The dropdown and your code are fighting each other over the Enter press. Try this for your listener:

    Code:
    specialkey: {
        buffer: 10,
        fn: function(combo, ev) {
            if (ev.getKey() === ev.ENTER) {
                combo.onTrigger2Click();
            }
        }
    }

Thread Participants: 1

Tags for this Thread