Is it possible to access and modify data in Kendo UI grid before updating?
Below is an example to illustrate what I need. The options.data contains the sent data but it is already formatted in string "models=%B7%22Id22%.... etc" not really convenient form.
dataSource = new kendo.data.DataSource({
transport: {
read: {
...
},
update: {
url: baseURL + "update",
beforeSend: function(xhr, options){
xhr.setRequestHeader('API-KEY', apikey );
var modifiedData = doSomething(options.data);
return modifiedData;
},
dataType: "json",
method: "POST",
dataFilter: function(data){
... some data recieved modification
return JSON.stringify(somedata);
},
complete: function(e) {
....
}
},
You should be able to use the parameterMap function, check the type for "update" and change the options.data anyway you want.
parameterMap: function(options, type) {
if(type === "update") {
options.someProperty = "somenewvalue";
}
return kendo.data.transports.odata.parameterMap(options, type);
}
Related
Have a Kendo Read Call from JQuery as follows:
var dataSource = new kendo.data.DataSource({
error: function (e) {
if (e.status === "error") {
this.cancelChanges();
showToast("Error Occurred", e.xhr.responseText, "exclamation-circle", "red");
var grid = $('#grid').data('kendoGrid');
grid.dataSource._data = self.formatData(grid.dataSource.data());
grid.refresh();
}
},
requestEnd: onRequestEnd,
transport: {
read: {
type: "GET",
dataType: "json",
url: '/api/user/getall'
},
destroy: {
url: function (data) {
return "api/user/delete/" + data.RecordKey;
},
type: "delete",
dataType: "json"
},
parameterMap: function (data, operation) {
return kendo.stringify(data);
}
},
The server determines user unauthorized and returns the following Content
...
return new ContentResult()
{
StatusCode = 401,
Content = "No Access"
};
...
The errors blodk in the in the datasource does not fire? Not sure what I am missing.
Seems like the issue is with the parameterMap definition, specifically when the function is executed on a read operation
parameterMap: function (data, operation) {
if (operation != "read") {
return kendo.stringify(data);
}
}
With the above update and a mock 401 response the error event fires as expected - example.
Found my issue I had an error begin throw in my requestEnd block. Corrected that and error is firing.
In my kendo dataSource > transport > update. I want to catch a server response status (refer image), but none of this methods trigger an alert. Any idea why?
update: {
url: "./getRevenueAccounts.php",
type: "POST",
data: function() {
return {
method: "editRevenueAccounts"
}
},
success: function(e) {
if(e.status == 'duplicate'){
alert('Trigger 1');
}
},
error: function(e) {
if (e.errorThrown == 'duplicate') {
alert("Trigger 2");
}else if(e.status == 'duplicate' ){
alert("Trigger 3")
}
},
complete: function (e) {
if(e.status == 'duplicate'){
alert('Trigger 4');
}
}
},
console.log(e) screen shot
Try the following code for your success function:
success: function(e) {
if(e.responseText.status == 'duplicate'){
alert('Trigger 1');
}
},
Essentially, you are looking at the status property when you should have been looking at the responseText property to get the status (which is another property on that object).
You need to make an ajax call inside the update function.
Like:
var dataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
/* implementation omitted for brevity */
},
update: function(options) {
// make JSONP request to https://demos.telerik.com/kendo-ui/service/products/update
$.ajax({
url: "https://demos.telerik.com/kendo-ui/service/products/update",
dataType: "jsonp", // "jsonp" is required for cross-domain requests; use "json" for same-domain requests
// send the updated data items as the "models" service parameter encoded in JSON
data: {
models: kendo.stringify(options.data.models)
},
success: function(result) {
// notify the data source that the request succeeded
options.success(result);
},
error: function(result) {
// notify the data source that the request failed
options.error(result);
}
});
}
},
batch: true,
schema: {
model: { id: "ProductID" }
}
});
For more details please check this from telerik documentation: https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/configuration/transport.update
Is not a good method to apply, but it works to fetch the response.
if(e.responseText=='{"status":"duplicate"}'){
kendo.alert('duplicate data');
}
I am creating a CRUD application, My application is getting a string from from a Kendo input box, and will need to send it to my controller which is expecting a string that I am getting from my Jquery call. However, the string is not getting to my controller. I have tried various ways and I am not able to send it through my Transport. I have put break point and I can confirm that the value is being picked up in my Kendo Observable.
My Datasource
var client = new kendo.data.DataSource({
transport: {
read: {
url: "Client/SearchClient",
contentType: "application/json; charset=utf-8",
dataType: "json",
},
My Controller
public ActionResult SearchClient()
{
return View();
}
[HttpPost]
public ActionResult SearchClient(string name)
{
Repo repo = new Repo();
var result = repo.GetClient();
return Json(new
{
list = result,
count = result.Count
}, JsonRequestBehavior.AllowGet);
}
This is my Kendo Observable
var viewModel = kendo.observable({
client: {
clientName: "",
clientNumber: "",
clientType: "",
},
dropdownlist: ["HCC", "Tax", "Audit", "Advisory"],
create: function (e) {
var userRequest = $("#clientname").val();
if (userRequest) {
client.read(userRequest);
}
if (!userRequest)
alert("Please Enter Client Name")
}
});
Search Client method wants POST, not GET? The default will be GET. Either change your api method to use HttpGet, or change the transport to method: "post" for read.
var client = new kendo.data.DataSource({
transport: {
read: {
url: "Client/SearchClient",
contentType: "application/json; charset=utf-8",
dataType: "json",
method: "post"
},
can i check what is new data on sync?
i have this:
$('#order_it').click(function(){
gridNewData.sync(); // this will send data to server
});
gridNewData complete:
complete: function(xhr, textStatus) {
if (textStatus == 'success') {
orders.read(); // this will refresh orders, and grid too, a
gridNewData.data([]); // empty that temp datasource
}
}
and:
var orders = new kendo.data.DataSource({
autoSync: false,
transport: {
read: {
contentType: 'application/json',
url: '/dokument/orders/',
dataType: 'json',
complete: function(xhr, textStatus) {
// i think that here i need to get new synced items(or uids)
}
}
},
schema: {
model: {
id: 'id'
}
}
});
I need to make that rows in grid with another color, but can't find way to check what is new data.
You will not get new uid's neither the items. What you can do is to iterate through the collection of data before you call sync() and search for "isdirty".
I am using the Data Source object to connect to a SharePoint 2013 ODATA source using REST and then use this as the data for a Kendo UI Grid.
The Data Source reads the list correctly and populates the grid, but when I update an item in the Kendo UI Grid the following error is returned by the REST end point.
The property '__deferred' does not exist on type 'SP.SecurableObject'.
Make sure to only use property names that are defined by the type.
This is caused by the Data Source returning all the properties from the initial read request and then returning in the update command.
SharePoint returns __deferred properties with a REST URL to defer loading, but is throwing a wobbly if they are returned back in an update command request.
Below is my Data Source
var dataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read: {
url: listUrl,
type: "GET",
dataType: "json",
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose"
}
},
create: {
url: listUrl,
type: "POST",
dataType: "json",
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
}
},
update: {
url: function (data) {
return listUrl + "(" + data.ID + ")";
},
beforeSend: function (jqXhr, options) {
var data = JSON.parse(options.data);
jqXhr.setRequestHeader("If-Match", data.__metadata.etag);
},
type: "POST",
dataType: "json",
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"X-HTTP-Method": "MERGE"
},
},
destroy: {
url: function (data) {
return listUrl + "(" + data.ID + ")";
},
type: "DELETE",
dataType: "json",
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"X-HTTP-Method": "MERGE",
"If-Match": "*"
}
}
},
pageSize: 20,
schema: {
data: "d.results",
model: {
id: "ID",
fields: {
ID: { editable: false, nullable: false },
Title: { validation: { required: true } },
Body1: { validation: { required: true } },
Votes: { type: "number", validation: { required: true, min: 1 } },
}
}
}
});
You can specify a "parameterMap" function on the DataSource.transport, and filter out the data you don't want.
var dataSource = new kendo.data.DataSource({
type: "odata",
transport: {
parameterMap: function(data, type){
if (type === "update" && data["__deferred"]){
delete data["__deferred"];
}
return kendo.stringify(data);
}
// ...
},
// ...
});
See http://docs.kendoui.com/api/framework/datasource#configuration-transport.parameterMap
Another option, if you're working with observable objects, is to provide a custom .toJSON method on your object. I wrote up a blog post about this, here: http://www.kendoui.com/blogs/teamblog/posts/13-04-04/hijacking-tojson-for-fun-and-profit.aspx
Using Derick Bailey's answer I was able to do the following with the parameterMap
the question object is a defined data model. Using this method, it will only send over the fields defined in the model plus the __metadata field that is need by SharePoint.
parameterMap: function (data, type) {
if (type == "update") {
for (var property in data) {
if (property != "__metadata" && !question.fields[property])
delete data[property];
}
}
return kendo.stringify(data);
}