KendoUI - Read edited data from grid cells using underlying model - javascript

below i have a kendoUI grid that fetches data from a server. The user can then edit two columns in the grid. I have a separate button that will post the data back to the server and i do not use the kendo grid's UPDATE transport for this. The problem i am having is that if i fetch the data from the grid, it does not reflect the user inputs. For example, to get to the underlying data for the grid i do the following:
products= $("#Grid").data("kendoGrid").dataSource.data()
But when i iterate over products and check the NewPrice or Comment property, it's always blank. Here is how the grid's data source is defined:
dataSource: {
transport: {
read: function (options) {
$.ajax({
url: "/Portal/API/GetProductPrices?id=" + pId,
dataType: "json",
success: function (data) {
localModel.userId = data.userId;
localModel.products = data.Products;
return options.success(model.products);
},
});
}
},
},
scrollable: false,
selectable: true,
schema: {
model: {
id: 'Id',
fields: {
Item: { type: 'string', editable: false },
Price: { type: 'number', editable: false },
NewPrice: { type: 'number', editable: true },
Comment: { type: 'string', editable: true, validation: { required: true } },
}
}
},
columns: [
{ field: "Price", title:"Price"},
{
field: "NewPrice", title: "<span class='editMode'>Proposed Value</span>", format: "{0:p}", attributes: { style: "text-align:center;" }, headerAttributes: { style: "text-align:center;" }, width: "50px",
template: "#=NewValueTemplate(data)#",
},
{ field: "Comment", title: "<span class='editMode viewWorkflowMode'>Notes</span>", width: "210px", template: "#=NotesTemplate(data)#" },
]
Any advice in resolving would be appreciated

You haven't specified the editing type that you are using.
Which type are you using: inline, batch or popup ?
Is only this the datasource ? I see no update function.
I suggest you take a look at the three demos.
Batch
Inline
Popup
The worst thing is that you haven't specified the value of the property editable.
By default it is false, that means the kendoGrid is not editable, even if you have specified editable: true over your model fields.
Shortcut to "Editable" configuration
update #2 :
As already said here
If the data source is bound to a remote service (via the transport option) the data method will return the service response.
So, when you use dataSource.data() method on your grid, if you haven't updated correctly your datasource, you should receive all "old" data. (I found strange that you get blank value over those properties, maybe a cache problem)
As I already said, your dataSource doens't provide no update function.
Here you are an example about the configuration of the update function in kendo dataSource, with request to remote service.
Suggest you to look on both examples:
Example - specify update as a string and Example - specify update as a function

Please implement the logic from the following example:
var _roleDataSource = new kendo.data.DataSource({
data: [
{ id: 1, title: "Software Engineer" },
{ id: 2, title: "Quality Assurance Engineer" },
{ id: 3, title: "Team Lead" },
{ id: 4, title: "Manager" }
]
});
var _peopleDataSource = new kendo.data.DataSource({
data: [
{ id: 1, name: "John", roleId: 1, roleTitle: "Software Engineer" },
{ id: 2, name: "Dave", roleId: 2, roleTitle: "Quality Assurance Engineer" },
{ id: 3, name: "Aaron", roleId: 3, roleTitle: "Team Lead" },
{ id: 4, name: "Russell", roleId: 4, roleTitle: "Manager" }
]
});
var _grid = $("#grid").kendoGrid({
dataSource: _peopleDataSource,
columns: [
{
field: "name",
title: "Name"
},{
field: "roleTitle",
title: "Role",
editor: function(container, options) {
$("<input data-bind='value:roleTitle' />")
.attr("id", "ddl_roleTitle")
.appendTo(container)
.kendoDropDownList({
dataSource: _roleDataSource,
dataTextField: "title",
dataValueField: "title",
template: "<span data-id='${data.id}'>${data.title}</span>",
select: function(e) {
var id = e.item.find("span").attr("data-id");
var person =_grid.dataItem($(e.sender.element).closest("tr"));
person.roleId = id;
setTimeout(function() {
$("#log")
.prepend($("<div/>")
.text(
JSON.stringify(_grid.dataSource.data().toJSON())
).append("<br/><br/>")
);
});
}
});
}
}
],
editable: true
}).data("kendoGrid");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="grid"></div>
<br/>
<div id="log"></div>
You may view the demo here: http://jsfiddle.net/khNsE/175/

In this case, i needed to allow some rows based on data rules to enter 'edit mode' at the same time, so specifying inline, popup, etc was not an option. What i did instead was use a custom template function when defining the grid columns. the custom template function returned html, but in the html i used the data-bind attribute to bind to my model. Finally on the DataBound event of the grid, i bind my model to the rows.
field: "NewPrice", title: "New", format: "{0:p}", template: "#=newValueTemplate(d)#",
....
....
function newValueTemplate(d){
if (d.IsEditable)
return "<input type='number' data-bind='value:NewPrice' />"
else
return "<span />"
}
function gridDataBound(e){
var items = this.dataSource.view();
var gridRows = this.tbody.children();
for (var i = 0; i < items.length; i++)
kendo.bind(gridRows[i], items[i]);
}

Related

What is Dojo treegrid expand/collapse event?

I have a very large treeGrid (~2000 elements in one node). And it seems to be frozen when I click [+] to expand it. I want to change mouse cursor state to 'wait' once clicked, but then to 'default' once expanded. Assume I can put it in onRowClick or onOpen event but what is onComplete event where I can reset the cursor? Also is there a way/property to see if row is expanded or collapsed? I want to change its style then.
var layout = [
{
cells: [
[
{ field: "userid", name: "User Id" },
{
field: "childItems",
children: [
{ field: "unid", name: "unid" },
{ field: "username", name: "User Name" },
{ field: "budget", name: "Budget" }
],
aggregate: "sum"
}
]
]
}
]
var jsonStore = new dojo.data.ItemFileWriteStore({ url: <...............>});
var grid = new dojox.grid.TreeGrid(
{
structure: layout,
store: jsonStore,
query: { type: 'userid' },
queryOptions: { deep: true },
rowSelector: true,
openAtLevels: [false],
autoWidth: true,
autoHeight: true,
onRowClick: function (evt) {
var idx = evt.rowIndex,
item = this.getItem(idx);
// ??????
}
},
dojo.byId("treeGrid")
);

Editable hierarchical grid in Kendo UI

I wish to create a grid that each row has grid inside it.
Both grids need to be editable and I managed to do so. However, when I try to add a new row to the outer grid, all the data inside it gone.
You can find the demo here: http://dojo.telerik.com/UqURE
Can you please help with this issue?
Thanks!
var outerDataSource= new kendo.data.DataSource({
schema: {
model: {
field1: { type: "string", validation: { required: true } },
field2: { type: "boolean", validation: { required: true } },
field3: { type: "string", validation: { required: true } }
}
}
});
$("#outerGrid").kendoGrid({
dataSource: outerDataSource,
detailInit: onExpansion,
toolbar: ["create"],
columns: [
{ field: "field1", title: "field1" },
{ field: "field2", title: "field2" },
{ field: "field3", title: "field3" },
{ command: ["destroy"], title: " " }],
editable: true
});
function onExpansion(e) {
var insideDataSource= new kendo.data.DataSource({
schema: {
model: {
in1: { type: "string", validation: { required: true } },
in2: { type: "string", validation: { required: true } }
}
},
data: [{
in1: "Click to edit",
in2: "Click to edit"
}]
});
var headers = $("<div/>").appendTo(e.detailCell).kendoGrid({
dataSource: insideDataSource,
width: 90,
toolbar: ["create"],
editable: true,
columns: [
{ field: "in1" },
{ field: "in2" },
{ command: ["destroy"], title: " " }]
});
};
Answer from Telerik:
Please note that operations like paging, sorting, filtering and
editing cause the Grid to rebind and reevaluate all templates inside
it (including the details). That why in order to preserve the child
Grid data between rebinds you should either save it to remove service
(link to documentation here) or add it as navigation property
collection to the parent Grid model (demo is available here).
http://www.telerik.com/forums/hirarchialy-editable-grids

Kendo Grid: How to sort (and filter) a column bound to a simple json object

I have seen a number of questions on sorting, but I couldn't find any for my very simple case.
I have taken the online example (where if I add the sortable and filterable, they don't work on the category field either), and modified it very slightly, just to use very simple local json data (to make it eaier to see what I am working with while learning the grid.
So, looking at the category field I want to sort and filter, in my columns definition I have ....
columns: [
{
...
{
field: "Category",
title: "Category",
width: "180px",
editor: categoryDropDownEditor,
template: "#=Category.description#"
},
and in the data source, the category field consists on s simple json object with 2 fields code and description (where code it to be the value field, and description is what to display) ...
var gridData = [
{
....
ProductID : 1,
ProductName : "Chai",
Category : {
code : '1',
description : "Beverages",
},
...
];
I have added the sortable, and filterable properties to the grid however the category field show the sort arrows (which toggle when clicked), but the column data does not sort or filter.
How do I will the sort and filter to look at the description field to carry out these operations?
Note I also have a combo cell editor attached
function createCombo(container, options, data) {
var input = $('<input name="' + options.field + '" />')
input.appendTo(container)
var combobox = input.kendoComboBox({
autoBind: true,
filter: "contains",
placeholder: "select...",
suggest: true,
dataTextField: "description",
dataValueField: "code",
dataSource: data,
});
where the data is of form
[
{code: 'code1', description: 'desc1'},
{code: 'code2', description: 'desc2'},
]
So I would need the combo to also populate the field with the correct value.
Thanks in advance for any help!
<script>
var gridData = [
{
ProductID: 1,
ProductName: "Chai",
Category: {
code: '1',
description: "beverages",
}
},
{
ProductID: 1,
ProductName: "bhai",
Category: {
code: '1',
description: "aceverages",
}
},
{
ProductID: 1,
ProductName: "dhai",
Category: {
code: '1',
description: "zeverages",
}
}
];
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: gridData,
height: 550,
groupable: true,
sortable: true,
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
columns: [{
field: "ProductID",
title: "Contact Name",
width: 200
}, {
field: "ProductName",
title: "Contact Title"
}, {
field: "Category.description",
title: "Category",
width: "180px",
template: "#=Category.description#"
}]
});
});
</script>

kendo UI grid update function wont fire

$('#usersGrid').kendoGrid({
columns: [
{ field: "UserName", title: "Display name", width: "140px" },
{ field: "Unit", title: "Unit", width: "140px" },
{ field: "Email", title: "E-mail", width: "140px" },
{ field: "Indienst", title: "Indienst", width: "140px" },
{ field: "Uitdienst", title: "Uitdienst", width: "140px" },
{ field: "Roles", title: "Roles" },
{ command: { text: "edit", click: openEdit } }
],
editable: {
update: true,
create: true
},
dataSource: {
transport: {
read: function (options) {
$.ajax({
url: "/Administration/GetUserList",
dataType: "json",
data: {
indienst: function () {
return indienst;
}
},
success: function (data) {
$("#usersGrid").data('kendoGrid').dataSource.data(data);
}
});
},
update: function (options) {
alert('not firing');
}
}
},
schema: {
model: {
id: "UserId",
fields: {
UserId: { editable: false, type: "int" },
UserName: { type: "string" },
Unit: { editable: false, type: "string" },
Email: { type: "string" },
Indienst: { type: "string" },
Uitdienst: { type: "string" },
Roles: { editable: false, type: "string" }
}
}
}
});
This is my kendo UI grid. It's reading fine, but the problem is that it wont fire the datasource.transport.update call when I change a grid cell inline. Why won't it?
I've made sure I specified an id column and that the transport CRUD functions are all of the same type (functions here, not urls), but I've tried to have it work with urls as well. Only transport.read will fire...
when I check the console logs there are no errors given.
So I want to edit it inline. Click on a cell on the grid, and change the value, when u leave focus of the cell I want dataSource.transport.update() to run, or any function at all.
http://jsfiddle.net/8tzgc/135/
Edit:
After doing some research on the docs I've found out about the change() event. By checking what kind of change event it is we can figure out if its an update event and run the function we want ourselves. Here's my updated jsfiddle:
http://jsfiddle.net/8tzgc/140/
If anyone figures out a way that does not require calling the update function yourself, then I'm all ears.
To edit inline, you can just leverage the example from the telerik demo site.
Change your command column to:
{ command: ["edit", "destroy"], title: " ", width: "160px" }
And change your editable specification to "inline":
editable: "inline",
I have edited your fiddle with the solution: http://jsfiddle.net/8tzgc/136/
In order to fully flesh this out, you would have to provide implementation for the associated methods from the command, such as update, create, etc... You can see those examples in the telerik demo.
If you would like to do cell-click editing with custom editors (dropdowns, etc), here is another telerik example.
There is also this example of batch editing.
try to change
command: { text: "edit", click: openEdit }
to
command: ["edit"]
If you are using editable:popup then try the following:
command: [
{ name: "view", template: "<a class='k-button k-button-icontext selectDiscountPercentage' title='Discount Percentage' ><i class='k-icon k-i-view'></i></a>", text: "", },
{ name: "edit", text: "" },
{ name: "destroy", text: " "}
], title: " ", width: "160px"
The trick here is to give empty space(" ") to the text key inside command array

Kendo DropDownList in Grid shows value after selection

I'm trying to use a drop-down list in my grid. This is my grid definition:
$("#grid").kendoGrid({
editable: true,
dataSource: {
data: data,
schema: {
model: {
fields: {
Name: {
type: "string",
editable: false
},
FruitName: {
type: "string"
},
FruitID: {
type: "number"
}
}
}
}
},
columns: [{
field: "Name",
title: "Name",
width: 150
}, {
field: "Fruit",
title: "Fruit",
width: 115,
editor: renderDropDown,
template: "#=FruitName#"
}]
});
And this is my editor function:
function renderDropDown(container, options) {
var dataSource = [
//{ name: "", id: null },
{
FruitName: "Apple",
FruitID: 1
}, {
FruitName: "Orange",
FruitID: 2
}, {
FruitName: "Peaches",
FruitID: 3
}, {
FruitName: "Pears",
FruitID: 4
}];
$('<input required name="' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
dataTextField: "FruitName",
dataValueField: "FruitID",
dataSource: dataSource
});
}
Here's a demo on JSBin for illustration: http://jsbin.com/malev/3/edit
Mine is a 2 part question.
Why isn't the dropdown in this sample defaulting to the value in the column before it's edited?
Why is the text switching to the value after the selection is made?
Take a look at your column definition:
{
field: "Fruit",
title: "Fruit",
width: 115,
editor: renderDropDown,
template: "#=FruitName#"
}
Your field name is Fruit. In the editor, you bind to this field name, but your schema model and your data only have a FruitID property. This explains why the dropdown doesn't have show the initial value correctly.
The other problem is that, if you need to update two properties on your model from the editor, you need to do that manually, e.g. by setting up your editor like this:
$('<input required name="' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
dataTextField: "FruitName",
dataValueField: "FruitID",
dataSource: dataSource,
change: function (e) {
var dataItem = e.sender.dataItem();
options.model.set("FruitName", dataItem.FruitName);
}
});
The alternative would be to have a lookup function that gives you the display text for a given value, e.g.:
var fruitNames = ["", "Apple", "Orange", "Peaches", "Pears"];
function getFruitName(value) {
return fruitNames[value];
}
Then you could use this in your template:
template: "#= getFruitName(FruitID) #"
and you wouldn't need the separate column for the name and the change handler in your editor.
(updated demo)

Categories

Resources