Kendo Datasource Transport custom function not getting called - kendo-ui

Im experiencing a rather annoying bug (?) in Kendo UI Datasource.
My Update method on my transport is not getting called when I pass a custom function, but it does work if I just give it the URL.
This works:
...
transport: {
update: { url: "/My/Action" }
}
...
This does not
...
transport: {
update: function(options) {
var params = JSON.stringify({
pageId: pageId,
pageItem: options.data
});
alert("Update");
$.ajax({
url: "/My/Action",
data:params,
success:function(result) {
options.success($.isArray(result) ? result : [result]);
}
});
}
}
...
The function is not getting invoked, but an ajax request is made to the current page URL, and the model data is being posted, which is rather odd. Sounds like a bug to me.
The only reason I have a need for this, is because Kendo can't figure out that my update action returns only a single element, and not an array - so, since I dont want to bend my API just to satisfy Kendo, I though I'd do it the other way around.
Have anyone experienced this, and can point me in the right direction?
I also tried using the schema.parse, but that didn't get invoked when the Update method was being called.
I use myDs.sync() to sync my datasource.

Works as expected with the demo from the documentation:
var dataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
$.ajax( {
url: "http://demos.kendoui.com/service/products",
dataType: "jsonp",
success: function(result) {
options.success(result);
}
});
},
update: function(options) {
alert(1);
// make JSONP request to http://demos.kendoui.com/service/products/update
$.ajax( {
url: "http://demos.kendoui.com/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" }
}
});
dataSource.fetch(function() {
var product = dataSource.at(0);
product.set("UnitPrice", product.UnitPrice + 1);
dataSource.sync();
});
Here is a live demo: http://jsbin.com/omomes/1/edit

Related

Populating a kendo multiselect with ajax data

I am using a kendo multiselect widget for users to select different values pulled from the database via an ajax call. The ajax call takes one parameter, searchValue, which will narrow down the returned data. Here is my controller:
[HttpPost]
public JsonResult ProfitabilitySearch(string searchValue)
{
return Json(InventoryDataAccess.ProfitabilitySearch(searchValue));
}
1) How do you get the value from the text box to use as your searchValue? I commented the area in question below.
Here is my dataSource:
var searchDataSource = new kendo.data.DataSource({
transport: {
read: function () {
$.ajax({
type: 'POST',
url: Firm.ProfitabilitySearchURL,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
//'SuperClient' is test data to see if it works, but what do i
//need to make searchValue = what I type?
data: JSON.stringify({ searchValue: 'SuperClient'}),
success: function (data) {
return data.RESULT;
}
});
}
},
group: { field: 'category' },
serverFiltering: true
});
And here is where I create the multiselect widget:
var TKSearch = $("#TKSearch").kendoMultiSelect({
dataSource: searchDataSource,
autoBind: false,
minLength: 3,
placeholder: 'Search Timekeepers...',
dataTextField: 'label',
dataTextValue: 'value',
delay: 200
}).data("kendoMultiSelect");
I'm not sure if this will help, but here is the structure of the json that is returned from the ajax call:
{"label":"SUNFLOWER REALTY CORP. (023932)","value":"023932","category":"RC"}
Solving the first question above may answer my second question so I will wait to ask that until after.
You can use functions for the request parameters.
var searchDataSource = new kendo.data.DataSource({
transport: {
read: function (options) {
$.ajax({
type: 'POST',
url: Firm.ProfitabilitySearchURL,
contentType: 'application/json; charset=utf-8',
data: {
searchValue: function () {
// better: use a model property instead of this
return $("#TKSearch").data('kendoMaskedTextBox').value();
}
},
success: function (data) {
options.success(data.RESULT);
}
});
}
},
group: { field: 'category' },
serverFiltering: true
});
Notes
This really should be a GET request. Use POST for requests that actually change data on the server and GET for requests that merely retrieve data from the server.
You do not have to JSON.stringify() yourself. jQuery does that transparently.
Specifying dataType is completely superfluous, jQuery will figure this out from the response headers.
Reading the input value via jQuery is not clean. Use the data-bound model property instead.
The callback invocation (options.success())
This sample lacks HTTP error handling, you must add that.

Kendo UI - DataSource works when using fetch(), but not read()

I have a Kendo UI DataSource that works when I use fetch(), but when I use the exact same configurtation with read() it fails. This is a problem as I need to retrieve data more than once and I can't do that with fetch().
Here is the DataSource code -
var FieldsDataSource = new kendo.data.DataSource({
transport: {
read: {
url: "../WebServiceAddress",
dataType: "json",
type: "POST",
contentType: 'application/json; charset=utf-8',
cache: false
},
parameterMap: function() {
return "{some mapping that has been confirmed to work}";
},
schema: {
data: function (data) {
if (data && data.d) {
//execution gets to here and stops
return data.d;
}
else {
return [];
}
},
}
});
Here is the code that calls the DataSource.read() function -
function loadFields() {
FieldsDataSource.read(function() {
var data = this.data();
if (data.length > 0) {
for (var i = 0; i < data.length; i++) {
var dataitem = data[i].Key;
$("#" + dataitem + "_field").prop("checked", data[i].Value);
}
}
});
}
If I change FieldsDataSource.read(function() to FieldsDataSource.fetch(function() everything works, but that doesn't make sense as I was under the improession that read and fetch do the same thing the difference being fetch only gets data once.
What I do know is that the data is being returned from the server, I can see it in fiddler - but the execution stops in the schema section where I flagged it in my code sample.
Apologies if I am asking a really obvious question, but I'm very new to Kendo.
have a look at the kendo demo site, this post explains how to read remote data quite nicely. I beleive the schema.data requires only string value. Configure your model and parse and then just call read(), your datasource.data collection will get populated and then you can play with it.
Also note that datasource.read() is async, thefore you populatefields method should be called from complete event of the datasource, not other way around. eg you might have no data in when populating.
transport: {
read: {
url: "../WebServiceAddress",
dataType: "json",
type: "POST",
contentType: 'application/json; charset=utf-8',
cache: false,
complete : function () { }
},

Is it possible to make multiple calls using Jsonp with deferred objects?

I'm trying to make two or more requests all at once if that's even possible? I'm concerned about speed since after the first request is made I want to display that info onto a web page and then do the same for each additional url.
I've been reading about deferred objects and trying some examples, and so far I've tried to do this,
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script >
$(document).ready(function($) {
// - 1st link in chain - var url = 'https://www.sciencebase.gov/
catalog/items?parentId=504108e5e4b07a90c5ec62d4&max=60&offset=0&format=jsonp';
// - 2nd link in chain - var url = 'https://www.sciencebase.gov/
catalog/itemLink/504216b6e4b04b508bfd333b?format=jsonp&max=10';
// - 3rd (and last) link in chain - var url = 'https://www.sciencebase.gov/
catalog/item/4f4e4b19e4b07f02db6a7f04?format=jsonp';
// parentId url
function parentId() {
//var url = 'https://www.sciencebase.gov/catalog/items?parentId=
504108e5e4b07a90c5ec62d4&max=3&offset=0&format=jsonp';
return $.ajax({
type: 'GET',
url: 'https://www.sciencebase.gov/catalog/items?parentId=
504108e5e4b07a90c5ec62d4&max=3&offset=0&format=jsonp',
jsonpCallback: 'getSBJSON',
contentType: "application/json",
dataType: 'jsonp',
success: function(json) {},
error: function(e) {
console.log(e.message);
}
});
}
// itemLink url
function itemLink() {
//var url = 'https://www.sciencebase.gov/catalog/itemLink
/504216b6e4b04b508bfd333b?format=jsonp&max=10';
return $.ajax({
type: 'GET',
url: 'https://www.sciencebase.gov/catalog/itemLink
/504216b6e4b04b508bfd333b?format=jsonp&max=10',
jsonpCallback: 'getSBJSON',
contentType: "application/json",
dataType: 'jsonp',
success: function(json) {},
error: function(e) {
console.log(e.message);
}
});
}
// Multiple Ajax Requests
$.when( parentId(), itemLink()).done(function(parentId_data, itemLink_data) {
console.log("parentId_data.items[0].title");
});
});
But it doesn't seem like the functions are functioning. I was expecting to be able to put some stuff after the .when() method inside the function to tell my program what to do, but I'm not getting anything displayed??
Thanks for the help!
Part of the problem is that in the done handler for $.when, the arguments that are passed to the callback are the array of arguments for each request, not simply the data that you want to use. You can get around this by using .pipe as in the example below.
Also, don't specify jsonpCallback unless you have a very good reason, most of the time you want to let jQuery manage that internally for you.
Here's a working example tested on JSFiddle
jQuery(function($) {
function parentId() {
return $.ajax({
url: 'https://www.sciencebase.gov/catalog/items?parentId=504108e5e4b07a90c5ec62d4&max=3&offset=0&format=jsonp',
dataType: 'jsonp',
error: function(e) {
console.log(e.message);
}
// We'll use pipe here so that rather than the value being passed to our $.when handler
// is simply our data rather than an array in the form of [ data, statusText, jqXHR ]
}).pipe(function( data, statusText, jqXHR ) {
return data;
});
}
function itemLink() {
return $.ajax({
url: 'https://www.sciencebase.gov/catalog/itemLink/504216b6e4b04b508bfd333b?format=jsonp&max=10',
dataType: 'jsonp',
error: function(e) {
console.log(e.message);
}
}).pipe(function(data) {
return data;
});
}
// Multiple Ajax Requests
$.when( parentId(), itemLink()).done(function(parentId_data, itemLink_data) {
console.log( parentId_data, itemLink_data );
});
});

ExtJs 4.1 : How to send json data in the request body using Ext.Ajax.request()?

I would like to send json data using Ext.Ajax.request() then access it in ASP.NET using Request.InputStream which is the content of the request body. I need a way to tell ExtJs to write the data in the request body as it is done while using an Ext.data.proxy.Ajax.
Specify POST method and just use the request's jsonData config:
Ext.Ajax.request({
url: 'myUrl',
method: 'POST',
params: {
requestParam: 'notInRequestBody'
},
jsonData: 'thisIsInRequestBody',
success: function() {
console.log('success');
},
failure: function() {
console.log('woops');
}
});
If you want a record written as JSON you can use a JSON writer like this also.
var writer = Ext.create('Ext.data.writer.Json'),
record = Ext.getStore('SomeStoreID').first();
Ext.Ajax.request({
url: 'myUrl',
method: 'POST',
params: {
requestParam: 'notInRequestBody'
},
jsonData: writer.getRecordData(record),
success: function() {
console.log('success');
},
failure: function() {
console.log('woops');
}
});

asp.net mvc ajax driving me mad

how come when I send ajax request like this everything works
$(".btnDeleteSong").click(function () {
var songId = $(this).attr('name');
$.ajax({
type: 'POST',
url: "/Home/DeleteSong/",
data: { id: songId },
success: ShowMsg("Song deleted successfully"),
error: ShowMsg("There was an error therefore song could not be deleted, please try again"),
dataType: "json"
});
});
But when I add the anonymous function to the success It always showes me the error message although the song is still deleted
$(".btnDeleteSong").click(function () {
var songId = $(this).attr('name');
$.ajax({
type: 'POST',
url: "/Home/DeleteSong/",
data: { id: songId },
success: function () { ShowMsg("Song deleted successfully"); },
error: function () {
ShowMsg("There was an error therefore song could not be deleted, please try again");
},
dataType: "json"
});
});
what if i wanted few things on success of the ajax call, I need to be able to use the anonymous function and I know that's how it should be done, but what am I doing wrong?
I want the success message to show not the error one.
function ShowMsg(parameter) {
$("#msg").find("span").replaceWith(parameter);
$("#msg").css("display", "inline");
$("#msg").fadeOut(2000);
return false;
}
Make sure your action is returning Json data.
"json": Evaluates the response as JSON and returns a JavaScript object. In jQuery 1.4 the JSON data is parsed in a strict manner; any malformed JSON is rejected and a parse error is thrown. (See json.org for more information on proper JSON formatting.)
http://api.jquery.com/jQuery.ajax/
Your action method should surely return Json data. I have the similar code see if that helps.
public ActionResult GetAllByFilter(Student student)
{
return Json(new { data = this.RenderPartialViewToString("PartialStudentList", _studentViewModel.GetBySearchFilter(student).ToList()) });
}
$("#btnSearch").live('click',function () {
var student = {
Name: $("#txtSearchByName").val(),
CourseID: $("#txtSearchByCourseID").val()
};
$.ajax({
url: '/StudentRep/GetAllByFilter',
type: "POST",
data: JSON.stringify(student),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(result) {
$("#dialog-modal").dialog("close");
RefreshPartialView(result.data);
}
, error: function() { alert('some error occured!!'); }
});
});
Above code is used to reload a partial view. in your case it should be straight forward.
Thanks,
Praveen

Resources