1. #1
    Sencha User Fire-Dragon-DoL's Avatar
    Join Date
    Dec 2011
    Posts
    141
    Vote Rating
    1
    Fire-Dragon-DoL is on a distinguished road

      1  

    Default Tutorial about building a combobox display value renderer for your grid

    Tutorial about building a combobox display value renderer for your grid


    Today after a lot of tests I finally found a correct way to render the combobox display value that is using a remote store, directly into your grid (normally only the value field is rendered).

    The problem which looks easy becomes harder to face when you understand that can happen that your grid will be rendered before your combobox store is actually loaded, resulting in an empty cell.

    Notice that this script won't cover when should be loaded the store of the combobox, but the option "store" of a combobox should be enough.

    Notice also that this renderer requires a reference to the combobox, so maybe you will need to preallocate it instead of using xtype in your column. (just put the allocated combobox as an "editor" in the column).

    This method could be placed anywhere, I placed it as a static method of a custom combobox I've created, but you can put it in a singleton for example.

    Code:
    xcomboboxRenderer: function(xcombobox) {
          return function(value, metaData, record, rowIndex, colIndex, gridStore, view) {
            // Cell renders with an empty string if no city is chosen
            if (value === null)
              return '';
    
            var currentModelRecord = xcombobox.store.getById(value);
    
            // If currentModelRecord is null, store is not already loaded
            if (currentModelRecord === null) {
    
              // If store is not loaded, we prepare a function that will update the cell string
              // when the store is loaded. In this way we have a clean interface effect.
              (function(){
                var comboStoreLoadFunc = function(obj, records, successful, eOpts) {
                  var cellEl = Ext.fly(Ext.fly(eOpts.view.getNode(eOpts.record)).query('.x-grid-cell')[eOpts.colIndex]).down('div');
                  cellEl.setHTML(this.store.getById(eOpts.value).get('display'));
                  this.mun(this.store, 'load', eOpts.callback, this);
                };
                xcombobox.mon(xcombobox.store, 'load', comboStoreLoadFunc, xcombobox, {
                  value: value,
                  metaData: metaData,
                  record: record,
                  rowIndex: rowIndex,
                  colIndex: colIndex,
                  gridStore: gridStore,
                  view: view,
                  callback: comboStoreLoadFunc
                });
              })();
    
              // If store is not already loaded, we put a loading image as cell text
              return '(Loading...)'; // Put a loading image here, will give you a nice result
            }
    
            // Return the correct text for the cell
            return currentModelRecord.get('display');
          }
        }
    Code is split in 2 parts by the IF "if (currentModelRecord === null) {".
    What happen inside the if, is what happens when the store is not loaded, otherwise we use common rendering technique for a combobox.

    What need a bit of explaination is what happens inside the if.
    First, we create an anonymous function and directly call it. This is a javascript exploit to make all variables "private" to that function, so basically those are variables that won't be called anywhere else, just to ensure it: (function(){})(), yea horrible syntax.

    Then, we create a function that will update our cell text with the display value of our value (you can see it by setHTML function).
    The

    Code:
    Ext.fly(Ext.fly(eOpts.view.getNode(eOpts.record)).query('.x-grid-cell')[eOpts.colIndex]).down('div')
    line was found on the internet, but you can build it by yourself: it gets a cell from a row markup. I don't understand why they didn't build this directly inside ext.
    Notice that we ensure that the function is removed from load event, this because once the store is loaded, is loaded. You can remove this line if you don't want this behaviour:

    Code:
    this.mun(this.store, 'load', eOpts.callback, this);
    But I never call "clear" on stores in my application.

    The next line will actually hook this function to the load event of the combobox store. Passing a lot of params.

    That's all.

    One important thing is that if your combobox store is "split" in pages, I don't think the script will work (I didn't handle any paging functionality), it can be fixed in some way but I didn't think about it because I don't need.
    I suggest you to always load all data when using a combobox (you do the same with a simple select box, so it's not a big problem). I understood this when trying to build paging and had a lot of problems.

    Thanks for reading this tutorial, hope this help in some way.

  2. #2
    Sencha - Support Team scottmartin's Avatar
    Join Date
    Jul 2010
    Location
    Houston, Tx
    Posts
    9,111
    Vote Rating
    470
    scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future

      0  

    Default


    Thank you for the contribution. Help is always appreciated.

    Scott.

  3. #3
    Sencha User Fire-Dragon-DoL's Avatar
    Join Date
    Dec 2011
    Posts
    141
    Vote Rating
    1
    Fire-Dragon-DoL is on a distinguished road

      1  

    Default


    Thank you for even reading the post.

    I decided to put this tutorial here so people will find this resource on the net hopefully.
    I'm working with Ext in this period so I'll share my experience to speed up work for other people.

Thread Participants: 1

Tags for this Thread