Kendo Grid using inline editing and custom editor dropdown control - javascript

I am trying to implement a custom editor for a column on a grid. The editor uses a DropdownList control.
I am able to get the Dropdown to show upon add/edit, however after making a selection and posting the json that is sent contains the default value, not the value that was selected.
My implementation is below it is an excerpt from a Razor page.
Can you help me figure out what I've done wrong here?
<div id="divGrid"></div>
<script>
$(document).ready(function () {
var dsGroupForm = new kendo.data.DataSource({
transport: {
read: {
url: '#Url.Action("GroupForm_Read", "Settings")',
dataType: "json"
},
update: {
url: '#Url.Action("GroupForm_Update", "Settings")',
dataType: "json"
},
destroy: {
url: '#Url.Action("GroupForm_Destroy", "Settings")',
dataType: "json"
},
create: {
url: '#Url.Action("GroupForm_Create", "Settings")',
dataType: "json"
}
},
batch: false,
pageSize: 5,
schema: {
data: "Data",
total: "Total",
errors: "Errors",
model: {
id: "GroupFormId",
fields: {
GroupFormId: { editable: false, nullable: false },
AdGroupId: { required: false },
AdGroupDisplayName: { validation: { required: true } },
FormKey: { validation: { required: true } },
Ordinal: { validation: { required: true } },
FormType: { validation: { required: false } },
FormTypeDisplay: { defaultValue: { FormTypeName: "Form1", FormTypeId: "1" } },
FormProjectionId: { validation: { required: false } }
}
}
}
});
$("#divGrid").kendoGrid({
autobind: true,
dataSource: dsGroupForm,
pageable: true,
height: 430,
toolbar: [{ name: "create", text: "Add"}],
columns: [
{field: "AdGroupDisplayName", title: "Group" },
{ field: "FormKey", title: "Key" },
{ field: "Ordinal", title: "Ordinal", format: "{0:d}", width: "100px" },
{ field: "FormTypeDisplay", title: "Type", width: "150px", editor: formTypeDropDownEditor, template: "#=FormTypeDisplay.FormTypeName#" },
{ field: "FormProjectionId", title: "ProjectionId" },
{ command: [{ name: "edit", text: "Edit" }, { name: "destroy", text: "Remove" }], title: " ", width: "172px" }
],
editable: "inline"
});
});
var formTypeData = new kendo.data.DataSource({
data: [
{ FormTypeName: "Form1", FormTypeId: "1" },
{ FormTypeName: "Form2", FormTypeId: "2" },
{ FormTypeName: "Form3", FormTypeId: "3" }
]
});
function formTypeDropDownEditor(container, options) {
$('<input name="FormTypeDisplay" required data-text-field="FormTypeName" data-value-field="FormTypeId" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: true,
dataTextField: "FormTypeName",
dataValueField: "FormTypeId",
dataSource: formTypeData
});
}
</script>

I was able to get it working using a MVC wrapper and by following this post:
http://www.sitereq.com/post/kendo-mvc-dropdown-lists-inside-inline-kendo-mvc-grids
The key was adding the save event due to a known Kendo grid bug - seems to me the Kendo docs should have some mention of this issue.
I tried implementing the same logic using the javascript implementation but could not get it working.

Try this
function formTypeDropDownEditor(container, options) {
$('<input name="' + options.field + '" required data-text-field="FormTypeName" data-value-field="FormTypeId" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: true,
dataTextField: "FormTypeName",
dataValueField: "FormTypeId",
dataSource: formTypeData
});
}

Related

Get selected dropdown value in inside kendo grid

Requirement: How to get selected drop down value in kendo grid while updating records
By using kendo editor i have implemented dropdown in grid column and i want to save datavaluefiled value
Datasource
ID:1,Interestname:cricket
Id:2,Interestname:football
while submiiting i need to save only value i:e Id
<html>
<head>
<title></title>
</head>
<body>
<div id="grid-container"></div>
#*Scripts*#
<script type="text/javascript">
$(document).ready(function () {
debugger
var gridDataSource = new kendo.data.DataSource({
transport: {
read: {
url: "/KendoGrid/GetStudents",
dataType: "json"
},
update: {
url: "/KendoGrid/CreateOrUpdate",
dataType: "json"
},
create: {
url: "/KendoGrid/CreateOrUpdate",
dataType: "json"
},
destroy: {
url: "/KendoGrid/DeleteDetails",
dataType: "json"
},
parameterMap: function (options, operation) {
debugger
if (operation !== "read" && options) {
return options;
}
}
},
pageSize: 5,
schema: {
model: {
id: "Id",
fields: {
Id: { editable: false, nullable: true },
Name: { editable: false, validation: { required: true } },
FatherName: { type: "text", validation: { required: true, min: 1 } },
DateOfBirth: { type: "date" },
Address: { type: "text", validation: { min: 0, required: true } },
Email: { type: "email", validation: { min: 0, required: true } },
Phone: { type: "text", validation: { min: 0, required: true } },
StudnetInterest: { type: "text", validation: { min: 0, required: true } }
}
},
parse: function (data) {
debugger
if (!data.success && typeof data.success !== 'undefined') {
//notifier.logixNotifier("notifyError", data.message);
gridDataSource.read();
}
if (data.success) {
//notifier.logixNotifier("notifySuccess", data.message);
gridDataSource.read();
}
return data;
}
}
});
$("#grid-container").kendoGrid({
dataSource: gridDataSource,
height: 550,
groupable: true,
sortable: true,
toolbar: ["create"],
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5,
},
columns: [
{
field: "Name",
title: "Name",
editable: false
},
{
field: "FatherName",
title: "Father Name",
},
{
field: "DateOfBirth",
title: "Date Of Birth",
format: "{0:MM/dd/yyyy}"
},
{
field: "Address",
title: "Address",
},
{
field: "Email",
title: "Email",
},
{
field: "Phone",
title: "Phone",
attributes: { hideMe: true }
},
{
field: "StudnetInterest",
title: "Student Interest",
editor: interestsDropdown,
values: interestsDropdown
},
{ command: ["edit", "destroy"], title: " ", width: "250px" }
],
// editable: "inline"
editable: "popup"
});
});
#*drop down Data Source*#
var dropDownDataSource = new kendo.data.DataSource({
transport: {
read: {
dataType: "json",
url: "/KendoGrid/GetInterest",
},
}
});
function interestsDropdown(container, options) {
debugger
$('<input required name="' + options.field + '" id="dropintrest" onchange="drop(this)"/>')
.appendTo(container)
.attr('data-bind', 'value:Id')
.kendoDropDownList({
autoBind: false,
dataTextField:"InterestName",
dataValueField:"Id",
dataSource: dropDownDataSource,
});
}
function drop(event) {
debugger
var data= $("#dropintrest").data("kendoDropDownList");
}
</script>
</body>
</html>
I think you may be binding to the wrong property on your model. Also, try setting the valuePrimitive property of your drop down list to true:
$('<input required data-bind="value:' + options.field + '" name="' + options.field + '" id="dropintrest" onchange="drop(this)"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataTextField:"InterestName",
dataValueField:"Id",
dataSource: dropDownDataSource,
valuePrimitive: true
});
According to the documentation:
If set to true, the View-Model field will be updated with the selected item value field. If set to false, the View-Model field will be updated with the selected item.
Hope this helps.

Kendo DropDownList in Grid not binding until after selection

I have an editable Kendo Grid, with a field that is a dropdownlist. I have a U_UserId and U_Name field that need to be used in that column. The name obviously displays, while the ID should be what is used for binding. I've removed my datasource URLs in the example below, but the DropDownList data displays just fine, with a list of Names and ID values.
I've been looking at this for a while so it's possible I'm missing something obvious. I'm having an identical problem to this question (the dropdown doesn't bind to the user displayed in that row until I click on the dropdown to expand it), but I think my model and fields are correct so I'm not sure why I still can't get the dropdown to bind correctly.
Here is my JS for both the grid and the editor:
$(document).ready(function () {
var grid = $("#grid").kendoGrid({
dataSource: {
type: "json-ajax",
transport: {
read: {
url: myUrl,
type: "GET"
}
},
batch: true,
pageSize: 20,
schema: {
data: "Data",
total: "Total",
model: {
id: "OrderId",
fields: {
O_OrderNumber: {
editable: false
},
O_Date: {
editable: false, type: "date"
},
O_InvoiceNumber: {
editable: false
},
O_Status: {
editable: false
},
O_DueDate: {
editable: false, type: "date"
},
U_UserId: {
editable: true
},
U_Name: {
editable: false
},
O_VendorId: {
editable: false
},
O_TrackingNumber: {
editable: false
}
}
}
},
},
scrollable: false,
editable: true,
pageable: true,
columns: [
{
field: "O_OrderNumber",
title: "Order #",
hidden: false
},
{
field: "O_Date",
title: "Pull Date",
hidden: false,
type: "date",
format: "{0:MM/dd/yyyy}"
},
{
field: "O_InvoiceNumber",
title: "Invoice #",
hidden: false
},
{
field: "O_Status",
title: "Status",
hidden: false
},
{
field: "O_DueDate",
title: "Due Date",
hidden: false,
type: "date",
format: "{0:MM/dd/yyyy}"
},
{
field: "U_UserId",
title: "Owner",
hidden: false,
width: 130,
editor: ownerDropDownEditor,
template: "#=U_Name#"
},
{
field: "O_VendorId",
title: "Vendor",
hidden: false
},
{
field: "O_TrackingNumber",
title: "Tracking #",
hidden: false
}
]
}).data("kendoGrid");
});
function ownerDropDownEditor(container, options) {
$('<input required name="' + options.field + '" />')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataTextField: "Name",
dataValueField: "UserId",
dataSource: {
type: "json",
transport: {
read: {
url: myOtherUrl,
type: "GET"
}
}
}
});
}
Edit: Out of curiosity, I tried changing my dropdownlist to have both the DataTextField and the DataValueField be UserId, and the selection was made right away, but with the ID (int) value being shown instead of the Name (string).
So investigating a little further into my edit above, I found this Telerik post, which made it sound like the dropdown actually binds by an object, and not by dropdown value. There is a data-value-primitive attribute that can be added so that it binds by value. I updated my editor, and it is now behaving as expected:
function ownerDropDownEditor(container, options) {
$('<input required name="' + options.field + '" data-value-primitive="true" />')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataTextField: "Name",
dataValueField: "UserId",
dataSource: {
type: "json",
transport: {
read: {
url: myOtherUrl,
type: "GET"
}
}
}
});
}

Selected kendo Dropdownlist value getting reset to previous selected value while performing batch operation in kendo ui grid

I have a kendo ui grid and I am doing batch operation on it. In one of the columns I populating data in kendo dropdownlist. While editing when I change value of that dropdown, it is getting changed at the moment but when I click outside of the row, old value comes back. How to keep teh selected value in dropdown?
here is my code:
var rateScheduleItemGridDatasource = new kendo.data.DataSource({
transport: {
read: {
type: 'get',
url: config.apiServer + "api/RateSchedule/GetAllRateScheduleItems?rateScheduleId=" + selectedRateScheduleId,
dataType: "json"
},
destroy: {
type: 'delete',
url: function (options) {
$.ajax({
url: config.apiServer + "api/RateSchedule/DeleteRateScheduleItem?rateScheduleItemId=" + options.RateScheduleItemId,
type: 'delete',
data: ko.toJSON(options),
contentType: "application/json",
success: function (data) {
popupNotification.show(updateSuccessMessage, "success");
rateScheduleItemGridDatasource.read();
},
error: function (jqXHR, textStatus, errorThrown) {
popupNotification.show(updateFailureMessage, "error");
}
});
},
dataType: "json",
contentType: "application/json"
}
},
pageSize: 10,
serverPaging: true,
serverSorting: true,
serverFiltering: true,
serverGrouping: true,
serverAggregates: true,
batch: true,
schema: {
data: "Data",
total: "Total",
errors: "Errors",
model: {
id: "RateScheduleItemId",
fields: {
RateScheduleItemId: { type: "number", editable: false, nullable: false },
RateScheduleId: { type: "number", editable: false, nullable: false, validation: { required: true } },
MathmetricalSymbolCode: { type: "number", nullable: true, editable: true, validation: { required: false } },
MathmetricalSymbolCodeValue: { type: "string", nullable: true, editable: true, validation: { required: false } },
MeasureTypeCode: { type: "number", nullable: true, editable: true, validation: { required: false } },
MeasureTypeCodeValue: { type: "string", nullable: true, editable: true, validation: { required: false } },
MultiplierRate: { type: "number", nullable: true, editable: true, validation: { required: false } },
RangeLowerNumber: { type: "number", nullable: true, editable: true, validation: { required: false } },
RangeUpperNumber: { type: "number", nullable: true, editable: true, validation: { required: false } },
RateTier: { type: "string", nullable: true, editable: false, validation: { required: false } }
}
}
}
});
$("#rateScheduleItemGrid")
.kendoGrid({
columns: [
{ "command": [{ name: "destroy", text: "&nbsp" }], "width": "60px" },
{ "title": "Rate Tier", "width": "100px", "field": "RateTier" },
{ "title": "Operand", "width": "100px", "field": "MathmetricalSymbolCode", "editor": rateScheduleItemOperandDropDownEditor, "template": "#= (MathmetricalSymbolCodeValue == null ) ? ' ' : MathmetricalSymbolCodeValue#" },
{ "title": "Range Type", "width": "100px", "field": "MeasureTypeCode", "editor": rateScheduleItemRangeTypeDropDownEditor, "template": "#= (MeasureTypeCodeValue == null) ? ' ' : MeasureTypeCodeValue#" },
{ "title": "Range (From)", "width": "100px", "field": "RangeLowerNumber" },
{ "title": "Range (to)", "width": "100px", "field": "RangeUpperNumber" },
{ "title": "Rate (Multiplier)", "width": "100px", "field": "MultiplierRate" }
],
toolbar: kendo.template($("#rateScheduleGridItemTemplate").html()),
resizable: true,
editable: true,
groupable: false,
filterable: true,
pageable: {
pageSize: 10,
pageSizes: [10, 50, 100, 150, 200, 250]
},
sortable: true,
height: 200,
dataSource: rateScheduleItemGridDatasource,
cancel: function (e) {
dirty = false;
},
save: function (e) {
dirty = false;
}
});
function rateScheduleItemOperandDropDownEditor(container, options) {
$('<input data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
dataTextField: "ReferenceValue",
dataValueField: "ReferenceValueId",
dataSource: rateScheduleItemOperandReferenceData,
optionLabel: "Select Operand"
});
}
function rateScheduleItemRangeTypeDropDownEditor(container, options) {
$('<input data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
dataTextField: "ReferenceValue",
dataValueField: "ReferenceValueId",
dataSource: rateScheduleItemRangeItemReferenceData,
optionLabel: "Select Range Type"
});
}
You are binding your columns to MathmetricalSymbolCode and MeasureTypeCode but you have based the templates on MathmetricalSymbolCodeValue and MeasureTypeCodeValue...BUT...you have nothing that actually sets the value of MathmetricalSymbolCodeValue and MeasureTypeCodeValue so they forever remain null.
When you make your selection in your dropdownlist, you are selecting the value for the "Code" fields not the "CodeValue" fields...the grid and dropdownlist have no idea that those are key-value pairs.
Here's an example with your setup(tweaked so I can run it without access to your data) where I have the Operand column working:
http://dojo.telerik.com/#Stephen/OCEpa
There are 2 important points:
using valuePrimitive: true on the DropDownList config, which is kind of required if the value is nullable(http://docs.telerik.com/kendo-ui/api/javascript/ui/dropdownlist#configuration-valuePrimitive)
After selecting the value in the dropdownlist(which returns the ID) you need to map that ID to the text you want to display in the cell somehow. The Kendo Grid provides the values for this purpose(http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#configuration-columns.values)
Another possible solution is instead of binding to the MathmetricalSymbolCode number field, bind the column to a complex object consisting of both the Code and the CodeValue fields with an appropriate column template...but that's more complicated(especially hooking up the dropdownlist) and I only do it when I have to.

How to set Kendo editor as cell template?

Requirement 1:
I need the user to the ability to edit content of the grid all the time, meaning as a template, the user should not be required click on the field and then the editor appears.
Requirement 2: I want a kendo editor for the user to enter/edit values.
The following is what I tried, since I don't know how to do this using template I tried out using editor
Grid setup:
dataSource: {
data: $scope.planOverviewModel,
sort: {
field: "TermName",
dir: "asc"
},
schema: {
model: {
fields: {
TermName: { type: "string", editable: false },
InNetwork: { type: "string", editable: true },
OutNetwork: { type: "string", editable: true }
}
}
},
},
columns: [
{ field: "TermName", title: "Term" },
{
field: "InNetwork",
title: "In-Network",
editor: $scope.setupTextBox
},
{
field: "OutNetwork",
title: "Out-Network",
editor: $scope.setupTextBox
}
],
editable: true,
change: function (e) {
console.log("changed");
if (e.action == "itemchange") {
this.sync();
}
}
Editor setup:
$scope.setupTextBox = function(container, options) {
$('<textarea class="form-control" type="text" data-bind="value:' + options.field + '"> </textarea>')
.appendTo(container).kendoEditor({
resizable: {
content: true,
toolbar: true
}
});
};

Saving column with custom editor gives nested column array

I am trying to use a dropdown select as an editor for one of my columns, defined as:
function phoneTypeEditor(container, options) {
$('<input required name="' + options.field + '" data-text-field="typeName" data-value-field="typeId" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataSource: [
{
"typeName": "Work",
"typeId": 1
},
{
"typeName": "Branch",
"typeId": 2
},
{
"typeName": "Home",
"typeId": 3
},
{
"typeName": "Mobile",
"typeId": 4
}
],
close: function()
{
}
});
}
In my model I have:
model: {
id: 'phoneId',
fields: {
phoneId: {
type: 'number'
},
type: {
type: 'string',
editable: true,
defaultValue: {
typeId: 1,
typeName: "Work"
},
},
tel: {
type: 'string',
editable: true
}
}
}
And finally my column:
{
field: 'typeId',
headerTemplate: '<b>Type</b>',
filterable: false,
editor: phoneTypeEditor,
width: '80px',
template: '#=typeName#'
},
But when I try to create a row in my grid my post data looks like this:
phoneId:0
type[typeId]:1
type[typeName]:Work
tel:
typeName:
contactId:97558
When it should be:
phoneId:0
typeId:1
typeName:Work
tel:
typeName:
contactId:97558
And I get a new row in my grid that is thin and empty.
How can I get this to work properly?
PS If I don't have:
typeName: {
type: 'string'
}
In my model I get an error saying typeName is not defined.
I now have:
model: {
id: 'phoneId',
fields: {
phoneId: {
type: 'number'
},
typeId: {
type: 'number',
defaultValue: 1
},
tel: {
type: 'string',
editable: true
},
typeName: {
type: 'string',
defaultValue: 'Work',
}
}
}
And...
columns: [
{
field: 'phoneId',
headerTemplate: '<b>Phone Id</b>',
filterable: false,
width: '50px',
hidden: true
},
{
field: 'typeId',
headerTemplate: '<b>Type</b>',
filterable: false,
editor: phoneTypeEditor,
width: '80px',
template: '#=typeName#'
},
{
field: 'tel',
headerTemplate: '<b>Number</b>',
filterable: false,
}
],
But now when I change the option in the dropdown, it appears that you haven't changed it but the actualy number id of the item has changed, just not the text. How do I make it so both the typeId and typeName change?

Categories