Using examples from web, I've tried to implement my own customized combobox (YesNoEditor) where it allows both display and value members to be saved. The idea is to have the HTML output of SELECT tag to contain both an option value and an actual text to be displayed like so:
("<SELECT tabIndex='0' class='editor-yesno'><OPTION value='valuemember'>DisplayMember</OPTION></SELECT>");
And here's my modified version of YesNoEditor from slick.editors.js
function YesNoSelectEditor(args) {
var $select;
var defaultValue;
var scope = this;
this.init = function () {
if (args.column.options && args.column.display) {
opt_display = args.column.display.split(',');
opt_values = args.column.options.split(',');
} else {
opt_values = "yes,no".split(',');
}
option_str = "";
for (i in opt_values) {
v = opt_values[i];
d = opt_display[i];
option_str += "<OPTION value='" + v + "'>" + d + "</OPTION>";
}
$select = $("<SELECT tabIndex='0' class='editor-select'>" + option_str + "</SELECT>");
$select.appendTo(args.container);
$select.focus();
};
this.getDefaultValue = function () {
return defaultValue;
};
this.destroy = function () {
$select.remove();
};
this.focus = function () {
$select.focus();
};
this.loadValue = function (item) {
defaultValue = item[args.column.field];
$select.val(defaultValue);
};
this.getSelectValue = function () {
if (args.column.options) {
return $select.val();
}
}
this.serializeValue = function () {
if (args.column.options) {
return $select.children("option:selected").text();
} 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();
}
This mostly works, except when I try to manually click the combobox, it sporadically changes the text value to something other than its previously selected value. For instance, the combobox could've had display value 2 but as soon as I click on the cell to activate the combobox, the display value changes to 1.
Is there any good alternative method to accomplish what I need?
-----Edit2
Here's an example of how I define the column using YesNoEditor
{ id: "Type", name: "Customer Type", width: 100, field: "Type", editor: Slick.Editors.YesNoSelect, options: customerTypeList.join(","), display: customerTypeList.join(",")},
I think your problem is in the this.loadValue
function... This is the piece of code I use and it always make the dropdown to open with the correct selection:
this.loadValue = function(item) {
defaultValue = item[args.column.field];
$select.val(defaultValue);
};
It's worth a try, hopefully that would be it...let me know
EDIT
Here is my complete code for custom , I can pass custom values or use the default yes/no when it doesn't find anything:
function SelectEditor(args) {
var $select;
var defaultValue;
var scope = this;
this.init = function() {
if(args.column.editorOptions.options){
tabOptions = args.column.editorOptions.options.split(',');
if(args.column.editorOptions.values)
tabValues = args.column.editorOptions.values.split(',');
}else{
tabOptions ="yes,no".split(',');
}
var option_str = "";
for( i in tabOptions ){
var opt = $.trim( tabOptions[i] ); // remove any white space including spaces after comma
//var val = (typeof tabValues == 'undefined') ? tabOptions[i] : tabValues[i];
option_str += "<OPTION value='"+opt+"'>"+opt+"</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.editorOptions.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();
}
I realized that I forgot to mention how I call it inside the columns
array definition...
{ id:'column1', field:'column1', name: "Column 1", width:75, editor: Slick.Editors.Select, editorOptions:{options:"val1,val2,val3"} }
EDIT #2
Alright after understanding your real need, I changed my code and even tested it to make sure that it works..and it does indeed works like you wanted:
function YesNoSelectEditor(args) {
var $select;
...
// define both your arrays here so they are global and availble from everywhere
var opt_values = [];
var opt_display = [];
...
this.loadValue = function (item) {
var displayedText = item[args.column.field];
// first find the index position inside your Display Array, ex.: Colorado
var idxPos = $.inArray(displayedText,opt_display);
// second use that index found to get the value, ex.: CO
defaultValue = opt_values[idxPos];
// then select that value ex.: $select.val("CO");
$select.val(defaultValue);
};
...
}