ExtJS 4: Combo Boxes, loadRecord() and Remote Stores

TV Remote

A while back I ran into an interesting issue regarding loading records from the database into a form that contained combo boxes driven by remote stores. The problem was, when the record got loaded into the form, the stores for the combo boxes hadn’t loaded, so all the combo boxes said “select one” instead of the option that was chosen when the form got submitted. After doing some digging, I came up with a way around this issue:

The Override Code

Ext.form.field.ComboBox.override( {
    setValue: function(v) {
        v = (v && v.toString) ? v.toString() : v;
        if(!this.store.isLoaded && this.queryMode == 'remote') {
            this.store.addListener('load', function() {
                this.store.isLoaded = true;
                this.setValue(v);
            }, this);
           this.store.load();
        } else {
            this.callOverridden(arguments);
        }
    }
});

Here, we override the setValue method of the ComboBox component and do the following:

  1. Make sure the store is not yet loaded (a custom property I added) and that it is tied to a remote store
  2. Add a listener to the ‘load’ event. When the store is loaded, set isLoaded equal to true and call setValue again.
  3. Load the store
  4. If the store is already loaded or the store is local, call the original overridden setValue method

Just drop this into whatever JS file you keep your other overrides in and you’ll be good to go. Happy coding!

Update: The source code for this snippet is available here.

Write us your thoughts about this post. Be kind & Play nice.
  1. Catalinux says:

    One problem is that a lot of change events appear on that combobox once you have made that override. I try to use it for a combobox grid cell editor where I have an POST onChange. This makes a lot of POSTs

    Reply
  2. Agile Hobo says:

    Fix typo: View should not create Store directly.

    And of course, you must set Store’s autoLoad property to true

    Reply
  3. Agile Hobo says:

    Don’t need to override, you only need to pass the store to Ext.widget(). Actually it’s my prefer way to load data. View should not work with Store directly.

    Reply
    • martijn says:

      I’m Interested in the ext.widget() solution. I do not follow what you mean by passing store to it…. and how it would work to fix this problem, I’m seeking for a solution without overrides.

      Reply
  4. soravengeur says:

    Hello, a little improvement.
    With your method, when I use the autocompletion, it’s clear all value in the field when I begin to write. Here the correction :

    if(!this.store.isLoaded && typeof(v) != “undefined”) {
    v = (v && v.toString) ? v.toString() : v;
    this.store.addListener(‘load’, function() {
    this.store.isLoaded = true;
    if (!this.store.firstLoad) {
    this.setValue(v);
    this.store.firstLoad = true;
    }
    }, this);
    this.store.load();
    } else {
    this.callOverridden(arguments);
    }

    Reply
  5. arcan9ne says:

    This is a nice hack, I had to remove:
    v = (v && v.toString) ? v.toString() : v;

    because the value field is an integer for me. Maybe there is a reason I don’t see behind this.

    One strange thing that is occuring is that the store of a combo is loading when rendered and the setValue() is not being called.

    Reply
  6. Santosh says:

    Hi Puneet

    You can use the record option of the json parser.

    Reply
  7. Puneet says:

    Hi,

    Nice post, i am facing one problem with combo box, hope you could help me/

    i have a nested json in form of data { ‘id’:’1′,[{'descr':'this is id'}]} .

    how i can display descr as displayField in combo and id as valueField ?

    Thanks

    Reply
  8. Conor says:

    Nice override. One issue though. If you are viewing a form and not making any amendments, then this code is going to automatically load the store necessitating another trip to the server. A better solution might be the Ext.ux.form.AutoCombo

    Reply
    • arcan9ne says:

      Any ideas on what could be done to circumvent one the unnecessary trips (other than Ext.ux.form.AutoCombo)?

      Thanks,
      arcan9ne

      Reply

Leave a reply.