Francesco Belladonna
Francesco Belladonna

Reputation: 11689

Get RowEditing or Grid from a RowEditing component (a combobox in this case)

I'm building a "fix" for combobox because it shows the value field instead of the display field in the textbox when you open the row editor. However, to do this I have to change the value of the combobox just before is sent to the server. To do this, my idea was to hook to beforeedit event of row editing plugin.

The biggest problem, is that I can't find a way to reach the grid which I'm row editing, or directly the row editing plugin.

Only thing I can find is the form where the combobox is in with combobox.up('form') and I can hook to those events, but I think they don't happen "early enough". I can't find a way to obtain the rowediting plugin from the form however :\

Any idea on how to solve this problem?

Edit 1:

As sha requested, this is the problem shown as images:

http://dl.dropbox.com/u/762638/Files/Images/Screenshots/show_combobox_extjs_problem/part_1.png

http://dl.dropbox.com/u/762638/Files/Images/Screenshots/show_combobox_extjs_problem/part_2.png

http://dl.dropbox.com/u/762638/Files/Images/Screenshots/show_combobox_extjs_problem/part_3.png

And here you can find the combobox code:

Ext.define('Fdd.form.field.XComboBox', {
  extend: 'Ext.form.field.ComboBox',
  alias: 'widget.xcombobox',

  displayField: 'display',
  queryMode: 'local',
  valueField: 'value',
  //forceSelection: true,

  /**
   *
   * @property {Ext.form.Panel} parentForm
   * Contains a reference to the combobox form, used internally
   *
   * @readonly
   */
  parentForm: null,
  /**
   *
   * @property {Boolean} hasChanged
   * `true` if the combobox has changed its value since last show/hide cycle
   */
  hasChanged: false,

  statics: {
    xcomboboxRenderer: function(xcombobox) {
      return function(value, metaData, record, rowIndex) {
        if (value === null)
          return '';
        return xcombobox.store.getById(value.toString()).get('display');
      }
    }
  },

  initComponent: function() {
    var me                  = this;
    var xComboBoxStoreClass = 'Fdd.data.XComboBoxStore';
    var xComboBoxStoreKey   = Ext.getClassName(me);

    // FIXME: Fix default value to be display and not value field
    // Create the combo store if not exists
    me.createComboStoreIfNotExists = function() {
      // If store is not set, we can't do anything
      if (!me.store)
        return false;

      // If the store is an array, we break the functionality and return to a normal combobox
      // because XComboBox is to avoid problems with stores
      if (Ext.isArray(me.store))
        return false;

      // We need the object for the parent store, to avoid missing references
      var parentStore = null;
      if (Ext.isString(me.store))
        parentStore = Ext.getStore(me.store)
      else
        parentStore = me.store;

      // If the store doesn't have the updatedAt variable, we don't enable functionalities
      // because that is a requirement
      if (!Ext.isDefined(parentStore.updatedAt))
        return false;

      // If parent store is of type XComboBoxStore, it means that we already have created a combo store
      if (Ext.getClassName(parentStore) == xComboBoxStoreClass)
        return false;

      var comboStore = Fdd.NamespaceKeyedStoreManager.lookup(xComboBoxStoreKey, parentStore.storeId);
      if (!comboStore) {
        comboStore = Ext.create(xComboBoxStoreClass, parentStore);
        Fdd.NamespaceKeyedStoreManager.register(xComboBoxStoreKey, parentStore.storeId, comboStore);
      }
      me.store = comboStore;

      //me.on('afterrender', function(obj, eOpts) {
      //  obj.setValue(1);
      //});

      return comboStore;
    }

    // Load data if required
    me.loadUpdatedData = function() {
      me.createComboStoreIfNotExists();
      if (me.store)
        Fdd.NamespaceKeyedStoreManager.lookup(xComboBoxStoreKey, me.store.parentStore.storeId).loadIfNotUpdated();
    };

    // Load data if required
    me.loadUpdatedData();

    // Fires loadUpdatedData every time trigger is pressed
    me.on('expand', function(obj) {
      obj.loadUpdatedData();
    });

    // TODO: Building a fix for the problem combobox input field shows the value field instead of the display field
    me.on('boxready', function(obj) {
      obj.parentForm = obj.up('form');
      console.log(obj.parentForm);
      obj.mon(obj.parentForm, 'edit', function(editor) {
        console.log("beforeaction");
        console.log(e.originalValue);
        console.log(obj);
        if (!obj.hasChanged)
          obj.setValue(obj.originalValue);
      });
      obj.mon(obj.parentForm, 'show', function() {
        /*console.log("move:");
        console.log(obj.getValue());
        console.log(obj.inputEl.dom.value);*/
        obj.hasChanged = false;

        if (obj.parentForm) {
          if (obj.getValue() === null)
            obj.inputEl.dom.value = "";
          else
            obj.inputEl.dom.value = obj.store.getById(obj.getValue().toString()).get('display');
        }
      });
    });
    me.on('change', function(obj) {
      obj.hasChanged = true;
    });

    // Call parent initializator
    me.callParent(arguments);
  }
});

The code we are talking about starts from the TODO.

I suggest to ignore previous part because is used to create a store-duplicate to avoid filtering and buffered stores.

Edit 2:

It seems like the problem I'm trying to solve through this question is not directly related to the issue I'm trying to solve anymore (solved in a different way) so the question can be closed.

Thanks anyway.

Upvotes: 0

Views: 2234

Answers (1)

sha
sha

Reputation: 17860

There is no bug in the standard Combobox control for this. I use it in many places in my projects without any issues.

Make sure you have matching types for valueFields in editor combobox, grid combobox and store itself.

Upvotes: 1

Related Questions