dmackerman
dmackerman

Reputation: 2966

ExtJS - Navigate through ComboBox with prev/next buttons

I'm designing a custom control to look something like this: enter image description here

I've got the ComboBox loading the Store fine, but what I'm trying to do is use the arrows to select the next and previous values in the Combo. I've set the valueField on the Combo to be the "id" from the Store, which are not incremental in fashion.

I've tried something like this:

   // this gets the current record
   var currentBanner = this.bannersComboBox.getStore().getById(this.bannersComboBox.getValue());

   // this gets the current records index in the store
   var currentStoreIndex = this.bannersComboBox.getStore().indexOf(currentBanner);

The problem is that setValue() on the ComboBox requires the "value", and in this case I need to just do a simple setValue(currentValue + 1 [-1]), or something of that nature. How would you increment the combo when the values aren't incremental?

This would be really easy if there was a selectNext() or something method on the Combo!

Upvotes: 2

Views: 1158

Answers (2)

Gabriel Hautclocq
Gabriel Hautclocq

Reputation: 3320

I prefer to use select() rather than setValue(). Here's the code to select the next combobox item:

function comboSelectNextItem( combo, suppressEvent ) {
    var store       = combo.getStore();
    var value       = combo.getValue();
    var index       = store.find( combo.valueField, value );
    var next_index  = index + 1;
    var next_record = store.getAt( next_index );
    if( next_record ) {
        combo.select( next_record );

        if( ! suppressEvent ) {
            combo.fireEvent( 'select', combo, [ next_record ] );
        }
    }
}

Code to select the previous combobox item:

function comboSelectPrevItem( combo, suppressEvent ) {
    var store       = combo.getStore();
    var value       = combo.getValue();
    var index       = store.find( combo.valueField, value );
    var prev_index  = index - 1;
    var prev_record = store.getAt( prev_index );
    if( prev_record ) {
        combo.select( prev_record );

        if( ! suppressEvent ) {
            combo.fireEvent( 'select', combo, [ prev_record ] );
        }
    }
}

You could also extend Ext.form.field.ComboBox to include those functions (with minor changes). For example you can place this code in the launch() function of your application, so that any Ext.form.field.Combobox inherits of those two methods:

Ext.define( "Ext.form.field.ComboBoxOverride", {
    "override": "Ext.form.field.ComboBox",

    "selectNextItem": function( suppressEvent ) {
        var store       = this.getStore();
        var value       = this.getValue();
        var index       = store.find( this.valueField, value );
        var next_index  = index + 1;
        var next_record = store.getAt( next_index );
        if( next_record ) {
            this.select( next_record );

            if( ! suppressEvent ) {
                this.fireEvent( 'select', this, [ next_record ] );
            }
        }
    },

    "selectPrevItem": function( suppressEvent ) {
        var store       = this.getStore();
        var value       = this.getValue();
        var index       = store.find( this.valueField, value );
        var prev_index  = index - 1;
        var prev_record = store.getAt( prev_index );
        if( prev_record ) {
            this.select( prev_record );

            if( ! suppressEvent ) {
                this.fireEvent( 'select', this, [ prev_record ] );
            }
        }
    }
});

Then you could use those methods anywhere in your code:

var combo = ...         // the combo you are working on
combo.selectNextItem(); // select the next item
combo.selectPrevItem(); // select the previous item

Upvotes: 1

dmackerman
dmackerman

Reputation: 2966

Figured it out. :)

var currentBanner = this.bannersComboBox.getStore().getById(this.bannersComboBox.getValue());
var currentStoreIndex = this.bannersComboBox.getStore().indexOf(currentBanner);
var nextBannerValue = this.bannersComboBox.getStore().getAt(currentStoreIndex + 1).get('id')
this.bannersComboBox.setValue(nextBannerValue);

Upvotes: 3

Related Questions