Handsontable: Updating a cell renderer at runtime - handsontable

I'm using handsontable, and I want to change the background color of a cell if its value is edited and changed. I can do this easily if my data source is an array of arrays (see fiddle: http://jsfiddle.net/chiman24/3o2c3c7m/).
document.addEventListener("DOMContentLoaded", function() {
// Row Styles
var blank = function(instance, td, row, col, prop, value,
cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
td.style.backgroundColor = '#ABAAAA'
};
var align = function(instance, td, row, col, prop, value,
cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
td.style.verticalAlign = 'middle';
td.style.fontWeight = 'bold';
};
var highlight1 = function(instance, td, row, col, prop, value,
cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
td.style.backgroundColor = '#BDD7EE';
td.style.textAlign = 'right';
};
var changedBackgroundColor = '#cbd9e4';
var defaultBackgroundColor = 'white';
var hasChanged = function(instance, td, row, col, prop, value,
cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
td.style.backgroundColor = changedBackgroundColor;
};
var noChange = function(instance, td, row, col, prop, value,
cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
td.style.backgroundColor = defaultBackgroundColor;
};
var data = [
["1", "Hear us from heaven", "New Life Worship",
"Anderson, Jared", "something"
],
["2", "Spirit Break Out", "Kim Walker", "Walker, Kim",
"Still Believe"
]
],
dataCopy = [
["1", "Hear us from heaven", "New Life Worship",
"Anderson, Jared", "something"
],
["2", "Spirit Break Out", "Kim Walker", "Walker, Kim",
"Still Believe"
]
],
container = document.getElementById('example1'),
hot1;
//Table Row and Col Options
hot1 = new Handsontable(container, {
data: data,
fixedColumnsLeft: 1,
columnSorting: true,
colHeaders: ["id", "title", "artist", "author", "album"],
columns: [{
type: "text"
}, {
type: "text"
}, {
type: "text"
}, {
type: "text"
}, {
type: "text"
}]
});
hot1.addHook('afterChange', afterChange);
function afterChange(changes, source) {
if (source == 'edit' || source == 'autofill') {
$.each(changes, function(index, element) {
var change = element;
var rowIndex = change[0];
var columnIndex = change[1];
var oldValue = change[2];
var newValue = change[3];
var cellChange = {
'rowIndex': rowIndex,
'columnIndex': columnIndex
};
if (oldValue != newValue) {
var cellProperties = hot1.getCellMeta(
rowIndex, columnIndex);
if (newValue != dataCopy[rowIndex][
columnIndex
]) {
cellProperties.renderer = hasChanged;
} else { //data changed back to original value.
cellProperties.renderer = noChange;
}
hot1.render();
}
});
}
}
});
// noSideScroll class added to fix some containers while side scrolling the table
$(window).scroll(function() {
$('.noSideScroll').css({
'left': $(this).scrollLeft()
});
});
However, when using an array of objects, I can't get it to work. (see fiddle: http://jsfiddle.net/chiman24/24mpavga/).
var data = [{
"id": 1,
"title": "First Loved Me",
"artist": "Israel and New Breed",
"author": "Houghton, Israel",
"album": "Covered: Alive In Asia"
}, {
"id": 2,
"title": "One Thing Remains",
"artist": "Israel and New Breed",
"author": "Houghton, Israel",
"album": "Covered: Alive In Asia"
}],
dataCopy = [{
"id": 1,
"title": "First Loved Me",
"artist": "Israel and New Breed",
"author": "Houghton, Israel",
"album": "Covered: Alive In Asia"
}, {
"id": 2,
"title": "One Thing Remains",
"artist": "Israel and New Breed",
"author": "Houghton, Israel",
"album": "Covered: Alive In Asia"
}],
container = document.getElementById('example1'),
hot1;
//Table Row and Col Options
hot1 = new Handsontable(container, {
data: data,
fixedColumnsLeft: 1,
columnSorting: true,
colHeaders: ["id", "title", "artist", "author", "album"],
columns: [{
data: "id"
}, {
data: "title"
}, {
data: "artist"
}, {
data: "author"
}, {
data: "album"
}]
});
hot1.addHook('afterChange', afterChange);
function afterChange(changes, source) {
if (source == 'edit' || source == 'autofill') {
$.each(changes, function(index, element) {
var change = element;
var rowIndex = change[0];
var columnIndex = change[1];
var oldValue = change[2];
var newValue = change[3];
var cellChange = {
'rowIndex': rowIndex,
'columnIndex': columnIndex
};
if (oldValue != newValue) {
var cellProperties = hot1.getCellMeta(
rowIndex, columnIndex);
if (newValue != dataCopy[rowIndex][
columnIndex
]) {
cellProperties.renderer = hasChanged;
} else { //data changed back to original value.
cellProperties.renderer = noChange;
}
hot1.render();
}
});
}
}
Is there a way to accomplish this? I want to get it working using an array of objects because my data coming from the server will be in JSON format. I've scoured the handsontable documentation for a couple of days to no avail. Any help will be much appreciated. Thanks.

I got some help from the handsontable github forum.
Apparently, if the data source is an array of objects, then when calling "getCellMeta", instead of passing in a numerical column index, you have to pass in the column index as a property like this:
hot.getCellMeta(2, hot.propToCol(columnIndex));
Here's the updated demo

Other way to change background color of cell is use the Cell Option
...
if (oldValue != newValue){
aCell.push(
{ row: rowIndex,
col: hot.propToCol(columnIndex),
className: "cssWithBackgroundColor" });
hot.updateSettings({ cell: aCell });
}
If the user undo change you can
if ( source == 'UndoRedo.undo'){
aCell.pop();
hot.updateSettings({ cell: aCell });
}

Related

How to trigger two different custom auto completer using (.) period and Ctrl_space in ace editor

I have two completer. one for Math custom functions and another for string custom functions. i want to trigger string functions using (.)period and for ctrl_space for math function.
Now if i press (.) or ctrl_space, it showing all the functions. but i want differentiate between two of them.Thanks..
var stringFunctions = ["Trim","Length","ToLower","ToUpper","ToNumber","ToString"]
var mathFunctions = ["Abs","Ceil","Exp","Floor","Log","ln","Pow","Round","Sqrt","cos","sin","tan","cosh","sinh","tanh","acos","asin","atan","Max","Min","Sum","Std","Var","Average","Norm","Median"]
var myCompleter1 = {
// identifierRegexps: [/[a-zA-Z_0-9\.\$\-\u00A2-\uFFFF]/],
getCompletions: function(editor, session, pos, prefix, callback) {
console.info("myCompleter prefix:", this.prefix);
callback(
null,
myList.filter(entry=>{
return entry.includes(this.prefix);
}).map(entry=>{
return {
value: entry
};
})
);
}
}
var myCompleter2 = {
// identifierRegexps: [/[a-zA-Z_0-9\.\$\-\u00A2-\uFFFF]/],
getCompletions: function(editor, session, pos, prefix, callback) {
console.info("myCompleter prefix:", this.prefix);
callback(
null,
myList.filter(entry=>{
return entry.includes(this.prefix);
}).map(entry=>{
return {
value: entry
};
})
);
}
}
langTools.addCompleter(myCompleter1);
langTools.addCompleter(myCompleter2);```
You can check the text of the line in the completer to decide if it is after dot or not
var stringFunctions = ["Trim", "Length", "ToLower", "ToUpper", "ToNumber", "ToString"]
var mathFunctions = ["Abs", "Ceil", "Exp", "Floor", "Log", "ln", "Pow", "Round",
"Sqrt", "cos", "sin", "tan", "cosh", "sinh", "tanh", "acos", "asin", "atan",
"Max", "Min", "Sum", "Std", "Var", "Average", "Norm", "Median"
]
var myCompleter1 = {
getCompletions: function(editor, session, pos, prefix, callback) {
var line = session.getLine(pos.row)
var lineStart = line.slice(0, pos.column - prefix.length)
var myList = !/\.\s*$/.test(lineStart) ? mathFunctions : stringFunctions;
callback(null, myList.map(entry => {
return {
value: entry,
score: 1000
};
}));
}
}
var langTools = ace.require("ace/ext/language_tools")
langTools.addCompleter(myCompleter1);
var editor = ace.edit("editor", {
maxLines: 20,
minLines: 5,
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: false,
})
// automatically open popup after dot or word characters
var doLiveAutocomplete = function(e) {
var editor = e.editor;
var hasCompleter = editor.completer && editor.completer.activated;
if (e.command.name === "insertstring") {
// Only autocomplete if there's a prefix that can be matched
if (/[\w.]/.test(e.args)) {
editor.execCommand("startAutocomplete")
}
}
};
editor.commands.on('afterExec', doLiveAutocomplete);
<script src=https://ajaxorg.github.io/ace-builds/src-noconflict/ace.js></script>
<script src=https://ajaxorg.github.io/ace-builds/src-noconflict/ext-language_tools.js></script>
<div id=editor></div>

How to map column to complex object in SlickGrid

var data = [{"Id":40072,"Id2":40071,"SmDetails":{"Id1":40071,"Id2":40072}}]
I want to display SmDetails.Id1 in a column. How is this possible? I tried:
var columns = [{name:'Personnel',field:SmDetails.id1,id:'detailId'}];
Please help me
Please help me
**My latest code**
var data = [{"Id":40072,"Id2":40071,"allocationDetails":{"Id1":40071,"allocationDetails":{"accommodationId":4007}}}]
var grid;
var columns = [ {name:"Personnel",field:"allocationDetails",fieldIdx:'accommodationId', id:"accommodationId"}];
var options = {
enableCellNavigation: true,
enableColumnReorder: false,
dataItemColumnValueExtractor:
function getValue(item, column) {
var values = item[column.field];
if (column.fieldIdx !== undefined) {
return values && values[column.fieldIdx];
} else {
return values;
}}};
var gridData=$scope.Vo;//This return as json format
grid = new Slick.Grid("#testGrid",gridData, columns);
This is the code tried recently.
You'll need to provide a custom value extractor to tell the grid how to read your object.
var options = {
enableCellNavigation: true,
enableColumnReorder: false,
dataItemColumnValueExtractor:
// Get the item column value using a custom 'fieldIdx' column param
function getValue(item, column) {
var values = item[column.field];
if (column.fieldIdx !== undefined) {
return values && values[column.fieldIdx];
} else {
return values;
}
}
};
The column definitions would look like:
{
id: "field1",
name: "Id1",
field: "SmDetails",
fieldIdx: 'Id1'
}, {
id: "field2",
name: "Id2",
field: "SmDetails",
fieldIdx: 'Id2'
} //... etc
Check out this fiddle for a working example.
try this to convert your data into object of single length values ...
newData = {};
for(key in data[0]){
parentKey = key;
if(typeof(data[0][key]) == "object"){
childData = data[0][key];
for(key in childData){
childKey = key;
newKey = parentKey+childKey;
newData[newKey] = childData[childKey];
}
} else {
newData[key] = data[0][key];
}
}
This will convert your data object like this
newData = {Id: 40072, Id2: 40071, SmDetailsId1: 40071, SmDetailsId2: 40072};
Now use this newData to map your data items in grid
I find this works well for nested properties, eg:
var columns = [
{ id: "someId", name: "Col Name", field: "myRowData.myObj.myProp", width: 40}
..
];
var options {
...
dataItemColumnValueExtractor: function getItemColumnValue(item, column) {
var val = undefined;
try {
val = eval("item." + column.field);
} catch(e) {
// ignore
}
return val;
}
};

Kendo Treeview Expand Node

I have this treeview wich can have a variable number of children (some nodes can have up to 3 generations of children, some may have only one etc)
What I'm trying to do is expand a certain node when the treeview is loaded. And I have 2 problems:
1) I can't find an event/callback so that I know when the treeview is ready
2) The expand function doesn't always work ( I'll explain )
This is my treeview:
function InitializeTreeview() {
var Children_Merchants = {
transport: {
read: {
url: function (options) {
return kendo.format(websiteRootUrl + '/Merchants/Merchants/?hasParents={0}', hasParent);
}
}
},
schema: {
model: {
model: {
id: "ID",
hasChildren: true,
children: Children_Merchants
}
}
}
};
var Brandowners = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: kendo.format(websiteRootUrl + '/Merchants/GetBrandowners?databaseID={0}', selectedDatabaseID)
}
},
//change: ExpandNode, - if I call expand node like this, it works.
schema: {
model: {
id: "ID",
hasChildren: true,
children: Children_Merchants
}
}
});
$('#treeview').kendoTreeView({
dataSource: Brandowners,
animation: {
collapse: {
duration: 200,
effects: "fadeOut"
},
expand: {
duration: 200,
effects: "fadeIn"
}
},
dataTextField: "Name",
complete: function () { alert('ok'); },
//dataBound : ExpandNode,
select: OnSelect,
expand: CheckIfHasParent
}).data('kendoTreeView');
}
function ExpandNode() {
var treeview;
treeview = $("#treeview").data("kendoTreeView");
var nodeToExpand = treeview.findByText('Adam'); //dummy txt, will have from parameter
treeview.expand(nodeToExpand);
}
The databind works ok, my controllers get called, everything's fine.
So what I tried is hook up the ExpandNode function to a click of a button. The function gets called but nothing happens. BUT if I hook it up to the change event of the parents datasource, it works. Another interesting thing is that the select works so if I replace treeview.expand(...) with treeview.select(...), it works on the click.
So my questions are:
1) What event should I use for loadEnd ( or smth like that ) - so I won't have to bind the function to button click (it's still ok but I preffer on load ended) - P.S. I tried all the ones I found on the kendo forums,like: change, requestEnd, success, dataBound and they don't work. I tried sending the JSON with the property "expanded" set to TRUE, for the node in question, but that only modifies the arrow to show like it's opened, but it doesn't call the controller and load the children.
2) Do you know why ExpandNode works only when binded to the change event? - the most important question to me.
3) If you have suggestions, or have I done something wrong in the initialiation of the treeview, please tell me.
I've copied your code with some free interpretations and the answer your questions is:
What event should I use for loadEnd => dataBound
Do you know why ExpandNode works only when binded to the change event? => No, it works without binding it to change event. If it does not then there is something else in your code.
Suggestions => There is some information missing about your code that might make the difference with what I've implemented.
What is CheckIfHasParent? => I have implemented it as a function that actually does nothing.
What is hasParent? => I've ignored it.
The code as I write it:
$(document).ready(function () {
function InitializeTreeview() {
var Children_Merchants = {
transport: {
read: function (op) {
var id = op.data.ID;
var data = [];
for (var i = 0; i < 10; i++) {
var aux = id * 100 + i;
data.push({ Name: "Name-" + aux, ID: aux});
}
op.success(data);
}
},
schema : {
model: {
model: {
id : "ID",
hasChildren: true,
children : Children_Merchants
}
}
}
};
var Brandowners = new kendo.data.HierarchicalDataSource({
transport: {
read: function (op) {
op.success([
{"Name": "Adam", "ID": 1},
{"Name": "Benjamin", "ID": 2},
{"Name": "Caleb", "ID": 3},
{"Name": "Daniel", "ID": 4},
{"Name": "Ephraim", "ID": 5},
{"Name": "Frank", "ID": 6},
{"Name": "Gideon", "ID": 7}
])
}
},
//change: ExpandNode, - if I call expand node like this, it works.
schema : {
model: {
id : "ID",
hasChildren: true,
children : Children_Merchants
}
}
});
$('#treeview').kendoTreeView({
dataSource : Brandowners,
animation : {
collapse: {
duration: 200,
effects : "fadeOut"
},
expand : {
duration: 200,
effects : "fadeIn"
}
},
dataTextField: "Name",
dataBound : ExpandNode,
expand : CheckIfHasParent
}).data('kendoTreeView');
}
function ExpandNode() {
var treeview;
treeview = $("#treeview").data("kendoTreeView");
var nodeToExpand = treeview.findByText('Adam'); //dummy txt, will have from parameter
treeview.expand(nodeToExpand);
}
function CheckIfHasParent(e) {
}
InitializeTreeview();
});
and you can play with it here : http://jsfiddle.net/OnaBai/dSt2h/
$("#treeview").kendoTreeView({
animation: {
expand: true
},
dataSource: dataSource,
dataBound: function (e) {
var tv = $("#treeview").data("kendoTreeView");
if (tv != null) {
tv.expand(".k-item");
}
},
dataTextField: "test",
dataValueField: "id"
});
For anyone who may be interested:
function ExpandNode() {
var treeview;
var node1;
treeview = $("#treeview").data("kendoTreeView");
var node2;
var myURL = kendo.format(websiteRootUrl + '/Merchants/GetPathForSelectedNode?databaseID={0}&merchantID={1}&brandownerID={2}', selectedDatabaseID,MerID,BowID);
node1 = treeview.dataSource.get(BowID);
node = treeview.findByUid(node1.uid);
var uid = node1.uid;
node.find('span:first-child').trigger('click'); //expand 1st level
$.ajax( {
url: myURL,
dataType: "json",
contentType: 'application/json; charset=utf-8',
success: function(result)
{
var length = result.length;
var lastVal = 1;
for (var i = 1; i < length-1; i++) {
$("#treeview li[data-uid=\'" + uid + "\'] ul.k-group").waitUntilExists (function
() {
i = lastVal; // have to reinitialize i because waitUntilExist's callback will find the i incermented, over the needed value
lastVal++;
node2 = node1.children.get(result[i]);
node = treeview.findByUid(node2.uid);
uid = node2.uid;
node1 = node2;
if(lastVal <= length-1)
node.find('span:first-child').trigger('click'); // keep expanding
else
{
treeview.select(node); // just select last node
currentSelectedNode = node;
}
});
}
if(length == 2) //select 1st child
{
$("#treeview li[data-uid=\'" + uid + "\'] ul.k-group").waitUntilExists (function
() {
node2 = node1.children.get(result[i]);
node = treeview.findByUid(node2.uid);
uid = node2.uid;
node1 = node2;
treeview.select(node); // just select last node
currentSelectedNode = node;
});
}
}
});
}
This is my method. The for loop starts at 1 because the 1st element in my array is the 1st node ID - wich I've already expanded. the .waitUntilExists is Ryan Lester's method (I put a link in the comments above). Many thanks to my colleague, to you OnaBai and, of courese, to Ryan Lester. I hope this helps someone. Cheers
ypu can easily find the treeview is ready for expand by following code which are expanding all the treeview nodes you can also find it by checking perticular id or text
hopw, following example will help you
Ex:
$("#treeview").kendoTreeView({
animation: {
expand: true
},
dataSource: dataSource,
dataBound: function (e) {
var tv = $("#treeview").data("kendoTreeView");
if (tv != null) {
tv.expand(".k-item");
}
},
dataTextField: "test",
dataValueField: "id"
});

MVC3 jquery.datatables.editable not picking up non visible id column

I have a project where I want to inline edit a value in a table generated via DataTables and am therefore using dataTables.editable
The table is rendering fine but when I try and to sumit an edit I get an error and if I look at the return value the id field is blank.
The controller action is as follows:
public ActionResult AjaxHandler(jQueryDataTableParamModel param)
{
var allMonthlyCosts = _unitOfWork.MonthlyCostRepository.Get(includeProperties: "Period, Employee");
IEnumerable<MonthlyCost> filteredMonthlyCosts;
if (!string.IsNullOrEmpty(param.sSearch))
{
filteredMonthlyCosts = _unitOfWork.MonthlyCostRepository.Get(includeProperties: "Period, Employee")
.Where(mc => mc.Period.Name.Contains(param.sSearch)
||
mc.Employee.ClockNo.Contains(param.sSearch));
}
else
{
filteredMonthlyCosts = allMonthlyCosts;
}
var displayedMonthlyCosts = filteredMonthlyCosts
.Skip(param.iDisplayStart)
.Take(param.iDisplayLength);
var result = from mc in displayedMonthlyCosts
select new { ID = mc.Id, EvisionCost = mc.EvisionCost, EmployeeNo = mc.Employee.ClockNo, PeriodName = mc.Period.Name, TotalDays = mc.TotalDays, TotalCost = mc.TotalCost() };
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = allMonthlyCosts.Count(),
iTotalDisplayRecords = filteredMonthlyCosts.Count(),
aaData = result
},
JsonRequestBehavior.AllowGet);
}
The Javascript is as follows:
$('#myDataTable').dataTable({
"bServerSide": true,
"sAjaxSource": "MonthlyCost/AjaxHandler",
"bProcessing": true,
"aoColumns": [
{ "mData": "ID",
"bSearchable": false,
"bSortable": false,
"bVisible": false
},
{ "mData": "EvisionCost" },
{ "mData": "PeriodName" },
{ "mData": "EmployeeNo" },
{ "mData": "TotalDays" },
{ "mData": "TotalCost" }
]
}).makeEditable({
sUpdateURL: "/MonthlyCost/UpdateData",
"aoColumns": [
{},
null,
null,
null,
null]
});
The error I get is:
Cell cannot be #Updated(Server Error)
And the returned form is as follows:
value:2505
id:
rowId:0
columnPosition:0
columnId:1
columnName:EvisionCost
Issue is quite st.forward
Your editing is not reaching this plug-in code below . Thats why its throwing the error of your mention
CODE IN EDITABLE DATATABLE PLUGIN:
//Utility function used to apply editable plugin on table cells
function fnApplyEditable(aoNodes) {
var oDefaultEditableSettings = {
event: 'dblclick',
"callback": function (sValue, settings) {
properties.fnEndProcessingMode();
if (sNewCellValue == sValue) {
var aPos = oTable.fnGetPosition(this);
oTable.fnUpdate(sValue, aPos[0], aPos[2]);
} else {
var aPos = oTable.fnGetPosition(this);
oTable.fnUpdate(sOldValue, aPos[0], aPos[2]);
properties.fnShowError(sValue, "update");
}
},
"submitdata": function (value, settings) {
properties.fnStartProcessingMode();
sOldValue = value;
sNewCellValue = $("input,select", $(this)).val();
var id = fnGetCellID(this);
var rowId = oTable.fnGetPosition(this)[0];
var columnPosition = oTable.fnGetPosition(this)[1];
var columnId = oTable.fnGetPosition(this)[2];
var sColumnName = oTable.fnSettings().aoColumns[columnId].sName;
if (sColumnName == null || sColumnName == "")
sColumnName = oTable.fnSettings().aoColumns[columnId].sTitle;
return {
"id": id,
"rowId": rowId,
"columnPosition": columnPosition,
"columnId": columnId,
"columnName": sColumnName
};
},
"onerror": function () {
properties.fnEndProcessingMode();
properties.fnShowError("Cell cannot be updated(Server error)", "update");
},
"height": properties.height
};
This issue i am facing recently and i am trying like
<script type="text/javascript">
$(document).ready(function () {
$('#myDataTable').dataTable({ "bProcessing": true,
**"bServerSide": true,
"sAjaxSource": 'Home/AjaxHandler',
"sUpdateURL": '#Url.Action("UpdateData","Home")',
"sAddURL": '#Url.Action("AddData","Home")' ,
"sDeleteURL": '#Url.Action("DeleteData","Home")',**
"aoColumns": [
{ "sName": "ID",
"bSearchable": false,
"bSortable": false,
"bVisible": false
},
{ "sName": "Contact_Name" },
{ "sName": "Contact_Address" },
{ "sName": "Lead_Source" },
{ "sName": "Domain" },
]
}).makeEditable();
});
</script>
}
If this work please let me know . If you find any other way around do mention it . I am also in the same situation like you Finding answers
Regards

SlickGrid dropdown box editor not working

I have am trying to implement something along the lines of
Slickgrid, column with a drop down select list?
my code is;
slick.editors.js ;
(function ($) {
// register namespace
$.extend(true, window, {
"Slick": {
"Editors": {
"Text": TextEditor,
"Integer": IntegerEditor,
"Date": DateEditor,
"YesNoSelect": YesNoSelectEditor,
"Checkbox": CheckboxEditor,
"PercentComplete": PercentCompleteEditor,
"LongText": LongTextEditor,
"SelectOption": SelectCellEditor
}
}
});
with the function defined futher down,
function SelectCellEditor(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();
}
Then in my CSHTML
var columns = [
{ id: "color", name: "Color", field: "color", options: "Red,Green,Blue,Black,White", editor: Slick.Editors.SelectOption },
{ id: "lock", name: "Lock", field: "lock", options: "Locked,Unlocked", editor: Slick.Editors.SelectOption },
];
var options = {
enableCellNavigation: true,
enableColumnReorder: false
};
$(function () {
var data = [];
for (var i = 0; i < 20; i++) {
data[i] = {
color: "Red",
lock: "Locked"
};
}
the grid shows and the colour is shown as if its a regular text in a cell, but no dropdown?.
The drop-down will appear only when you are editing that cell. Adding editable: true to your grid options should work I think.

Resources