DataSource transport.destroy called +1 times for each successive delete (recalled for previously deleted items) - kendo-ui

I have a DataSource in my code that support destroy. In order to delete object from the it, i directly call remove, i.e.
myDataSource.remove(discardedData);
I get a behavior similar to this. However, unlike the linked thread, my destroy is not set to a function, so the solution does not help me.
My DataSource (i included all of it in case some of my configuration is to blame):
var QueueMessages = {
type: "aspnetmvc-ajax",
transport: {
read: {
url: BASE_URL + "api/QueueMessages/GetMessagesHeaders",
dataType: "json",
type: "GET",
beforeSend: function (req) {
req.setRequestHeader('Authorization', authService.getAuth());
}
},
destroy: {
url: BASE_URL + "api/QueueMessages/deleteMessage",
dataType: "json",
type: "DELETE",
beforeSend: function (req) {
req.setRequestHeader('Authorization', authService.getAuth());
}
}
},
schema: {
model: {
id: "id",
fields: {
profileName: { type: "string" },
queueType: { type: "string" },
acceptedAt: { type: "date" },
processedAt: { type: "date" },
BodyExcerpt: { type: "string" }
}
},
total: "total",
data: "data",
},
error: function (e) {
//throw user back to login page
if (e.errorThrown === "Unauthorized")
$rootScope.$apply($location.path('/'));
},
requestStart: function () {
},
requestEnd: function () {
},
pageSize: 50,
serverPaging: true,
serverFiltering: true,
serverSorting: true,
serverGrouping: true,
serverAggregates: true
};
I cant find any clues as to why this is happening.

thanks to OnaBai I found the problem.
consulting RFC 7231, i my changed the http DELETE response from 200 OK to 204 no content.

Related

Kendo Grid not showing data with proper json being returned

My kendo grid is not showing data after successfully calling a web method and seeing data being returned in the ajax request.
$(document).ready(function () {
var filterSource = new kendo.data.DataSource({
transport: {
read: function (options) {
$.ajax({
type: "GET",
url: "DoJo.aspx/GetProjects",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
// msg.d has the json data
}
});
}
},
schema: {
model: {
fields: {
ProjNum: {type: "string"},
Stat: {type: "string"}
}
},
data: "d"
},
change: function (e) {
// e.items is empty
}
});
$("#grid").kendoGrid({
dataSource: filterSource,
columns: [
{
field: "ProjNum", title: "Project Number", width: "130px", filterable: {
multi: true,
dataSource: filterSource
}
},
{
field: "Stat", title: "Status", filterable: {
multi: true,
dataSource: filterSource
}
}
]
});
})
The JSON below is in an array format.
[{"ProjNum":"12345","Stat":null,"ProjTitle":"Test Title","ClientName":"Test Client","ClientContactName":"Test Name","ClientFacilityLocation":"Test Location","SourceOfContact":"Test Contact","ProjManager":"Test Manager","Department":"Test Department"}]
Why is change callback returning an empty e.items? If I remove data: "d" it returns e.Items with the JSON data.
When you set dataSource.transport.read to a function and invoke the ajax call yourself, you need to pass the result (or error) back into the dataSource, like so:
var filterSource = new kendo.data.DataSource({
transport: {
read: function (options) {
$.ajax({
type: "GET",
url: "DoJo.aspx/GetProjects",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
// msg.d has the json data
// notify the data source that the request succeeded
options.success(msg);
},
error: function(msg) {
// notify the data source that the request failed
options.error(msg);
}
});
}
},
schema: {
model: {
fields: {
ProjNum: { type: "string" },
Stat: { type: "string" }
}
},
data: "d"
},
change: function (e) {
// e.items is empty
}
});
See the documentation for more information.

Kendo-UI autocomplete fails to load

I am having an issue with the data source not being accessed. The webservice executes it's query and firebug shows the return string but I don't get the features of the autocomplete list.
$("#txtCriteria").kendoAutoComplete({
minLength: 1,
suggest: true,
filter: "startswith",
dataTextField: "ACName",
select: function (e) {
var dataItem = this.dataItem(e.item.index());
//output selected dataItem
document.getElementsByName("hdfldSelect")[0].value = dataItem.ACCode;
$("#txtCriteria").kendoAutoComplete();
var autocomplete = $("#txtCriteria").data("kendoAutoComplete");
autocomplete.destroy();
},
dataSource: new kendo.data.DataSource({
serverFiltering: true,
transport: {
read: {
url: "../DAL/Reports/wsReports.asmx/AutoComplete",
dataType: "json",
type: "GET",
},
parameterMap: function (data, action) {
var newParams = {
Type: Type,
filter: data.filter.filters[0].value
};//var
return newParams;
},//parameter
}//trans2
})//data
});
Thank you for any assistance
Going along the fact that your endpoint returns the expected data set, you could try adding a 'schema' to your kendo-datasource.
dataSource: new kendo.data.DataSource({
schema: {
data: function (e) {
return e.Results
},
model: {
fields: {
Id: { type: "number" },
Name: { type: "string" }
}
}
},
serverFiltering: true,
transport: {
read: {
url: "../DAL/Reports/wsReports.asmx/AutoComplete",
dataType: "json",
type: "GET",
},
parameterMap: function (data, action) {
var newParams = {
Type: Type,
filter: data.filter.filters[0].value
};//var
return newParams;
},//parameter
}//trans2
})//data

kendu ui grid after server update cells stay marked as "dirty"

i based this code on kendu grid ui code demo.
when ever i add a new record, it gets sent to the server side (c# handler)
and from there i convert json to object.. and so on.
the operation is successful and the request that kendu made is done with status code 200.
but for some reason the cells that were changed are still marked as "dirty" .
as a result of this any new row is sent with the first attempt since it thinks it needs to be sent again. here is my code:
jQuery("#getallDataBTN").click(
function () {
$("#grid").kendoGrid({
dataSource: {
transport: {
read: {
url: "/WallEHandler.ashx?command=getallPermissions",
dataType: "json"
},
create: {
url: "/WallEHandler.ashx?command=addPermission",
dataType: "json",
type:"post"
},
update: {
// url: "/WallEHandler.ashx?command=editPermission",
// dataType: "jsonp"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
schema: {
model: {
id:"Method",
fields: {
Method: { type: "string" , validation: { required: true }},
ServiceType: { type: "string" ,validation: { required: true }},
Role: { type: "string" ,validation: { required: true }},
Permission: { type: "string" ,validation: { required: true }},
ExtendedData: { type: "string" }
}
}
},
pageSize: 100,
batch: true,
},
height:850,
scrollable: true,
sortable: true,
filterable: true,
pageable: {
input: true,
numeric: false
},
columns: [
"Method",
"ServiceType",
"Role",
{ field: "Permission", editor: categoryDropDownEditor },
"ExtendedData"
],
navigatable: true,
toolbar: ["create", "save", "cancel"],
editable: true
//selectable: "row",
//save: function(e)
// {
//alert("Save");
// }
});
}
);
is there maybe somthing i need to return from the server to tell the grid that it was successful?
thanks for any help
i figured it out, it seems that the response of a successful request must return the same object as sent. (must be some sort of inside validation by kendu).
c#:
Response.Write(context.Request.Form["models"]);

kendo ui how to filter dataSource requestStart

Main Problem
My current problem is the refresh progress when updating a grid datasource. I have change my code use the kendo.ui.progress in that way when requestStart event starts I ser the kendo.ui.progress to true. This activates the loading image when it end it calls the requestEnd.
The problem is that this event is hapenning for sorting and filtering. And I want it to only trigger for the read function of the dataSource. This problem makes the grid to use the progress endlessly.
Is there some way to filter in the requestStart and requestEnd only activate on the transport read?
My DataSource Code
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: url_Obtener_Periodo,
type: "POST"
},
parameterMap: function (options, operation) {
if (operation == "read" && options) {
return {
"periodo.Year": $("#periodo-anio").val(),
"periodo.Month": $("#periodo-mes").val(),
"Filtro": $("#Filtro").val()
};
}
}
},
requestStart: function (e) {
kendo.ui.progress($("#grid-container"), true);
},
requestEnd: function (e) {
kendo.ui.progress($("#grid-container"), false);
},
schema:{
model: {
id: "Codigo_De_Pedido",
fields: {
Codigo_De_Pedido: { type: "number" },
Fecha_Y_Hora_De_Creacion: { type: "date" },
UserName: { type: "string" },
Nombre_Del_Usuario: { type: "string" },
Codigo_Del_Vendedor: { type: "number" },
Nombre_Del_Vendedor: { type: "string" },
Is_Pedido_Closed: { type: "bool" },
Estado: { type: "string" }
}
}
},
pageSize: 10
});
The changes I did to solve the progress endlessly problem where 2.
Removing requestEnd function from the dataSource
Adding dataBound function to the Grid
Data Source Code
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: url_Obtener_Periodo,
type: "POST"
},
parameterMap: function (options, operation) {
if (operation == "read" && options) {
return {
"periodo.Year": $("#periodo-anio").val(),
"periodo.Month": $("#periodo-mes").val(),
"Filtro": $("#Filtro").val()
};
}
}
},
schema:{
model: {
id: "Codigo_De_Pedido",
fields: {
Codigo_De_Pedido: { type: "number" },
Fecha_Y_Hora_De_Creacion: { type: "date" },
UserName: { type: "string" },
Nombre_Del_Usuario: { type: "string" },
Codigo_Del_Vendedor: { type: "number" },
Nombre_Del_Vendedor: { type: "string" },
Is_Pedido_Closed: { type: "bool" },
Estado: { type: "string" }
}
}
},
pageSize: 10,
requestStart: function (e) {
kendo.ui.progress($("#grid-container"), true);
}
});
Kendo Grid Code
kendoGrid = $("#selectable-pedidos").kendoGrid({
dataSource: dataSource,
pageable: true,
sortable: true,
filterable: {
extra: false,
operators: {
string: {
startswith: "Comienza Con",
eq: "Es Igual A",
neq: "No Es Igual A"
}
}
},
dataBound: function (e) {
kendo.ui.progress($("#grid-container"), false);
},
columns: [
{ field: "Fecha_Y_Hora_De_Creacion", title: "Fecha y Hora", template: "#= kendo.toString(Fecha_Y_Hora_De_Creacion, 'dd/MM/yyyy hh:mm:ss tt') #" },
{ field: "Codigo_De_Pedido", title: "Código de Pedido" },
{ field: "Estado", filterable: true, title: "Estado" },
{ field: "Codigo_Del_Vendedor", title: "Código de Vendedor" },
{ field: "Nombre_Del_Vendedor", title: "Nombre de Vendedor" },
{
command: {
text: "Ver Detalle de Pedido",
click: function (e) {
$("#empty").append("<form method='POST' action='/HojaDeRuta/GetById/'><input type='hidden' name='Codigo_Pedido' value='"
+ this.dataItem($(e.currentTarget).closest("tr")).Codigo_De_Pedido + "' /><input type='submit' /></form>");
$("#empty input[type='submit']").click();
}
},
title: " "
}
]
}).data("kendoGrid");
There are a few things about your questions worth mentioning for those who read this:
Is there some way to filter in the requestStart and requestEnd only
activate on the transport read?
Yes, but it will not help you. The parameter of the event has a type property that will contain read, update, destroy or create.
statementEntriesDS.bind("requestStart", function (e) {
switch (e.type) {
case "create":
alert('-> event, type "create".');
break;
case "read":
alert('-> event, type "read".');
break;
case "update":
alert('-> event, type "update".');
break;
case "destroy":
alert('-> event, type "destroy".');
break;
}
});
Your example code doesn't specify serverFiltering or serverSorting so sorting and filtering wouldn't cause an remote action. You'll only get client-side sorting and filtering. However, if they are specified they're all going to result in a read and that wouldn't really help you.
That you would not have the requestEnd event fire sounds odd. You should probably add a handler for the error event and see if something is failing.
If you really want complete control over what's happening, you can specify a function for your read:
transport: {
read: function (options) {
kendo.ui.progress($gridContainer, true);
$.ajax({
url: carrierServiceBaseUrl + "/GetManualStatementsCarrierList",
contentType: 'application/json; charset=utf-8',
dataType: "json",
type: "POST",
success: function (result) {
// notify the data source that the request succeeded
options.success(result);
kendo.ui.progress($gridContainer, false); },
error: function (result) {
options.error(result); // Call the DataSource's "error" method with the results
kendo.ui.progress($gridContainer, false);
notification.show({
title: "ERROR:",
message: result.statusText
}, "error");
}
});
}
}

Kendo grid post and delete send null to controller

I'm posting a kendoui web grid and it isn't sending data and I can't see what I'm doing different from the sample that's failing. I'm posting to the controller, but it's either empty (if batch: true or null if batch: false)
var crudServiceBaseUrl = "api/Certifications/",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + member.id,
dataType: "json"
},
update: {
url: crudServiceBaseUrl,
type: "Post",
dataType: "json"
},
destroy: {
url: crudServiceBaseUrl,
type: "Delete",
contentType: "application/json; charset=utf-8",
dataType: "json"
},
create: {
url: crudServiceBaseUrl,
type: "Post",
dataType: "json"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
}
},
editable: { //disables the deletion functionality
update: true,
destroy: true
},
batch: true,
pageSize: 30,
schema: {
model: {
id: "Id",
fields: {
Id: { editable: false, nullable: true },
MemberId: { editable: false, nullable: true },
Name: { validation: { required: true} },
AuthorityName: { validation: { required: true} },
StartDate: { type: "date", validation: { required: true} },
EndDate: { type: "date" }
}
}
}
});
$("#certifications").kendoGrid({
dataSource: dataSource,
pageable: true,
height: 300,
toolbar: ["create"],
columns: [
{ field: "Name", title: "Product Name", width: 250 },
{ field: "AuthorityName", title: "Authority", format: "{0:c}", width: "140px" },
{ field: "StartDate", title: "Earned", template: '#= kendo.toString(StartDate,"MM/dd/yyyy") #', width: 50 },
{ field: "EndDate", title: "Expired", template: '#= kendo.toString(EndDate,"MM/dd/yyyy") #', width: 50 },
{ command: ["edit", "destroy"], title: " ", width: "130px" }],
editable: "popup"
});
the web api:
public Certification DeleteCertification(CertificationVm cert)
{
var model = Uow.Certifications.Get(cert.Id);
if (model == null)
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NoContent));
Uow.Certifications.Delete(model);
Uow.Commit();
return model;
}
I'd figured it out, although I had to depart from the example http://demos.kendoui.com/web/grid/editing-popup.html
The fix was add the content type, correctly use dataType: "json" as noted above, change from batch: true to batch: false and change the parameter map to the below
destroy: {
url: crudServiceBaseUrl,
type: "Delete",
contentType: "application/json; charset=utf-8",
dataType: "json"
},
parameterMap: function (model, operation) {
if (operation !== "read" && model) {
return kendo.stringify(model) ;
}
}
There is no such thing as jsonp + POST - it is discussed here.
Do not use jsonp unless you really know why you need it.

Resources