What is the perfect meaning of editor and template in kendo grid
columns: [{
field: "CategoryId",
title: "#T("Admin.Catalog.Products.Categories.Fields.Category")",
width: 200,
editor: categoryDropDownEditor,
template: "#:Category#"
}]
With the editor property you can specify a function that is called when editing the cell (of course, the grid must be set to 'editable:true')
The function could look like this:
function numberEditor(container, options) {
$('<input name="' + options.field + '"/>')
.appendTo(container)
.kendoNumericTextBox({
decimals: 0,
step : 1,
min : 0
});
}
So when editing a cell, a NumericTextBox is shown which in this case only allows positive (min:0) integers (decimal:0). In general you can define how the cell can be edited.
The template defines how the value is displayed.In your case the value is just shown as it is.
You could for example add some html:
template: "<b>#:Category#</b>" // Display bold text
template: "#:Category#" // Display as link
The #:Category# accesses the data field with that name. You can also use multiple fields in one column:
template: "#:Category# / #:SomethingElse#"
this follows in from another post to do with setting a grid's selected fields when we have a data source field (and combo fields) with a json object (as opposed to a simple string).
So if we look at the change event handler for the following combox...
function createCombo(container, options, data) {
var input = $('<input name="' + options.field + '" />')
input.appendTo(container)
input.kendoComboBox({
autoBind: true,
filter: "contains",
placeholder: "select...",
suggest: true,
dataTextField: "display",
dataValueField: "rego",
dataSource: data,
change: function () {
var dataItem = this.dataItem();
var dataField = options.field.split('.');
var fieldName = dataField[0];
options.model.set(fieldName + '.rego', dataItem.rego);
options.model.set(fieldName + '.display', dataItem.display);
}
});
}
I am setting my 2 fields as follows...
options.model.set(fieldName + '.rego', dataItem.rego);
options.model.set(fieldName + '.display', dataItem.display);
(each item in the combo, and the grid data source has a json object with a 'rego' and 'display' field, see full example here.
This seemed to work exactly as I wanted, but I had just had someone point out to me that when you scroll the combobox with the up/down arrow keys, it just seems to toggle between 2 values in the list, as opposed to iterating through all the items. If I remove the 2 'options.model.set' statements, the combo then behaves.
I am really hoping there is a work around this, but everything I Have tried makes no different.
If there were any suggestion to finish this off, it would be greatly appreciated!
Thanks in advance for any help
Since you're modifying the model manually, you should to remove the name=... attribute from the input (otherwise the grid will also modify the model; you could also use name="car.rego" - it has to be the value field - and then not set the combobox value in the config) and also only call set for the last change you make on the model (otherwise, the grid's save event will get triggered twice, once with invalid data).
So you editor would look like this:
function createCombo(container, options, data) {
var dataField = options.field.split('.');
var fieldName = dataField[0];
var input = $('<input/>')
input.appendTo(container)
input.kendoComboBox({
autoBind: true,
filter: "contains",
placeholder: "select...",
suggest: true,
dataTextField: "display",
dataValueField: "rego",
dataSource: data,
value: options.model[fieldName].rego,
change: function (e) {
var dataItem = this.dataItem();
options.model[fieldName]['rego'] = dataItem.rego;
options.model.set(fieldName + '.display', dataItem.display);
}
});
}
Also, your data should be consistent (in one DS, you use "C1" as rego, in the other "CAR1").
(demo)
I'm trying to set the values for an multiselect editor, as in:
http://dojo.telerik.com/oneGE
But when I implement same in a Kendoui Grid custom editor the value setting is ignored.
The editor is setup in the grid declaration as a function:
$("#rocongrid").kendoGrid({<br/>
....
editor : function (container,options) {
$('<select multiple="multiple" data-bind="value:' + options.field + '"/>')
.appendTo(container).kendoMultiSelect({
dataTextField: "genre",
dataValueField: "genre",
dataSource: GenreDS,
value: [ "Classical" ]
});
}
},
The "Classical" item is set fine in the dojo sample, but in the Grid Edit mode it does not. Is there something I am not implementing in the custom editor?
There are a couple of questions that you need to consider when implementing multiselect in a Grid.
Values are not going to be a single value but an array of values so you need to implement some way for displaying it as (for example) comma separated values.
if you use data-bind="value:' + options.field + '" then this will overwrite value: [ "Classical" ]. Actually the later does not make sense since what you want is initially showing the values that are already stored in the Grid DataSource
I have a grid/detail grid set up. On the detail grid, I have a drop down list. The editor function for the drop down is:
function ActionTypeEditor(container, options) {
$('<input id="ddlActionType" data-text-field="name" data-value-field="id"> data-bind="value:' + options.field + '" ').appendTo(container).kendoDropDownList({
dataTextField: "name",
dataValueField: "id",
autoBind: false,
dataSource: GC.ViewModels.Config.AlertAction.actionTypeArray
}).appendTo(container).data("kendoDropDownList").text(options.model.ActionTypeId);
var dropdownlist = $("#ddlActionType").data("kendoDropDownList");
dropdownlist.value(options.model.ActionTypeId);
}
This works fine when I edit one row on a detail grid associated with the "parent" grid row. However, if I edit another detail row associated with another parent row BELOW the first, the next to last stamement
where I select the dropdown list always gets the first one on the page, rather than the one for the lower row. How do I get the correct drop
down list?
Why, you use
var dropdownlist = $(container.find("#ddlActionType")).data("kendoDropDownList");
instead.
You're welcome!
While both autocomplete and select in jqgrid editform place the selected label into the cell, select will place the value (id) in the postdata array where autocomplete will place the label into the postdata array.
is there a way to get the editoption's autocomplete to post the item value (id) instead of the label?
here is the jqgrid code segment i'm using autocomplete in...
$('#tab3-grid').jqGrid({
colNames:['Workorder', 'wo.CUID',.....],
colModel:[
.
.
.
{name:'wo.CUID', index:'cu.LastName', width:120, fixed:true, align:'center', sortable:true, editable:true, edittype:'text',
editoptions:{dataInit:function(el){$(el).autocomplete({ source: 'php/customer-ac-script.php'
, minLength: 1
})
}
},
formoptions:{rowpos: 1, label:'Customer', elmprefix:'* '},
editrules:{required:true}
},
.
.
.
$('#tab3-grid').jqGrid('navGrid', '#tab3-pager',
{view:true, closeOnEscape:true, cloneToTop:true}, // general parameters that apply to all navigation options below.
{jqModal:true, navkeys:[true,38,40], savekey:[true,13]}, // edit options.
{jqModal:true, navkeys:[true,38,40], savekey:[true,13], reloadAfterSubmit:false, afterSubmit: addRecordID}, // add options.
{jqModal:true, afterSubmit: serverMessage}, // del options.
{jqModal:true}, // search options.
{jqModal:true, navkeys:[true,38,40]} // view options.
);
The php code segment:
// construct autocomplete select.
$i = 0;
while($row = mysql_fetch_assoc($result)) {
$output[$i][$crudConfig['id']] = $row['CUID'];
$output[$i][$crudConfig['value']] = $row['LastName'];
logMsg(__LINE__,'I','cu.CUID: '.$row['CUID'].', cu.LastName: '.$row['LastName']);
$i++;
}
// encode to json format and send output back to jqGrid table.
echo json_encode($output);
logMsg(__LINE__,'I','Send json output back to jqGrid table: '.json_encode($output));
Would it be as simple as calling a function under the autocomplete select event or the grid before or after editform submit?
Also, i noticed this note in the jqgrid doc's for datainit: that says...
Note: Some plugins require the position of the element in the DOM and
since this event is raised before inserting the element into the DOM
you can use a setTimeout function to accomplish the desired action.
Would the lack of including the settimeout function be causing the problem?
The server code which provide the JSON response on the autocomplete request has id and value properties. On the other side the standard behavior of jQuery UI Autocomplete is to use label and value properties (see "Datamodel" in the documentation). The value of label property (if any exist) will be used to display in the contextmenu. The value of value property will be placed in the <input> field after the user choose the item from the contextmenu. The value of label property can has HTML markup, but the value of value property must be the text.
So I see the problem as pure problem of the usage of jQuery UI Autocomplete independent on jqGrid. If I understand correct your question you can solve your problem by modification your server side code.
Oleg's answer clarifying the data model for jquery UI's autocomplete, has allowed me to move forward and understand that autocomplete has nothing to do with constructing and sending the postdata array to the server, jqgrid's editform handles it. With that knowledge, i was able to answer my original question and successfully integrate autocomplete into jqgrid. So, in the interest of sharing, i'd like to show you all my motivation and solution.
By default, selecting a label from the autocomplete list put's the value of the selected label/value pair into the text box. All the editform cares about when you submit is what's in the edit fields. So when you submit the editform, the cell's postdata element value will again contain the value of the autocomplete text box. But what if while wanting to post the value of the label/value pair, you want the label of the label/value pair displayed in the text box? You have a problem! How do you get the value of the label/value pair posted to the server?
Well, after spending a few days on it, it turns out to be quite simply. While i'm sure there is more than one solution, here is mine:
add a hidden id column in the grid
define the select: and focus: events in the autocomplete function
in the select: function; insert the selected label into the text box (optional), disable the default behavior of autocomplete, then set the cell of the hidden column to the value of the selected label/value pair
in the focus: function; insert the selected label into the text box(optional), disable the default behavior of autocomplete
add an "onclickSubmit:" event to the navgrid edit options with function name something like "fixpostdata"
in the "fixpostdata" function; get the cell value of the hidden column and insert it into the postdata element associated with the cell.
The following are the grid and javascript code segments i used…
grid segments
{name:'wo_CUID', index:'wo_CUID', width: 70, hidden: true},
{name:'wo.CUID', index:'cu.LastName', width:120, sortable:true, editable:true, edittype:'text',
editoptions:{
dataInit:function(el){ // el contains the id of the edit form input text box.
$(el).autocomplete({
source: 'php/customer-ac-script.php',
minLength: 1,
select: function(event, ui){event.preventDefault();
$(el).val(ui.item.label);
var rowid = $('#tab3-grid').getGridParam('selrow');
// set the hidden wo_CUID cell with selected value of the selected label.
$('#tab3-grid').jqGrid('setCell', rowid,'wo_CUID',ui.item.value);},
focus: function(event, ui) {event.preventDefault();
$(el).val(ui.item.label);}
})
}
},
formoptions:{rowpos: 1, label:'Customer', elmprefix:'* '},
editrules:{required:true}
},
.
.
$('#tab3-grid').jqGrid('navGrid', '#tab3-pager',
{view:true, closeOnEscape:true, cloneToTop:true},
{jqModal:true, navkeys:[false,38,40], onclickSubmit: fixpostdata}, // edit options.
.
.
javascript function
// define handler function for 'onclickSubmit' event.
var fixpostdata = function(params, postdata){
var rowid = $('#tab3-grid').getGridParam('selrow');
var value = $('#tab3-grid').jqGrid('getCell', rowid,'wo_CUID');
postdata['wo.CUID'] = value;
return;
}
The fixpostdata function fires when you submit the editform but befor the postdata array is sent to the server. At this point you replace the cell's postdata element value with whatever you want. In this case, the value of the label/value pair stored in the hidden column cell. When the function returns, the modified postdata array is sent to the server.
Done!