0

We have a listbox defined in a slickgrid column. We have the problem that to select an option from the listbox, we first have to select the cell, and then the option can be selected from the list box. Thus the user requires two clicks instead of one. What do we have to do so that the user can with one click open the list box to select the required value.

We use the following cell formatter and editor to display the list box:

FORMATTER:

function SelectCellFormatter(row, cell, value, columnDef, dataContext) {
    opt_values = columnDef.options.split(',');
    option_str = "";
    for( i in opt_values ){ 
        v = opt_values[i]; 
        if(v == value)
        {
            option_str += "<OPTION value='"+v+"' selected>"+v+"</OPTION>";
        }
        else
        {
            option_str += "<OPTION value='"+v+"'>"+v+"</OPTION>";
        }
    } 
    return "<SELECT tabIndex='0' class='editor-select'>"+ option_str +"</SELECT>"
}

EDITOR:

SelectCellEditor : function(args) {
    var $select;
    var defaultValue;
    var scope = this;

    this.init = function() {

        if(args.column.options){
            opt_values = args.column.options.split(',')
        } else {
            opt_values ="yes,no".split(',');
        }
        option_str = ""
        for( i in opt_values ){
            v = opt_values[i];
            option_str += "<OPTION value='"+v+"'>"+v+"</OPTION>";
        }
        $select = $("<SELECT tabIndex='0' class='editor-select'>"+ option_str +"</SELECT>");
        $select.appendTo(args.container);
        $select.focus();
    };

    this.destroy = function() {
        $select.remove();
    };

    this.focus = function() {
        $select.focus();
    };

    this.loadValue = function(item) {
        defaultValue = item[args.column.field];
        $select.val(defaultValue);
    };

    this.serializeValue = function() {
        if(args.column.options){
            return $select.val();
        } else {
            return ($select.val() == "yes");
        }
    };

    this.applyValue = function(item,state) {
        item[args.column.field] = state;
    };

    this.isValueChanged = function() {
        return ($select.val() != defaultValue);
    };

    this.validate = function() {
        return {
            valid: true,
            msg: null
        };
    };

    this.init();
}
David-Cole
  • 1
  • 1
  • 3
  • I have no idea if it will work but have you tried setting `{ autoEdit: true }` in the grid options? Don't know if the editor will activate in the right order to allow the listbox to receive the click. – njr101 Apr 18 '12 at 14:58

2 Answers2

0

First of all, you are implementing the same control in both the formatter and the editor. This can serve no useful purpose.

Second, SlickGrid architecture is not well suited for using rich editable controls in cells. SlickGrid is designed to only load them when a cell is switched into edit mode (I won't go into the reasons behind that here).

As @njr pointed out, you can set the "autoEdit" option to make cells go into edit mode right away, though that won't "open" the combobox on first click.

Tin
  • 9,082
  • 2
  • 34
  • 32
0

The solution is to use just a formatter and not an editor. The click now opens the list box as one would expect Then with the onChange method of the formatter the required logic can be carried out.

The only problem was that we could not define the formatter for new rows. We set enableAddRow : false, and used an insert button to add new rows.

Formatter:

function SelectCellFormatter(row, cell, value, columnDef, dataContext) {
    opt_values = columnDef.options.split(',');
    option_str = "";
    for( i in opt_values ){ 
        v = opt_values[i]; 
        if(v == value)
        {
            option_str += "<OPTION value='"+v+"' selected>"+v+"</OPTION>";
        }
        else
        {
            option_str += "<OPTION value='"+v+"'>"+v+"</OPTION>";
        }
    } 
    return "<SELECT onchange='SelectCellFormatter_onchange(this, "
       + row + "," + cell + ",\"" + value + "\");'>"+ option_str + "</SELECT>"
}

SelectCellFormatter:

function SelectCellFormatter_onchange(vThis, vRow, vCell, vValue)
{
     document.protokoll_form.protokoll_name.value += " row/" + vRow;
     document.protokoll_form.protokoll_name.value += " cell/" + vCell;
     document.protokoll_form.protokoll_name.value += " old/" + vValue;
     document.protokoll_form.protokoll_name.value += " new/" 
            +  vThis[this.event.currentTarget.selectedIndex].value;
}
David-Cole
  • 1
  • 1
  • 3