I am using Inline editing in a Kendo Grid and I want to be able to get the current row data when doing an update.
Html.Kendo().Grid<WheresMyTool.Models.COMPANYADDRESS>()
.Name("ShipToLocationsGrid")
.Editable(editable => editable.Mode(Kendo.Mvc.UI.GridEditMode.InLine))
.Pageable(pager => pager.PageSizes(new List<object> { 5, 10, 20, 100 }))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.COMPANY))
.Read(read => read.Action("IndexShipToLocations", "Company", new { company = Model.company }))
.Update(update => update.Action("ShipToLocations_Update"))
.PageSize(20)
)
Here is my update method
public ActionResult ShipToLocations_Update([DataSourceRequest] DataSourceRequest request, COMPANYADDRESS ca)
{
Repository repo = new Repository();
repo.UpdateCompanyAddressRecord(ca, username);
return Json(ca);
}
I want to be able to access the current data. It seems like only the modified data is passed in.
[HttpPost]
public ActionResult EditTestStationInLine([DataSourceRequest] DataSourceRequest request, TestStationViewModel tsvm)
{
if(tsvm != null && ModelState.IsValid)
{
TestStation ts = _testStationService.Find(tsvm.Id);
ts.ProductionLineId = tsvm.ProductionLineId;
ts.ProdLine = _productionLineService.Find(tsvm.ProductionLineId);
ts.Name = tsvm.Name;
_testStationService.Update(ts);
tsvm.Id = ts.Id;
tsvm.ProductionLineId = ts.ProductionLineId;
}
return this.Json(new[] { tsvm }.ToDataSourceResult(request, ModelState));
}
This is an example of one of my InLine edits. Your view model is used to create a database model. Once your database model is created, you can pass back the hidden attributes, in my case the Id and CreateAt. Hope this helps answer your question.
Edit:
function Edit(e) {
var grid = $('#NAMEOFKENDOGRID').data('kendoGrid');
var dataItem = grid.dataItem($(e.target).parents('tr'))
var id = dataItem.id;
$.ajax({//Makes an ajax call
success: function (data) {
$('#NAMEOFDIV').load("/Controller/Update/" + id);
}
});
}
You can make a custom command, conveniently called Edit, which then gets the Id from that row. It also makes an ajax call to your update method. Modify the ajax to fit your needs.
Related
I am trying to create a Kendo Dropdownlist and it will not call the read.Action for some reason. I cannot figure out what I am missing.
I have set the read.Action to different methods and it works but it just will not call it to this specific method. I have verified that I am spelling it correctly and I've set breakpoints on everything to find what it runs.
#(Html.Kendo().DropDownList()
.Name("productionline-dropdown")
.DataTextField("Id")
.DataValueField("Name")
.DataSource(source =>
{
source.Read(read => { read.Action("GetDropDownList", "Home"); });
})
)
[HttpPost]
public JsonResult GetDropDownList()
{
var productionLines = _productionLineService.GetAll().Select(x => new ProductionLineViewModel
{
Id = x.Id,
Name = x.Name,
CreatedAt = x.CreatedAt,
UPE = x.UPE,
ComputerName = x.ComputerName,
ActiveLine = x.ActiveLine
});
return Json(productionLines, JsonRequestBehavior.AllowGet);
}
I want my DropDownList to populate with the Names of the ProductionLines not the Ids. Thanks
This is because the action is decorated with HttpPost, while the control apparently sends Get (quite logically) to fetch the data. Remove this attribute, and that should fix it.
So I'm trying to get a simple Kendo treeview to bind to JSON data but I am having a hard time. Any ideas why this isn't working? I put a break point on my JSON result code, but it never even fires.
My HTML:
#(Html.Kendo().TreeView()
.Name("treeview")
// The property that specifies the text of the node
.DataTextField("Name")
.LoadOnDemand(true)
.DataSource(dataSource => dataSource
.Read(read => read
// The action method which will return JSON
.Action("ReadCats", "Entity")
.Data("Id")
)
)
)
My Controller:
public JsonResult ReadCats(int? id)
{
var categories = _entityLogic.GetActiveCategories();
var jsonResult = categories.Select(cat => new
{
Id = cat.Id,
Name = cat.Name,
HasChildren = categories.Where(c => c.ParentCategory == cat.Id).Any(),
ParentId = cat.ParentCategory
}).ToList();
return Json(jsonResult, JsonRequestBehavior.AllowGet);
}
Now if I browse to myapplication/Admin/Entity/ReadCats, I do get the JSON data back. Like I said though, the breakpoint never hits when I load the view the tree is on.
Any ideas? I'd note that I've tried every variation of .Action("ReadCats", "Entity") I can think of like: .Action("ReadCats", "/Admin/Entity"), .Action("ReadCats", "~/Admin/Entity"), etc.
I'm trying to use Teleric's Kendo Grid in ASP.NET MVC 5. I'm following the example here, but the grid is not populating with data. The columns show up, but it says "No items to display".
http://docs.telerik.com/kendo-ui/getting-started/using-kendo-with/aspnet-mvc/helpers/grid/ajax-binding
This is my Words/Read function:
public ActionResult Read([DataSourceRequest] DataSourceRequest request)
{
var items = db.Words.Take(1).ToList();
//this code was necessary to get the correct JSON result
JsonSerializerSettings jsSettings = new JsonSerializerSettings();
jsSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
var converted = JsonConvert.SerializeObject(items, null, jsSettings);
return Content(converted);
}
I got the following JSON result from Words/Read:
[{"WordId":1,"Rank":1,"PartOfSpeech":"article","Image":"Upload/29/1/Capture1.PNG","FrequencyNumber":"22038615","Article":null,"ClarificationText":null,"WordName":"the | article","MasterId":0,"SoundFileUrl":"/UploadSound/7fd752a6-97ef-4a99-b324-a160295b8ac4/1/sixty_vocab_click_button.mp3","LangId":1,"CatId":null,"IsActive":false}]
Finally, my view page:
#(Html.Kendo().Grid<NextGen.Models.Word>
()
.Name("grid")
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(15)
.Read(read => read.Action("Read", "Words"))
)
.Columns(columns =>
{
columns.Bound(c => c.WordName);
columns.Bound(c => c.PartOfSpeech);
})
.Pageable()
.Sortable()
)
I've seen some similar questions to this one, but most are using Javascript rather than Html helpers. Am I doing something dumb?
I found an alternative way to get around the circular reference problem I was having. Basically, the answer is here: A circular reference was detected while serializing an object of type 'SubSonic.Schema .DatabaseColumn'.
For people with the same problem: I took the two properties I needed - WordName and PartOfSpeech, and passed only those attributes to the toDataSource function Kendo provides.
My new read function looks like this:
public ActionResult Read([DataSourceRequest] DataSourceRequest request)
{
var items = db.Words.Select(w => new WordL{
WordName = w.WordName,
PartOfSpeech = w.PartOfSpeech
});
return Json(items.ToDataSourceResult(request));
}
where WordL is a model with just PartOfSpeech and WordName attributes, rather than all the attributes of my class.
It is probably because you are not using 2 methods in your controller. While your page view is first ActionResult you should use second one as in the grid as you did in your example. I hope it is obvious.
public ActionResult ReadPage()
{
return View();
}
public ActionResult Read([DataSourceRequest] DataSourceRequest request)
{
var items = db.Words.Take(1).ToList();
//this code was necessary to get the correct JSON result
JsonSerializerSettings jsSettings = new JsonSerializerSettings();
jsSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
var converted = JsonConvert.SerializeObject(items, null, jsSettings);
return Content(converted);
}
I am trying to implement Telerik's example on their site that binds to a remote data source. The grid displays, but there is never any data in it. I am getting a JSON result from my controller. I verified this by browsing directly to RemoteData/GetData and seeing the JSON string. It is populated with the correct data.
Also when I browse directly to localhost/RemoteData/RemoteData, I see it resolve correctly using Fiddler. (status code 200).
Here is the code from their example with my modifications to it. This is in my View
#(Html.Kendo().Grid<DataObjects.Car>()
.Name("grid")
.Columns(columns => {
columns.Bound(p => p.CarID);
columns.Bound(p => p.Make);
columns.Bound(p => p.Model);
columns.Bound(p => p.Year);
columns.Bound(p => p.Mileage);
})
.Pageable()
.Sortable()
.Scrollable()
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Read(read => read.Action("GetData", "RemoteData"))
)
)
Code in the controller:
public ActionResult GetData()
{
var cars = new List<Car>();
cars.Add(new Car { CarID = 1, Make = "Chevrolet", Mileage = 259301, Model = "Cavalier", Year = 2000 });
cars.Add(new Car { CarID = 2, Make = "DeLorean", Mileage = 44087, Model = "DMC-12", Year = 1981 });
cars.Add(new Car { CarID = 3, Make = "Honda", Mileage = 183000, Model = "Del Sol", Year = 1993 });
return Json(cars, JsonRequestBehavior.AllowGet);
}
when you do return Json(cars, JsonRequestBehavior.AllowGet); you return a JSON array to your Kendo Grid DataSource(the requestor), exactly like below:
[
{
"CarID": 1,
"Make": "Chevrolet",
"Mileage":259301,
"Model":"Cavalier",
"Year":2000
},
{
"CarID": 2,
"Make": "DeLorean",
"Mileage":44087,
"Model":"DMC-12",
"Year":1981
},
]
but your kendo DataSource expects a javascipt array in a different pre-defined schema then returned by your method.
You need to return the javascript array json in exactly same format as required by the grid. Most simple way to do this is to make your grid_read ActionMethod like this:
public ActionResult GetData([DataSourceRequest] DataSourceRequest request)
{
///your usual code
return Json(cars.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
now your response is in acceptable schema definition by the kendo grid on the client side.
Also, if you don't wish or simply can't change the server side definition then you can directly bind the simple json array returned, to your kendoGrid by doing dataSource.read(response);
Please try with the below code snippet.
using Kendo.Mvc.UI;
using Kendo.Mvc.Extensions;
...............
...............
public ActionResult GetData([DataSourceRequest] DataSourceRequest request)
{
var cars = new List<Car>();
cars.Add(new Car { CarID = 1, Make = "Chevrolet", Mileage = 259301, Model = "Cavalier", Year = 2000 });
cars.Add(new Car { CarID = 2, Make = "DeLorean", Mileage = 44087, Model = "DMC-12", Year = 1981 });
cars.Add(new Car { CarID = 3, Make = "Honda", Mileage = 183000, Model = "Del Sol", Year = 1993 });
return Json(cars.ToDataSourceResult(request));
}
I am using mvc4. On one of my page, it has Kendo Grid. I want to show 5 rows per page. I have no problem doing it using pure javascript, however, If I am using mvc helper. I got lost, couldn't find any samples online.
here's my javascript code.
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: {
type: "json",
serverPaging: true,
pageSize: 5,
transport: { read: { url: "Products/GetAll", dataType: "json"} },
schema: { data: "Products", total: "TotalCount" }
},
height: 400,
pageable: true,
columns: [
{ field: "ProductId", title: "ProductId" },
{ field: "ProductType", title: "ProductType" },
{ field: "Name", title: "Name" },
{ field: "Created", title: "Created" }
],
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
}
});
});
now if i am using mvc helper
#(Html.Kendo().Grid(Model)
.Name("Grid") //please help me to finish the rest
Update:
Adding the action code.
[HttpPost]
public ActionResult GetAll([DataSourceRequest]DataSourceRequest request, int id)
{
var products= ProductService.GetAll(id);
return Json(products.ToDataSourceResult(request));
}
GetAll method in the service layer:
public IQueryable<Product> GetAll(int id)
{
var products= ProductRepository.Get(p => p.Id== id && p.IsActive == true, null, "ProductionYear")
.OrderBy(o => o.Name); //.ToList();
return Product.Select(p => new ProductVM()
{
Name = p.Name,
ProductionYear= p.ProductionYear.Year.ToString()
Id = p.Id
}).AsQueryable();
}
now, if I run the app, i will get following error:
"LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression."}
in the GetAll method, I comment out the "ToList()". If I use ToList, everything works. but I will query all the rows back instead just those rows I needed for that page.
You can set the PageSize inside the DataSource method. So you will need something like:
#(Html.Kendo().Grid(Model)
.Name("Grid")
.DataSource(dataSource => dataSource.Ajax()
.PageSize(5)
.Read(c => c.Action("GetAll", "Products")
.Model(s => s.Id(m => m.Id)))
.Columns(columns =>
{
columns.Bound(m => m.ProductId).Title("ProductId");
//other colums
})
.Events(g => g.DataBound("somefunction"))
.Pageable(true))
You can find more info the KendoUI Grid's Asp.NET MVC wrappers documentation.
If you are not using Kendo's ASP.NET MVC wrappers and are using the Kendo JavaScript objects directly and you are trying to do server side paging, then you need to create your datasource as follows:
var dataSource = {
"type":"aspnetmvc-ajax",
"serverSorting": true,
"serverPaging": true,
"page": 1,
"pageSize": 8,
"schema": {
"data":"items",
"total":"count",
"errors":"errors"
}
};
And your Read controller method will look something like:
public ActionResult List_Read([DataSourceRequest]DataSourceRequest request) {
try {
var model = null /* prepare your model object here contain one page of grid data */;
// using Json.NET here to serialize the model to string matching the
// schema expected by the data source
var content = JsonConvert.SerializeObject(new { count = model.Count, items = model.Items }, Formatting.None);
return Content(content, "application/json");
}
catch (Exception exception) {
// log exception if you need to
var content = JsonConvert.SerializeObject(new { errors = exception.Message.ToString() }, Formatting.None);
return Content(content, "application/json");
}
}
type, serverSorting and serverPaging are important to make sure paging and sorting happens server-side. type must be aspnetmvc-ajax, otherwise the query data will not be recognized by the model binder that has been specified by the [DataSourceRequest] attribute in the Read method. You cannot omit that attribute unless you want to write your own custom modelbinder to parse the query data sent by the kendo dataSource, which does not conform to the modelbinding conventions used by the DefaultModelBinder in ASP.NET MVC.
The other answer will work if you are using Kendo UI for ASP.NET MVC. If you don't you need to implement paging yourself. The Kendo DataSource will send pageSize and current page when making a request. You can use that to do the paging. It also sends "take" and "skip" which makes things even easier (hint Linq).
The error
"LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression."}
is self explanatory, to gat around this, you should do something like
return Product.**AsEnumerable**.Select(p => new ProductVM()
{
Name = p.Name,
ProductionYear= p.ProductionYear.Year.ToString()
Id = p.Id });
using AsEnumerable brings all records from the db, so best to use after any filtering
products.where(x => x.active = true).AsEnumerable
rather then
products.AsEnumerable.where(x => x.active = true)
Download kendo examples, then unzip and follow
<your directory>\Kendo UI for ASP.NET MVC Q1 2013\wrappers\aspnetmvc\Examples\Areas\razor\Views\web\grid\
for the view index
and
<your directory>\Kendo UI for ASP.NET MVC Q1 2013\wrappers\aspnetmvc\Examples\Controllers
for IndexController
in your view you might also want .ServerOperation(true) as bellow to avoid
Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.
If you have big data to fetch
#(Html.Kendo().Grid(<yourmodel>)
.Name("Grid")
.Columns(columns =>
...
})
.Filterable()
.Pageable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(8)
.ServerOperation(true) )
.Model(model =>
{
model.Id(p => p.Id);
...
})
)
)
also in controller in ActionResult Products_Read consider
DataSourceResult result = GetProducts().ToDataSourceResult(request, o => new { Id = o.Id, ... } );
return Json(result , JsonRequestBehavior.AllowGet);