SlickGrid select editor
I want to make a dynamically populated html select for a select cell. I extract some information from a database which is different for every row item. The problem is that the editor loses the initial data and I don't know how to keep some data for a specific cell. Has someone done this before?
function StandardSelectCellEditor($container, columnDef, value, dataContext) {
var $input;
var $select;
var defaultValue = value;
var scope = this;
this.init = function() {
$input = $("<INPUT type=hidden />");
$input.val(value);
}
$input.appendTo($container);
$select = $("<SELECT tabIndex='0' class='editor-yesno'>");
jQuery.each(value, function() {
$select.append("<OPTION value='" + this + "'>" + this + "</OPTION></SELECT>");
});
$select.append("</SELECT>");
$select.appendTo($container);
$select.focus();
};
this.destroy = function() {
//$input.remove();
$select.remove();
};
this.focus = function() {
开发者_JAVA百科 $select.focus();
};
this.setValue = function(value) {
$select.val(value);
defaultValue = value;
};
this.getValue = function() {
return $select.val();
};
this.isValueChanged = function() {
return ($select.val() != defaultValue);
};
this.validate = function() {
return {
valid: true,
msg: null
};
};
this.init();
};
A similar queations was asked here (this one is however not slickgrid tagged).
I did make a SelectEditor, with a flexible range of options depending on the column we are in. The reason of thinking here is that the datatype of the value you edit in a column will determine the valid choices for this field.
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();
}
You can slightly modify the above SelectCellEditor to create different select options for each cell.
function SelectCellEditor(args) {
.....
// just to get the DOM element
this.getInputEl = function() {
return $input;
};
}
Now it is easy to create a dynamic dropdown editor.
function DynamicSelectCellEditor(args) {
// 1: if you already have a select list for individual cells
args.columns.options = optionsList[args.item.id] // or any custom logic
return new Slick.Editors.SelectCellEditor(args);
/* OR */
// 2: if data needs to be fetched from the server
var editor = new Slick.Editors.SelectCellEditor(args),
$select = editor.getInputEl();
$select.html("<option>Loading...</option>");
$.ajax({ }).done(function(list) {
// Update select list
$select.html(newHtml);
});
return editor;
}
replace
for( i in opt_values ){
v = opt_values[i];
option_str += "<OPTION value='"+v+"'>"+v+"</OPTION>";
}
with
$.each(opt_values , function( index, value ) {
option_str += "<OPTION value='"+value+"'>"+value+"</OPTION>";
});
if it is not working for you
Please try the below code.
In slick.editors.js,Define a new editor.
$.extend(true, window, {
"Slick": {
"Editors": {
"SelectOption": SelectCellEditor,
.....
}
}
});
function SelectCellEditor(args) {
var $select;
var defaultValue;
var scope = this;
var s;
this.init = function() {
opt_values = eval(args.column.options);
option_str = "";
var tuples = [];
for (var key in opt_values) tuples.push([key, opt_values[key]]);
tuples.sort(function(a, b) { return a[1] < b[1] ? 1 : a[1] > b[1] ? -1 : 0 });
var length = tuples.length;
while (length--) option_str += "<OPTION value='"+tuples[length][0]+"'>"+tuples[length][1]+"</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() {
return $select.val();
};
this.applyValue = function(item,selectedIndex) {
if($.isNumeric(selectedIndex))
item[args.column.field] = parseInt(selectedIndex);
else
item[args.column.field] = selectedIndex;
};
this.isValueChanged = function() {
return ($select.val() != defaultValue);
};
this.validate = function() {
return {
valid: true,
msg: null
};
};
this.init();
}
Then, modify your grid options
var grid_options = {
editable: true,
enableAddRow: false,
multiColumnSort: true,
explicitInitialization: true,
dataItemColumnValueExtractor: function(item, columnDef) {
if(columnDef.editor == Slick.Editors.SelectOption){
return eval(columnDef.options)[item[columnDef.field]];
}else{
return item[columnDef.field];
}
}
};
And use the editor while columns initialization.
{id: "currency_id", name: "Currency *", field: "currency_id", editor: Slick.Editors.SelectOption, options: { 1: 'Dollar', 2: 'Yen', 3: 'Rupiah' }, sortable: true,width: 234}
I can't add comments yet, but I need to add something to HeiN's answer.
HeiN's answer works great, but I have data coming in that does not match my select options and I need to still display that data... so I have had to modify dataItemColumnValueExtractor in the options. This allows my original data to display if I do not have an option in the list to match.
dataItemColumnValueExtractor: function(item, columnDef) {
if(columnDef.editor == Slick.Editors.SelectOption){
return eval(columnDef.options)[item[columnDef.field]] != null ? eval(columnDef.options)[item[columnDef.field]] : item[columnDef.field];
}else{
return item[columnDef.field];
}
}
Hope this helps somebody later down the line.
精彩评论