Kendo grid not calling MVC action - kendo-ui

I've got the Kendo Grid calling an MVC action, but my breakpoint in the action isn't getting hit and nothing is getting returned. Any ideas why?
JavaScript:
$("#grid").kendoGrid({
dataSource: {
type: "json",
transport: {
read: {
url: "Sales/GetSalesHistory",
dataType: "json",
type: "GET",
data: { id: "#ViewBag.CustomerEstimateKey" }
}
},
schema: {
data: "data",
total: "total"
}
}
});
Action:
[HttpGet]
public JsonResult GetSalesHistory(int id)
{
List<Sales> sales = PestsLogic.GetSalesById(id);
return Json(new { data = sales, total = sales.Count }, JsonRequestBehavior.AllowGet);
}

Changing the url property to this fixed it:
'#Url.Action("GetSalesHistory", "Sales")'

I had the same issues you did. If you add a leading forward slash in the URL string so it looked like this - URL:"/Sales/GetSalesHistory" it should also work.

Related

Kendo DropDownList Not Binding Data

I am using a Kendo dropdownlist to display data made from a remote service call.
First, here is the definition in the HTML template:
<select
kendo-drop-down-list
k-options="dropdownOptions"
k-ng-delay="dropdownOptions">
</select>
Next, here is the code to populate the dropdown from an AngularJS controller:
var myUrl = '(url of REST service)';
$scope.dropdownOptions = {
dataSource: {
transport: {
read: {
url: myUrl,
dataType: 'json',
type: 'POST',
contentType: "application/json;charset=ISO-8859-1"
},
parameterMap: function (data, type) {
const req = {
"PARAMS": $scope.params
};
return JSON.stringify(req);
}
}
},
dataTextField: 'DESCRIPTION',
dataValueField: 'VALUE',
schema: {
type: "json",
data: "resultData",
model: {
id: "VALUE",
fields: {
"VALUE":{field: "VALUE", type: "string"},
"DESCRIPTION":{field: "DESCRIPTION", type: "string"}
}
}
}
};
(Note: the REST service requires data to be provided as a JSON object via POST, hence the type and parameterMap).
I have confirmed that the data to populate the dropdown is being returned from the REST service as an array under the key "resultData":
{
"resultData":[{"DESCRIPTION":"Whatever","VALUE":"VALUE1"},...]
}
Can anyone help me?
Update
I am also seeing "e.slice is not a function" in my dev console.
Edit
Added id field to model, no effect.
The problem was that schema should have been a child of dataSource. Once I fixed that, the data began to display.

JSON encoded improperly when using KendoGrid POST payload

I am binding to a JSON data source, then rebinding after the user initiates a search based on filters on the page. The JSON payload is encoded improperly and nothing I've tried thus far seems to explain why.
If I could just add the correct JSON to the HTTP post, everything would work normally, and does with the $.ajax method listed first.
Using $.ajax call (works)
$.ajax(
{
url: '/api/DataProcessing',
type: "Post",
contentType: "application/json; charset=utf-8",
data: '' + JSON.stringify(searchObject),
dataType: 'json',
success: function (result) {
$(".kendoDataProcessing").data("kendoGrid").dataSource = new kendo.data.DataSource({ data: result });
$(".kendoDataProcessing").data("kendoGrid").dataSource.read();
$(".kendoDataProcessing").data("kendoGrid").refresh();
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Status: ' + xhr.status + ', Error Thrown: ' + thrownError);
}
});
However, when I update the kendogrid data source in what I expect to send an equivalent payload, it encodes the JSON in an unexpected way (see below the code block for before and after HTTP requests captured in Fiddler. (encodes improperly)
$(".kendoDataProcessing").kendoGrid({
dataSource: {
transport: {
read: {
url: '/api/DataProcessing',
type: 'Post',
contentType: 'application/json; charset=utf-8',
data: '' + JSON.stringify(searchObject),
dataType: 'json',
}
},
pageSize: 25
},
height: 620,
sortable: true,
pageable: true,
filterable: true,
columns: [
{
field: "Client",
title: "Client Name",
width: 120
}, {
field: "Study",
title: "Study",
width: 100
}, {
field: "DataLogId",
title: "Batch Description",
width: 120
}, {
field: "Indicator",
title: "Indicator",
width: 100
}, {
field: "UserName",
title: "Username",
width: 110
}, {
field: "AssessmentPoint",
title: "Assessment Point",
width: 130
}, {
field: "DateStamp",
title: "Date Stamp",
width: 180
}]
});
**Expected JSON encoding (HTTP call created using $.ajax method) **
{"Client":"Choose a client...","Study":"Choose a study...","UserName":"Choose a user...","from":"","To":"","AssessmentPoint":"Choose an AP...","Indicator":"Choose an indicator...","DataLogId":""}
**Actual JSON encoding (HTTP call created using Kendogrid data source update and rebind **
0=%7B&1=%22&2=C&3=l&4=i&5=e&6=n&7=t&8=%22&9=%3A&10=%22&11=C&12=h&13=o&14=o&15=s&16=e&17=+&18=a&19=+&20=c&21=l&22=i&23=e&24=n&25=t&26=.&27=.&28=.&29=%22&30=%2C&31=%22&32=S&33=t&34=u&35=d&36=y&37=%22&38=%3A&39=%22&40=C&41=h&42=o&43=o&44=s&45=e&46=+&47=a&48=+&49=s&50=t&51=u&52=d&53=y&54=.&55=.&56=.&57=%22&58=%2C&59=%22&60=U&61=s&62=e&63=r&64=N&65=a&66=m&67 ... (continues)
It looks like it is making the json string into an array of sorts. So I tried with just a test string of "floof" and it encoded to "0=f&1=l&2=o&3=o&4=f"
Controller method called:
public HttpResponseMessage Post([FromBody]DataProcessingSearch dataProcessingSearch)
{
// dataProcessingSearch var is null (was passed oddly encoded)
}
Additional Details (search object)
var searchObject = new Object();
searchObject.Client = $('#ClientList').val();
searchObject.Study = $('#StudyList').val();
searchObject.Site = $('#SiteList').val();
searchObject.UserName = $('#UserList').val();
searchObject.from = $('#beginSearch').val();
searchObject.To = $('#endSearch').val();
searchObject.AssessmentPoint = $('#AssessmentPointList').val();
searchObject.Indicator = $('#IndicatorList').val();
searchObject.DataLogId = $('#DataLogIdText').val();
demo: http://so.devilmaycode.it/json-encoded-improperly-when-using-kendogrid-post-payload
function searchObject(){
return {
Client : $('#ClientList').val(),
Study : $('#StudyList').val(),
Site : $('#SiteList').val(),
UserName : $('#UserList').val(),
from : $('#beginSearch').val(),
To : $('#endSearch').val(),
AssessmentPoint : $('#AssessmentPointList').val(),
Indicator : $('#IndicatorList').val(),
DataLogId : $('#DataLogIdText').val()
}
}
// i have putted the dataSource outside just for best show the piece of code...
var dataSource = new kendo.data.DataSource({
transport: {
read : {
// optional you can pass via url
// the custom parameters using var query = $.param(searchObject())
// converting object or array into query sring
// url: "/api/DataProcessing" + "?" + query,
url: "/api/DataProcessing",
dataType: "json",
// no need to use stringify here... kendo will take care of it.
// also there is a built-in function kendo.stringify() to use where needed.
data: searchObject
},
//optional if you want to modify something before send custom data...
/*parameterMap: function (data, action) {
if(action === "read") {
// do something with the data example add another parameter
// return $.extend({ foo : bar }, data);
return data;
}
}*/
}
});
$(".kendoDataProcessing").kendoGrid({
dataSource: dataSource,
...
});
comments are there just for better explanation you can completely remove it if don't need it. the code is fully working as is anyway.
doc: http://docs.telerik.com/kendo-ui/api/wrappers/php/Kendo/Data/DataSource
What May be the wrong perception:-
1.The Json() method accepts C# objects and serializes them into JSON
strings. In our case we want to return an array of JSON objects; to
do that all you do is pass a list of objects into Json().
public JsonResult GetBooks()
{
return Json(_dataContext.Books);
}
Can you identify what is wrong with the above method? If you didn't already know, the above method will fail at runtime with a "circular reference" exception.
Note: try to return Json, HttpResponse may serialize the data in such a way that it is not acceptable by Kendo Grid. this has happened with me in my project.
Try this Approach:-
Now lets create instances of them in a JsonResult action method.
public JsonResult GetFooBar()
{
var foo = new Foo();
foo.Message = "I am Foo";
foo.Bar = new Bar();
foo.Bar.Message = "I am Bar";
return Json(foo);
}
This action method would return the following JSON:
{
"Message" : "I am Foo",
"Bar" : {
"Message" : "I am Bar"
}
}
In this example we got exactly what we expected to get. While serializing foo it also went into the Bar property and serialized that object as well. However, let's mix it up a bit and add a new property to Bar.
I remember working with a kendo grid in the past. Solution back then was returning jsonp. (needed to work crossdomain not sure if it does in your case)
Suggestion change you controller method to return sjonp by decorating you method with a JsonpFilterAttribute. Something like so:
[JsonpFilter]
public JsonResult DoTheThing(string data, string moreData)
{
return new JsonResult
{
Data = FetchSomeData(data, moreData)
};
}
Then in de Kendo grid try use http://demos.telerik.com/kendo-ui/datasource/remote-data-binding.
For the Jsonpfilter attribute first look at here or else here.

HttpPost not rendering the page

The below mentioned code not redering the page. is there anything need to be added with this.
[HttpPost]
public ActionResult CompetitiveSnapshotDetails(Object[] comp)
{
CompetitiveSnapModel[] compSnapList = new JavaScriptSerializer().Deserialize<CompetitiveSnapModel[]>(comp[0].ToString());
String[] competitiveDetailHeader = { "State", "Rank", "Terracon Inc Transcations", "Number 1 Firm", "Number 2 Firm", "Number 3 Firm", "Total Transcations" };
ViewData["CompetitiveDetailHeader"] = competitiveDetailHeader;
ViewData["CompetitiveDetail"] = compSnapList;
return View();
}
Call this using ajax
$("#com-snap").click(function () {
var competitiveSnap = JSON.parse(window.localStorage.getItem("l_compSnap"));
var URL = "../Detailpage/CtDetails";
$.ajax({
cache: false,
type: "POST",
url: URL,
data: { comp: JSON.stringify(competitiveSnap)},
dataType: "json",
success: function (data) {
},
error: function (xhr) {
}
});
});
What I see is that in you AJAX code, you are not calling the same action you showed first.
The URL you need to put is more like:
"/YourController/CompetitiveSnapshotDetails"
The second and more important issue is that your need to grab the html of your view and do something with it.
Your VIEW HTML is in your data parameter in your success function.
Something like this: $('#YourContainer').html(data);

Kendo Datasource Transport custom function not getting called

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

jquery autocomplete using mvc3 dropdownlist

I am using ASP.NET MVC3 with EF Code First. I have not worked previously with jQuery. I would like to add autocomplete capability to a dropdownlist that is bound to my model. The dropdownlist stores the ID, and displays the value.
So, how do I wire up the jQuery UI auto complete widget to display the value as the user is typing but store the ID?
I will need multiple auto complete dropdowns in one view too.
I saw this plugin: http://harvesthq.github.com/chosen/ but I am not sure I want to add more "stuff" to my project. Is there a way to do this with jQuery UI?
Update
I just posted a sample project showcasing the jQueryUI autocomplete on a textbox at GitHub
https://github.com/alfalfastrange/jQueryAutocompleteSample
I use it with regular MVC TextBox like
#Html.TextBoxFor(model => model.MainBranch, new {id = "SearchField", #class = "ui-widget TextField_220" })
Here's a clip of my Ajax call
It initially checks its internal cached for the item being searched for, if not found it fires off the Ajax request to my controller action to retrieve matching records
$("#SearchField").autocomplete({
source: function (request, response) {
var term = request.term;
if (term in entityCache) {
response(entityCache[term]);
return;
}
if (entitiesXhr != null) {
entitiesXhr.abort();
}
$.ajax({
url: actionUrl,
data: request,
type: "GET",
contentType: "application/json; charset=utf-8",
timeout: 10000,
dataType: "json",
success: function (data) {
entityCache[term] = term;
response($.map(data, function (item) {
return { label: item.SchoolName, value: item.EntityName, id: item.EntityID, code: item.EntityCode };
}));
}
});
},
minLength: 3,
select: function (event, result) {
var id = result.item.id;
var code = result.item.code;
getEntityXhr(id, code);
}
});
This isn't all the code but you should be able to see here how the cache is search, and then the Ajax call is made, and then what is done with the response. I have a select section so I can do something with the selected value
This is what I did FWIW.
$(document).ready(function () {
$('#CustomerByName').autocomplete(
{
source: function (request, response) {
$.ajax(
{
url: "/Cases/FindByName", type: "GET", dataType: "json",
data: { searchText: request.term, maxResults: 10 },
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data, function (item) {
return {
label: item.CustomerName,
value: item.CustomerName,
id: item.CustomerID
}
})
);
},
});
},
select: function (event, ui) {
$('#CustomerID').val(ui.item.id);
},
minLength: 1
});
});
Works great!
I have seen this issue many times. You can see some of my code that works this out at cascading dropdown loses select items after post
also this link maybe helpful - http://geekswithblogs.net/ranganh/archive/2011/06/14/cascading-dropdownlist-in-asp.net-mvc-3-using-jquery.aspx

Resources