質問

Overview

I am using dojo and dgrid to build a grid. The 2 relevant columns are Client and Proposal. Double clicking on either column will allow you to edit it with a dijit/form/Select. I want options for proposal to be be based on the options for client.

Here is the column plugin used for both colums:

define([
    "dojo",
    "sb",
    "put-selector/put",
    "dgrid/editor",
    "dijit/form/Select"
], function(dojo, sb, put, editor, Select){
    dojo.global.starbug.grid.columns = dojo.global.starbug.grid.columns || {};
    dojo.global.starbug.grid.columns.select = function(column){

        //populate the cell with the label or value
        column.renderCell = function(object, value, cell, options, header){
            put(parent && parent.contents ? parent : cell, ".dgrid-select");
            items = column.editorInstance.getOptions();
            var label;
            for (var i in items) {
                if (value == items[i].value) value = items[i].label;
            }
            put(cell, 'span.'+value.replace(/ /g, '-').toLowerCase(), value);
        };

        column.editorArgs = {
            style:'width:100%',
            labelAttr:'label',
            store:sb.get(column.from, 'select')
        };

        column = editor(column, Select, "dblclick");

        return column;
    };
});

The store is equivalent to dojo/store/JsonRest.

The Problem

If I understand the nature of dgrid and dojo/store, I need to find a way populate/update the dijit/form/Select options when the user attempts to edit the column.

In summary

  • How do I determine when the user attempts to edit the column?
  • How do I then access the dijit/form/Select so that I can update it?
  • How can I delay displaying the editor until it is populated?
役に立ちましたか?

解決

1. How do I determine when the user attempts to edit the column?

You can use the dgrid-editor-show event that is dispatched by the editor plugin.

2. How do I then access the dijit/form/Select so that I can update it?

You will have access to column.editorInstance from the event handler

3. How can I delay displaying the editor until it is populated?

To do this I did have to access a private member of column.editorInstance, but I was able to accomplish the task by using dojo/when on column.editorInstance._queryRes

I also needed this to set the value of the editor once the results were in.

Here is my solution:

define([
    "dojo",
    "dojo/when",
    "sb",
    "put-selector/put",
    "dgrid/editor",
    "dijit/form/Select"
], function(dojo, when, sb, put, editor, Select){
  dojo.global.storm.grid.columns.proposals = function(column){

    //We have to keep some cached display values since our editor
    //will only contain the display values from the last request
    var cache = {};

    //Use the init function to access the grid
    //so we can attach the event handler to `dgrid-editor-show`
    column.init = function() {
        column.grid.on('.dgrid-cell:dgrid-editor-show', function(evt) {

            //My data contains null values,
            //so I need to convert them to strings
            if (evt.cell.row.data[column.field] == null) {
                evt.cell.row.data[column.field] = "NULL";
            }

            //This is where we set the query and update the available options
            column.editorInstance.setStore(
                column.editorInstance.store,
                evt.cell.row.data[column.field],
                {query:{client:evt.cell.row.data.client_id}}
            );
            //This is where we set editor value upon receipt of the results
            when(column.editorInstance._queryRes, function() {
                column.editorInstance.set(
                    'value',
                    evt.cell.row.data[column.field]
                );
            });
        });
    };

    //Use the renderCell function to set the display value
    column.renderCell = function(object, value, cell, options, header){

        //add a class to distinguish this column
        put(parent && parent.contents ? parent : cell, ".dgrid-select");

        //for null values, we just put in an empty string
        if (value == "NULL") put(cell, 'span.proposal', "");
        else if (value) {
            //otherwise delay til we have results
            when(column.editorInstance._queryRes, function() {
                //look for the display value in the editor
                items = column.editorInstance.getOptions();
                var found = false;
                for (var i in items) {
                    //if we find the display value in the editor, cache it
                    if (value == items[i].value) {
                        found = true;
                        cache[value] = items[i].label;
                        value = items[i].label;
                    }
                }
                //if we don't find the display value in the editor,
                //look for it in the cache
                if (!found && cache[value]) value = cache[value];
                //finally, populate the cell
                put(cell, 'span.proposal', value);
            });
        }
    };

    //Set the editor args, mostly standard stuff
    column.editorArgs = {
        style:'width:100%',
        labelAttr:'label',
        sortByLabel:false,
        store:sb.get(column.from, 'select'),
        onSetStore:function(store, items) {
            //if the field is not required, put in an empty options
            //so the store doesn't have to include one
            if (!this.required) {
                this.options.unshift({label:' ', value:'NULL'});
                this._loadChildren();
            }
        }
    };

    //create the editor
    column = editor(column, Select, "dblclick");

    //return the column
    return column;

  };
});
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top