Slickgrid, column with a drop down select list?

*爱你&永不变心* 提交于 2019-11-27 19:44:29

I assume you mean a custom cell editor. Here's a sample select-based boolean cell editor from slick.editors.js. You could easily modify it to work with an arbitrary set of possible values.

function YesNoSelectCellEditor($container, columnDef, value, dataContext) {
    var $select;
    var defaultValue = value;
    var scope = this;

    this.init = function() {
        $select = $("<SELECT tabIndex='0' class='editor-yesno'><OPTION value='yes'>Yes</OPTION><OPTION value='no'>No</OPTION></SELECT>");

        if (defaultValue)
            $select.val('yes');
        else
            $select.val('no');

        $select.appendTo($container);

        $select.focus();
    };


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


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

    this.setValue = function(value) {
        $select.val(value);
        defaultValue = value;
    };

    this.getValue = function() {
        return ($select.val() == 'yes');
    };

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

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

    this.init();
};
Matthijs

You probably dont want to make a new select editor for each range of options. Also you may not know that range of all option value beforehand.

In that case you want a flexible range of options in a select type editor. In order to do this you can add an extra option to your column definitions (e.g. called options) like this:

 var columns = [
  {id:"color", name:"Color", field:"color",  options: "Red,Green,Blue,Black,White", editor: SelectCellEditor},
  {id:"lock", name:"Lock", field:"lock",  options: "Locked,Unlocked", editor: SelectCellEditor}
 ]

and access that using args.column.options in the init method of your own SelectEditor object like this:

 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();
    }

If your cell already contains a "select"-tag with multiple options, you can extract this html from the args. The approach differs from the previous answers, but I was personally troubled with these solutions, course my cell already contained a select-tag. I'd like to reuse this cell instead of reconstructing it completely in the this.init. Likewise, I'd like to keep using the same options, as my existing select already have, instead of parsing them to the var column = { ...

The $( args.item[ args.column.field ] ) return the active cells content, which basically just get re-appended to the the container (the cell-object). From if ( document.createEvent ) and down, is just a functionality which automatically opens the dropdown on activation; etc. when you use tabulator to navigate to the cell.

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

    this.init = function () {
        $select = $( args.item[ args.column.field ] );
        $select.appendTo( args.container );
        $select.focus();

        // Force the select to open upon user-activation
        var element = $select[ 0 ];

        if ( document.createEvent ) { // all browsers
            var e = new MouseEvent( "mousedown", {
                bubbles: true,
                cancelable: true,
                view: window
            });

            element.dispatchEvent( e );
        } else if ( element.fireEvent ) { // ie
            element.fireEvent( "onmousedown" );
        }

    };
}

Complet editor for Dropdown html-input -> Dropdown html-output

function SelectCellEditor( args ) {
    var $select = $( args.item[ args.column.field ] );
    var defaultValue;
    var scope = this;

    this.init = function () {
        //$select
        $select.appendTo( args.container );

        // Force the select to open upon user-activation
        var element = $select[ 0 ];

        if ( document.createEvent ) { // all browsers
            var e = new MouseEvent( "mousedown", {
                bubbles: true,
                cancelable: true,
                view: window
            });

            element.dispatchEvent( e );
        } else if ( element.fireEvent ) { // ie
            element.fireEvent( "onmousedown" );
        }

        $select.on("click", function( e ) {
            var selected = $( e.target ).val();

            $select.find( "option" ).removeAttr( "selected" );
            $select.find( "option[value='" + selected + "']" ).attr( "selected", "selected" );
        });

    };

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

    this.focus = function () { };

    this.loadValue = function ( item ) { };

    this.serializeValue = function () { };

    // Only runs if isValueChanged returns true
    this.applyValue = function ( item, state ) {
        item[ args.column.field ] = $select[ 0 ].outerHTML;
    };

    this.isValueChanged = function () {
        return true;
    };

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

    this.init();
}

Without jq, and inline injected elements, packed in module:

'use strict';
 class SelectCellWidget {
    constructor(args) {
        this._args = args;
        this._$select = undefined;
        this._defaultValue = undefined;
        this._init();
    }
     _init () {
        let selects, container, divend, opt_values;
        const args = this._args;
        if(args.column.options){
            opt_values = args.column.options.split(',');
        }else{
            opt_values = ["yes","no"];
        }
        container = document.createElement("div");
        container.classList.add('select-editable');
        divend = document.createElement('input');
        divend.setAttribute("type", "text");
        divend.setAttribute("name", "format");
        divend.setAttribute("value", "");
        selects = document.createElement("select");//"<select id='Mobility' tabIndex='0' class='editor-select'>"+ option_str +"</select>";
        selects.setAttribute("id", "Mobility");
        selects.setAttribute("tabIndex", 0);
        selects.setAttribute("class", "editor-select");
        for(let i = 0; i < opt_values.length; i++) {
            let v = opt_values[i];
            let option = document.createElement("option");
            option.setAttribute("value", v);
            option.innerText = v;
            selects.appendChild(option);
        }

        container.appendChild(divend);
        container.appendChild(selects);
        this._$select = container;
        args.container[0].appendChild(this._$select);
        this._$select.focus();
        document.getElementById("Mobility").selectedIndex = args.item[args.column.field] ? opt_values.indexOf(args.item[args.column.field]) : 0;
    }
     destroy () {
        this._$select.remove();
    }
     focus () {
        this._$select.focus();
    }
     loadValue (item) {
       this._defaultValue = item[this._args.column.field];
       this._$select.value = this._defaultValue;
    }
     serializeValue () {
        if(this._args.column.options){
            return this._$select.lastElementChild.value;
        }else{
            return (this._$select.lastElementChild.value === "yes");
        }
    }
     applyValue (item,state) {
       item[this._args.column.field] = state;
    }
     isValueChanged () {
       return (this._$select.lastElementChild.value !== this._defaultValue);
    }
     validate () {
       return {
           valid: true,
           msg: null
       };
    }
}
module.exports=SelectCellWidget; 

https://github.com/YaAlfred/SlickgridSelectDropdownWidget

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!