can't get the data Kendo pager - asp.net-mvc

I'm trying to use kendo pager in my project but I can't get the data see the attached image
[result][1]
[1]: http://i.stack.imgur.com/xmLYn.png
here is my javascript code :
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: '/Option/Get',
}
},
pageSize: 2,
schema: {
data: 'Data',
model: { id: 'ID' }
}
});
the action method :
public JsonResult Get([DataSourceRequest] DataSourceRequest request,int Id)
{
var donnees=_DService.GetList(Id);
var results = donnees.ToDataSourceResult(request);
return Json(results);
}

The problem is caused by the missing schema.total setting. Since you are using ToDataSourceResult, then it should be set to "Total".
In addition, the action method expects an Id parameter, which the Kendo UI DataSource currently does not provide. If you need this parameter to query the database, then use the data function of transport.read to send it.
Last but not least, call the fetch method of the Kendo UI DataSource instance, unless there is some other widget that will do that automatically (e.g. a ListView).
Here is an example, compare it with your implementation:
http://dojo.telerik.com/okaTeD
This is the dummy data service:
http://dojo.telerik.com/ifEvu

Related

View content is not displayed correctly after redirected in controller in asp.net mvc

I have a action method in the controller and two views in different language.
public ActionResult Index(Guid id, string languageName)
{
var view = "Welcome_en";
if (languageName == "Spanish")
view = "Welcome_es";
return View(view, model);
}
The default languageName is "English".(In RouteConfig.cs defaults part). So at the beginning, the page is loaded at http://localhost:12091/Some/sssf6bda-9r5e-64d7-9bd2-63c2te616adb.
And I saw the view was Welcome_en.cshtml. in that view I have a dropdown menu for languages to switch active language. I select Spanish then make an ajax call.
$("#Languages").change(function () {
var activeLanguage= $(this).find('option:selected').val();
$.ajax({
url: "/Some/Index",
datatype: "text",
data: { id: '#Model.Guid', languageName: activeLanguage },
type: "POST",
success: function () {
console.log('Success')
}
})
Then I saw the code entered the controller again. The view to be displayed should be Welcome_es.cshtml.
The view Welcome_es.cshtml basically is same as Welcome_en.cshtml. The difference is the content in different language. And I set break points in Welcome_es.cshtml, it did reached. However the final displayed result is still same as Welcome_en.cshtml.
I am not sure why it shows the English view's content, I cleaned the cookies but it is same. Also I set a break point in English page, it didn't go to there when the language was "Spanish".
Your AJAX request is returning your view, but you aren't doing anything with it. If your view is a partial then you can change the success callback in your AJAX call to update the part of the page which the HTML should replace.
$.ajax({
url: "/Some/Index",
datatype: "text",
data: { id: '#Model.Guid', languageName: activeLanguage },
type: "POST",
success: function (html) {
$('.partial').html(html);
}
});
Or if the view is really a full page then don't use AJAX to make the request.
Your current code is making the ajax call, but is not using the response coming from that call.
You should return the partial view result and use that to update the relevant part of your DOM to see the changes. You can do that in the success event of the ajax call
$.ajax({
url: "/Some/Index",
data: { id: '#Model.Guid', languageName: activeLanguage },
type: "POST",
success: function(response) {
$("#someDiv").html(response);
}
});
Assuming you have a div with id someDiv present in your page, the above code will update the inner html of that element with the response coming from your ajax call, which is the html markup generated by the corresponding views (based on the language name you are passing from client side)
I also noticed that you are calling the same action method for your normal page load and the ajax call. In that case, what are you trying to achieve with the ajax call ? You could simply reload the page. No need of ajax.
$(function() {
$("#Languages").change(function() {
var activeLanguage = $(this).val();
window.location.href = "#Url.Action("index","Home")?languageName="
+ activeLanguage +"&id=#Guid.NewGuid()";
});
});
If you are using a page reload, you might want to select the dropdown with the selection from previous page. You may use the Html.DropDownListFor helper with a view model for your page to address this issue.
Add a new property to your view model to store the selected language.
public class YourPageViewModel
{
// Your other existing properties goes here
public string SelectedLanguage { set;get;}
}
Now in your GET action method, you should set the SelectedLanguage property value based on your method parameter.
public ActionResult Index(Guid id, string languageName)
{
var view = "Welcome_en";
if (languageName == "Spanish")
view = "Welcome_es";
var model = new YourPageViewModel();
model.SelectedLanguage = languageName;
return View(view, model);
}
Now in your view, use the DropDownListFor helper method
#model YourPageViewModel
#Html.DropDownListFor(m => m.SelectedLanguage, languages,
new { #class = "form-control" });
Assuming languages is a list of SelectListItem's. Replace it with the collection you have to render the dropdown items.
The helper will render the dropdown with the name and id SelectedLanguage. So make sure you update that in your javasacript as well.
$(function() {
$("#SelectedLanguage").change(function() {
var activeLanguage = $(this).val();
window.location.href = "#Url.Action("index","Home")?languageName="
+ activeLanguage +"&id=#Guid.NewGuid()";
});
});

max json length error when populating telerik grid

I am trying to populate a telerik grid from a table based on date selected.
I get an error message:
System.InvalidOperationException: Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property
Is there any other way I can populate Telerik grids on client events?
view:
<%= Html.Telerik().DatePicker().Min("01/01/2011")
.Name("Date")
.ClientEvents(e => e.OnChange("Date_onChange"))
%>
<div>
<%= Html.Telerik().Grid<DataAccess.Entity.Dto.ReportData>()
.Name("tblGrid")
.DataBinding(databinding => databinding.Ajax()
.Select("MasterDataGrid", "Report"))
.Columns(col =>
{
col.Bound(f => f.ID).Title("ID Number");
col.Bound(f => f.Date).Title("Date");
})
.Filterable(filter => filter.Enabled(true))
.Pageable(page => page.PageSize(200))
.Sortable(sort => sort.Enabled(true))
%>
</div>
JavaScript:
function Date_onChange() {
var link = '/Report/DataGrid';
var Date = $("#Date").val().toString();
$.ajax({
type: 'POST',
url: link,
data: { date: Date },
dataType: 'json',
success: function (result) {
$("#tblGrid").data("tGrid").dataBind(result.data);
},
error: function (result) {
$("#ErrorMessage").text(result.message);
}
});
};
Controller:
[HttpPost]
[GridAction]
public ActionResult DataGrid(DateTime date)
{
var model = context.GetReportData_tblData(date);
return View(new GridModel { Data = model });
}
It looks like you are returning far too much data. There are two possible scenarios here, and it may be one or the other or both.
(1) As your page size is 200, this implies that you are expecting a lot of data, so you may be returning far too many objects. By default, the Telerik Grid will take the entire collection and do the sorting and filtering client-side. I would try implementing server-side paging and sorting so that you only return 1 page of data at a time.
View:
#(Html.Telerik.Grid<IEnumerable<MyClass>>()
.Name("MyGrid")
.Columns(col => // column definitions)
.EnableCustomBinding(true)
.Pageable(pg =>
{
paging.Total(Model.TotalCount);
paging.PageSize(Model.PAGE_SIZE);
})
.DataBinding(db =>
{
db.Ajax().Select("DataGrid", "MyController");
}
)
Controller:
[GridAction(EnableCustomBinding = true)]
public ActionResult DataGrid(GridCommand command, DateTime date)
{
MyModel model = new MyModel();
IEnumerable<MyClass> data = context.GetReportData_tblData(date);
// apply paging, filtering, grouping, and sorting
GridModel gm = data.AsQueryable().ToGridModel(command.Page, command.PageSize, command.SortDescriptors, command.FilterDescriptors, command.GroupDescriptors);
return View(gm);
}
Telerik provides a handy extension method to apply all the paging, sorting, filtering and grouping: IQueryable<T>.ToGridModel(), which you can find in the Telerik.Web.Mvc.Extensions assembly (h/t: vladimir77).
(2) If your DataAccess.Entity.Dto.ReportData class has a lot of properties, and/or some of its properties have long strings or child objects which are also recursively serialized, then you can easily hit the transfer limit with just a few objects. I notice you are only using two properties in the Grid. Please consider creating view model objects that only have the data that you need (that's good practice anyway).
You can increase the default JavaScriptSerializer.MaxJsonLength. Just see this answer: https://stackoverflow.com/a/7207539/443379
After this the filtering, paging... functionality won't work anymore. All you have to do though is use CustomBinding (inspired from #howcheng's answer):
[GridAction(EnableCustomBinding=true)]
public ActionResult DataGrid(GridCommand command, DateTime date)
{
var data = context.GetReportData_tblData(date)
.ToGridModel(command.Page, command.PageSize, command.SortDescriptors, command.FilterDescriptors, command.GroupDescriptors);
var serializer = new JavaScriptSerializer();
var result = new ContentResult();
serializer.MaxJsonLength = Int32.MaxValue; // overriding the default max length
result.Content = serializer.Serialize(data);
result.ContentType = "application/json";
return result;
}
This works even for Client Operation Mode. You can refactor this to a class: http://macaalay.com/2011/09/27/large-json-result-for-teleriks-mvc-grid/

MVC Controller return Content instead of JSON

I've been working on a project were all of my requirements involved JSON. However now suddenly I have a need to return results from my model that can be used in an input elements value field. I can't use the solution I have been as I get objects returned instead of plain text for the value. This is the controller pattern I have been using:
public virtual JsonResult fooData()
{
var fooresults = new fooQueries().fooTotal();
return new JsonResult
{ JsonRequestBehavior = JsonRequestBehavior.AllowGet, Data = fooresults };
}
Is there a way to use return content instead of JsonResult? I'm fairly new to the .NET MVC framework and having some difficulty finding the correct way to do this.
My current results are formatted like this:
[{ "foo", 3 }]
Instead I would prefer to get plain text so that I can use an AJAX request to pass the 3 value into an input elements value="" field.
AJAX call I am using with the controller:
$.ajax({
type: 'GET',
url: $('#fooValue').data('url'),
success: function (data) {
$('#fooValue').val(data);
}
});
The data-url is equivalent to:
../fooController/fooData
I'm just using T4MVC.
Return a ContentResult instead of a JsonResult
public virtual ContentResult gooData()
{
var fooresults = new fooQueries().fooTotal();
return Content(fooresults);
}
You can return content as:
return Content(fooresults);
But this wont be clean to you separate the elements as JSON return is.
I'm not sure what the shape of fooresults is, but you should be able to alter your AJAX call to the following:
$.ajax({
type: 'GET',
url: $('#fooValue').data('url'),
success: function (data) {
$('#fooValue').val(data.foo);
}
});
If the dataType property of the jQuery ajax call isn't explictly set, then jQuery will try and infer the type of the return result based on the MIME type, which in your case will be JSON. Therefore jQuery will deserialise the JSON to a JSON object. See http://api.jquery.com/jQuery.ajax/ for more info.
to return a Json, the method should be changed as follow:
public JsonResult fooData()
{
var fooresults = new fooQueries().fooTotal();
return Json(fooresults , JsonRequestBehavior.AllowGet);
}

How to implement Server side paging in Client side Kendo UI grid in asp.net mvc

Can anyone tell me how can I implement server-side paging with client-side Kendo UI Grid?
UPDATE: We have released an open source .NET library which makes paging, sorting an filtering a lot easier.
The grid will send the current pageSize and skip once you set serverPaging to true. On the server side you should page your data using the provided info and return it together with the total number of items. Here is a code snippet:
Action
public ActionResult Products(int pageSize, int skip)
{
using (var northwind = new NorthwindDataContext())
{
var products = northwind.Products;
// Get the total number of records - needed for paging
var total = products.Count();
// Page the data
var data = products.Skip(skip).Take(pageSize).ToList();
// Return as JSON - the Kendo Grid will use the response
return Json(new { total = total, data = data });
}
}
View
$("#grid").kendoGrid({
dataSource: {
transport: {
read: {
url: "home/products",
dataType: "json",
type: "POST"
}
},
schema: {
data: "data", // records are returned in the "data" field of the response
total: "total" // total number of records is in the "total" field of the response
},
serverPaging: true // enable server paging
}
});
Reference
Paging with LINQ
Take() and Skip()
DataSource configuration settings
serverPaging
schema.data
schema.total
The accepted answer does not have a UI solution; only provides a jQuery answer. In case it helps anyone else, here is the solution that worked for our kendo grid in UI:
code snippet of Controller
DataSourceResult result = new DataSourceResult()
{
Data = dataSet,
Total = recordCount
};
return Json(result, JsonRequestBehavior.AllowGet);
code snippet of View
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("*<our method>*", "*<our controller>*")
)
To implement server pagination, correct format should be return from server. For server side paging JSON format will be something like below JSON:-
{ "mytotal":1069, "mydata": [{ ProductID : 1, ProductName : "Chai"}, { ProductID : 2, ProductName : "Chang" }]}
Tell to kendo grid pick total number of records from mytotal object and data rows from mydata in schema
schema: {
data: "mydata"
total: "mytotal" // total is returned in the "total" field of the response
}
Check detail example here

How to send a model in jQuery $.ajax() post request to MVC controller method

In doing an auto-refresh using the following code, I assumed that when I do a post, the model will automatically sent to the controller:
$.ajax({
url: '<%=Url.Action("ModelPage")%>',
type: "POST",
//data: ??????
success: function(result) {
$("div#updatePane").html(result);
},
complete: function() {
$('form').onsubmit({ preventDefault: function() { } });
}
});
Every time there is a post, I need to increment the value attribute in the model:
public ActionResult Modelpage(MyModel model)
{
model.value = model.value + 1;
return PartialView("ModelPartialView", this.ViewData);
}
But the model is not passed to the controller when the page is posted with jQuery AJAX request. How can I send the model in the AJAX request?
The simple answer (in MVC 3 onwards, maybe even 2) is you don't have to do anything special.
As long as your JSON parameters match the model, MVC is smart enough to construct a new object from the parameters you give it. The parameters that aren't there are just defaulted.
For example, the Javascript:
var values =
{
"Name": "Chris",
"Color": "Green"
}
$.post("#Url.Action("Update")",values,function(data)
{
// do stuff;
});
The model:
public class UserModel
{
public string Name { get;set; }
public string Color { get;set; }
public IEnumerable<string> Contacts { get;set; }
}
The controller:
public ActionResult Update(UserModel model)
{
// do something with the model
return Json(new { success = true });
}
If you need to send the FULL model to the controller, you first need the model to be available to your javascript code.
In our app, we do this with an extension method:
public static class JsonExtensions
{
public static string ToJson(this Object obj)
{
return new JavaScriptSerializer().Serialize(obj);
}
}
On the view, we use it to render the model:
<script type="javascript">
var model = <%= Model.ToJson() %>
</script>
You can then pass the model variable into your $.ajax call.
I have an MVC page that submits JSON of selected values from a group of radio buttons.
I use:
var dataArray = $.makeArray($("input[type=radio]").serializeArray());
To make an array of their names and values. Then I convert it to JSON with:
var json = $.toJSON(dataArray)
and then post it with jQuery's ajax() to the MVC controller
$.ajax({
url: "/Rounding.aspx/Round/" + $("#OfferId").val(),
type: 'POST',
dataType: 'html',
data: json,
contentType: 'application/json; charset=utf-8',
beforeSend: doSubmitBeforeSend,
complete: doSubmitComplete,
success: doSubmitSuccess});
Which sends the data across as native JSON data.
You can then capture the response stream and de-serialize it into the native C#/VB.net object and manipulate it in your controller.
To automate this process in a lovely, low maintenance way, I advise reading this entry that spells out most of native, automatic JSON de-serialization quite well.
Match your JSON object to match your model and the linked process below should automatically deserialize the data into your controller. It's works wonderfully for me.
Article on MVC JSON deserialization
This can be done by building a javascript object to match your mvc model. The names of the javascript properties have to match exactly to the mvc model or else the autobind won't happen on the post. Once you have your model on the server side you can then manipulate it and store the data to the database.
I am achieving this either by a double click event on a grid row or click event on a button of some sort.
#model TestProject.Models.TestModel
<script>
function testButton_Click(){
var javaModel ={
ModelId: '#Model.TestId',
CreatedDate: '#Model.CreatedDate.ToShortDateString()',
TestDescription: '#Model.TestDescription',
//Here I am using a Kendo editor and I want to bind the text value to my javascript
//object. This may be different for you depending on what controls you use.
TestStatus: ($('#StatusTextBox'))[0].value,
TestType: '#Model.TestType'
}
//Now I did for some reason have some trouble passing the ENUM id of a Kendo ComboBox
//selected value. This puzzled me due to the conversion to Json object in the Ajax call.
//By parsing the Type to an int this worked.
javaModel.TestType = parseInt(javaModel.TestType);
$.ajax({
//This is where you want to post to.
url:'#Url.Action("TestModelUpdate","TestController")',
async:true,
type:"POST",
contentType: 'application/json',
dataType:"json",
data: JSON.stringify(javaModel)
});
}
</script>
//This is your controller action on the server, and it will autobind your values
//to the newTestModel on post.
[HttpPost]
public ActionResult TestModelUpdate(TestModel newTestModel)
{
TestModel.UpdateTestModel(newTestModel);
return //do some return action;
}
I think you need to explicitly pass the data attribute. One way to do this is to use the
data = $('#your-form-id').serialize();
This post may be helpful.
Post with jquery and ajax
Have a look at the doc here..
Ajax serialize
you can create a variable and send to ajax.
var m = { "Value": #Model.Value }
$.ajax({
url: '<%=Url.Action("ModelPage")%>',
type: "POST",
data: m,
success: function(result) {
$("div#updatePane").html(result);
},
complete: function() {
$('form').onsubmit({ preventDefault: function() { } });
}
});
All of model's field must bo ceated in m.
In ajax call mention-
data:MakeModel(),
use the below function to bind data to model
function MakeModel() {
var MyModel = {};
MyModel.value = $('#input element id').val() or your value;
return JSON.stringify(MyModel);
}
Attach [HttpPost] attribute to your controller action
on POST this data will get available

Resources