I'm trying to use a Kendo grid for the first time: Here's the code for the grid:
#model IEnumerable<SustIMS.Models.ModelTest>
<div id="grid">
#(Html.Kendo().Grid(Model)
.Name("datagrid")
.Columns(columns =>
{
columns.Bound(c => c.Genre).Width(140);
columns.Bound(c => c.Title).Width(190);
columns.Bound(c => c.ReleaseDate);
columns.Bound(c => c.Price).Width(110);
})
.HtmlAttributes(new { style = "height: 90%;" })
.Scrollable()
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Show", "MasterData"))
)
)
</div>
This displays the grid without any data in it. I've created a test model and am trying to add data like this in the controller:
public ActionResult Show()
{
var list = new List<ModelTest>();
list.Add(new ModelTest { Title = "A Title", Price = 10.5m, ReleaseDate = DateTime.Now, ID = 1, Genre = "zz" });
list.Add(new ModelTest { Title = "B Title", Price = 11.5m, ReleaseDate = DateTime.Now, ID = 2, Genre = "zzzzzz" });
return Json(list);
}
This doesn't show any data in the grid. How can I pass data into it? And does it have to come from a model or can it be added in a custom way?
try this:
public ActionResult Show([DataSourceRequest] DataSourceRequest request)
{
var list = new List<ModelTest>();
list.Add(new ModelTest { Title = "A Title", Price = 10.5m, ReleaseDate = DateTime.Now, ID = 1, Genre = "zz" });
list.Add(new ModelTest { Title = "B Title", Price = 11.5m, ReleaseDate = DateTime.Now, ID = 2, Genre = "zzzzzz" });
return Json(list.ToDataSourceResult(request));
}
then put this in your controller:
using Kendo.Mvc.Extensions;
Related
Here is the code of the grid with the dropdown that I have inserted into a Kendo grid:
#model Portal.Web.Areas.Orders.Models.IngressoMerceViewModel
#(Html.Kendo().Grid<Portal.Web.Areas.Orders.Models.IngressoMerceGridViewModel>()
.Name("grid")
.Events(e => e.DataBound(#<text>function() {for (var i = 0; i #Html.Raw("<") this.columns.length; i++) {this.autoFitColumn(i);}}</text>))
.Columns(columns =>
{
columns.Template("<input type='checkbox' />");
columns.Bound(p => p.Posizione).Title("Posizione").Width(200);
columns.Bound(p => p.Materiale).Title("Materiale").Width(200);
columns.Bound(p => p.Description).Title("Testo breve").Width(200);
columns.Bound(p => p.WarehouseLogicStore).Editable("false").Width(200)
.ClientTemplate(Html.Kendo().DropDownList()
.Name("WHLogicValue").DataTextField("Code").DataValueField("Code").DataSource(source =>
{
source.Read(read =>
{
read.Action("WarehouseLogicTypes_Read", "IngressoMerce");
});
}).ToClientTemplate().ToString()
); ;
columns.Bound(p => p.Quantity).Title("Qta Ordine").Width(200);
columns.Bound(p => p.UnitOfMeasure).Title("UM").Width(200);
columns.Bound(p => p.ReceivedQty).Title("Qta giĆ ricevute").Width(200);
columns.Template("<input type='text' />").Title("Qta ricevute");
columns.Bound(p => p.InProgressQtyCheck).Title("Qta da ricevere").Width(200);
columns.Bound(p => p.ExpectedDeliveryDate).Format("{0:dd/MM/yyyy}").Title("Data consegna prevista").Width(200);
columns.Bound(p => p.QualityCheckNeeded).Title("Check qualitativo richiesto").Width(220);
})
.Pageable()
.Sortable()
.Scrollable()
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
//.Read(read => read.Url("/orders/details").Type(HttpVerbs.Get))
.Read(read => read.Action("OrderDetails_Read", "IngressoMerce", Model))
)
.Deferred(!Model.IsAjax)
)
Unfortunately, the dropdown shows as textbox and the respective action in the ASP.net MVC controller is not firing. Here is the code for the action:
[AllowAnonymous]
public async Task<JsonResult> WarehouseLogicTypes_Read()
{
try
{
var types = await gateway.GetWarehouseLogicTypes();
return Json(types);
}
catch (Exception ex)
{
//logger.LogError(ex.Message);
throw ex;
}
}
you can insert dropdown inside kendo grid using EditorTemplates
Your Index view code should be like this
#(Html.Kendo().Grid<DemoApplication.Models.ProductsModel>()
.Name("CategoryGrid")
.Columns(columns =>
{
columns.Bound(p => p.category).ClientTemplate("#=category.CategoryName#");
columns.Bound(c => c.ProductName);
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Scrollable()
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(x => x.Id);
})
.Read(read => read.Action("ListAll", "Test"))
.PageSize(10)
))
Add Editor Template(_CategoryEditor.cshtml) inside Shared/EditorTemplates folder
your _CategoryEditor code should be like this
#model DemoApplication.Models.Category
#(Html.Kendo().DropDownListFor(m => m)
.Name("category")
.DataValueField("CategoryId")
.DataTextField("CategoryName")
.BindTo((System.Collections.IEnumerable)ViewData["Category"]))
Model code
public class ProductsModel
{
public int Id { get; set; }
[UIHint("_CategoryEditor")]
public Category category { get; set; }
public string ProductName { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
}
Controller Code
public ActionResult Index()
{
ViewData["Category"] = GetCategories();
return View();
}
public List<Category> GetCategories()
{
List<Category> categories = new List<Category>();
categories.Add(new Category() { CategoryId = 1, CategoryName = "Category 1" });
categories.Add(new Category() { CategoryId = 2, CategoryName = "Category 2" });
categories.Add(new Category() { CategoryId = 3, CategoryName = "Category 3" });
return categories;
}
public ActionResult ListAll([DataSourceRequest] DataSourceRequest request)
{
List<ProductsModel> productsList = new List<ProductsModel>();
productsList.Add(new ProductsModel() { Id = 1, category = GetCategories().First(), ProductName = "Product 1" });
productsList.Add(new ProductsModel() { Id = 1, category = GetCategories().First(), ProductName = "Product 1" });
productsList.Add(new ProductsModel() { Id = 1, category = GetCategories().First(), ProductName = "Product 1" });
return Json(productsList.ToDataSourceResult(request));
}
I use the dropdown list as an EditorTemplate for a column in the grid:
#model Guid?
#(Html.Kendo().DropDownListFor(m => m)
.DataValueField("Id")
.DataTextField("Name")
.DataSource(dataSource =>
{
dataSource.Read(read => read.Action(MVC.Controller.ActionNames.ActionName_Read, MVC.Controller.Name))
.ServerFiltering(true);
})
.ValuePrimitive(true)
)
My Controller:
public virtual ActionResult ActionName_Read()
{
var applicationID = AppSettings.Id.Guid;
var return = _db.table.Where(w => w.ID == appID).Select(s => new { s.Name, Id = s.Guid});
return Json(return, JsonRequestBehavior.AllowGet);
}
My Column:
columns.Bound(c => c.Name).Filterable(f => f.UI("$.proxy(filterFunction, {field: Name})").Operators(o => o.ForString(e => e.Clear().IsEqualTo("Is equal to").IsNotEqualTo("Is not equal to")))).EditorTemplateName("EditorTemplateName");
I added .ValuePrimitive(true) and that returns the ID, but if I remove that, it returns [object object].
I have the Name and the ID return from the action, but only the name field gets populated, and it gets populated by the ID.
You can use the .ValueTemplate() property.
here is one example https://demos.telerik.com/aspnet-mvc/dropdownlist/template
.ValueTemplate("#:yourObject.Name#")
I looped into the change event of my DropDownList in the EditorTemplate and did the following:
function selectRow(name, event) {
var rowUid = $("#Name").closest("tr").attr("data-uid");
var rowItem = $("#" + name).data("kendoGrid").dataSource.getByUid(rowUid);
var currentName = event.sender._focused[0].textContent;
var currentDataSource = event.sender.dataSource._data;
for (var i = 0; i < currentDataSource.length; i++) {
if (currentDataSource[i].Name=== currentName) {
rowItem.set("Id", currentDataSource[i].Id);
rowItem.set("Name", currentDataSource[i].Name);
}
}
}
I have a kendo grid that returns all the results except for the first column, being the date. It is showing as blank. In my viewmodel the reviewdate is of type string. In my controller I have the reviewdate converted to a string. I know that reviewdate returns MM/dd/yyyy from debug.
Controller snippet:
foreach (var item in query)
{
model.Add(new PreviousReviewViewModel()
{
ReviewId = item.ReviewId,
ReviewDate = item.NextReviewDt.ToString("MM/dd/yyyy"),
Rating = item.Rating,
SubmittedFl = item.SubmittedFl
});
}
In my view i have the grid as follows:
#(Html.Kendo().Grid<PreviousReviewViewModel>()
.Name("Grid")
//.HtmlAttributes(new { style = "width:450px;" })
.Columns(columns =>
{
columns.Template(
#<text>
#Html.ActionLink(Model.ReviewDate, "SavedFormsIndex", new { Controller = "Forms", id = Model.ReviewId })
</text>).ClientTemplate(#"").Title("Review Date");
columns.Bound(m => m.Rating).Title("Composite Rating"); //rating is the avg
columns.Bound(m => m.SubmittedFl).Title("Submitted");
})
.Pageable(p => p.Numeric(false).PreviousNext(false).Refresh(true))
.Resizable(resize => resize.Columns(true))
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(2147483647)
.Read(read => read.Action("read_PrevProjReviews", "Forms", new { id = ViewBag.ProjectId }))
)
try change your client template
.ClientTemplate(#"#=ReviewDate#
I have a kendo Grid which pulls loads of data. To increase the performance i have set the ServerOperation(true), which hits the database for each pagination click to load only 20 records each time it hits.
But, kendo Grid Filter is not working when ServerOperation(true).
Here is the code.If we make ServerOperation false, the grid retrieves all the data at once which will hit the performance. Please suggest any solution to have the filter with ServerOperation true.
#(Html.Kendo().Grid<ViewModel>().Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.Id).Hidden();
columns.Bound(p => p.Number).Filterable(filterable => filterable.UI("NumberFilter")).Width("150px").Locked(true);
})
.Filterable().Sortable()
.Resizable(resizing => resizing.Columns(true))
.Reorderable(reordering => reordering.Columns(true))
.Pageable().Scrollable(scr => scr.Height(580))
.DataSource(dataSource => dataSource.Ajax().PageSize(20)
.Read(read => read.Action("LoadTransaction", ControllerName.).Data("geton"))
))
public ActionResult LoadTransaction(int clientid, string id)
{
PagingInfo gvpi = UiControls.GetGridViewPagingInfo(Request.Form);
gvpi.FilterColumns.Add(new PagingColumn() { Name = "ClientId", Value = clientId.ToString(), IsFullTextFilter = true });
gvpi.FilterColumns.Add(new PagingColumn() { Name = "Id", Value = Id, IsFullTextFilter = true });
gvpi.PageSize = 20;
var pagedResult = _contextservice.GetAllByPage(gvpi);
return UiControls.GetGridViewDataAsJson(pagedResult.GridData, pagedResult.RecordCount);
}
function geton()
{
var clientId = $('#ClientId').val();
var Id = $('#Id').val();
return { clientId: clientId, Id: divisionId }
}
Thanks,
Namitha
I am using a master-detail Telerik MVC Grid on two levels.
The first level contains a drop-down of Customers and some misc data.
The second level contains a drop-down of Cars that are linked to the customer on the first level and some misc data.
I am now using a foreign key column to show the dropdowns of cars and clients.
How can the second dropdown be filtered by the customer on the first level?
Code:
#(Html.Telerik().Grid<Models.ClientsModel>()
.Name("Grid")
.ToolBar(commands => commands.Insert().ButtonType(GridButtonType.ImageAndText))
.DataKeys(keys => keys.Add(c => c.ClientLineID))
.Columns(columns =>
{
columns.ForeignKey(o => o.ClientID, (System.Collections.IEnumerable)ViewBag.Client, "ClientID", "Name")
.Width(330)
.Title("Client");
columns.Command(commands =>
{
commands.Edit().ButtonType(GridButtonType.ImageAndText);
commands.Delete().ButtonType(GridButtonType.ImageAndText);
}).Width(250);
})
.DetailView(car => car.ClientTemplate(
Html.Telerik().Grid<Delta.Models.CarModel>()
.Name("Car_<#= ClientID #>")
.DataKeys(keys => keys.Add(c => c.LineID))
.ToolBar(commands => commands.Insert().ButtonType(GridButtonType.ImageAndText))
.DataBinding(dataBinding =>
{
dataBinding.Ajax()
.Select("_CarLineIndex", "Client", new { id = "<#= ClientID #>" })
.Insert("_CarLineCreate", "Client", new { id = "<#= ClientID #>" })
.Update("_CarLineUpdate", "Client")
.Delete("_CarLineDelete", "Client");
})
.Columns(columns =>
{
columns.ForeignKey(o => o.CarID, (System.Collections.IEnumerable)ViewBag.Cars,
"CarID", "No")
.Width(500)
.Title("Car");
columns.Command(commands =>
{
commands.Edit().ButtonType(GridButtonType.ImageAndText);
commands.Delete().ButtonType(GridButtonType.ImageAndText);
}).Width(200);
})
.Editable(editing => editing => editing.Mode(GridEditMode.InLine))
.Scrollable(c => c.Height("auto"))
.Resizable(resizing => resizing.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
.KeyboardNavigation()
.Footer(false)
.ToHtmlString()
))
.DataBinding(dataBinding =>
{
dataBinding.Ajax()
.Select("_ClientIndex", "Client")
.Insert("_ClientCreate", "Client")
.Update("_ClientUpdate", "Client")
.Delete("_ClientDelete", "Client");
})
.Scrollable(c => c.Height("auto"))
.Editable(editing => editing.Mode(GridEditMode.InLine))
.Pageable(o => o.PageSize(50))
.Filterable()
.KeyboardNavigation()
.Groupable())
I am thinking that the code might involve some javascript on the OnDetailViewExpand event, but I can't figure out what.
The only solution I have now is to split the grid into separate views and build cascasing comboboxes there.
Unfortunately I cannot comment on posts yet to clarify some facts about your question. I'll make some assumptions in my answer so that we can work out the exact nature of the problem. You have two model classes one for each grid ClientsModel and CarModel. You are filtering the CarModel (second)grid with fields from the ClientsModel (first)grid.
You are not restricted to just one(<= ClientID =>) parameter in your select binding. You can use other fields from the ClientsModel class the same way as ClientID.
Sample Code:
dataBinding.Ajax().Select("_CarLineIndex", "Client", new { id = "<#= ClientID #>", city = "<#= City #>" })
Here is a working example with mock data that illustrates the method mentioned above:
Client Class
public class Client
{
public int ClientId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string City { get; set; }
}
Car Class
public class Car
{
public string Make { get; set; }
public string Model { get; set; }
public int Year { get; set; }
public string Color { get; set; }
}
HomeController
[GridAction]
public ActionResult _Index()
{
Client c1 = new Client() { ClientId = 1, City = "Boston", FirstName = "Ted", LastName = "Boder" };
Client c2 = new Client() { ClientId = 2, City = "New York", FirstName = "Chris", LastName = "Tobb" };
Client[] clients = {c1, c2};
return View(new GridModel(clients));
}
[GridAction]
public ActionResult _Cars(int ClientId, string City)
{
Car c1 = new Car() { Color = "Yellow", Make = "Ford", Model = "Mustang", Year = 2012 };
Car c2 = new Car() { Color = "Black", Make = "Toyota", Model = "Camry", Year = 2010 };
Car[] cars = { c1, c2 };
return View(new GridModel(cars));
}
View
#(Html.Telerik().Grid<Client>()
.Name("Clients")
.Columns(columns =>
{
columns.Bound(o => o.FirstName);
columns.Bound(o => o.LastName);
columns.Bound(o => o.City);
})
.DetailView(clientDetailView => clientDetailView.ClientTemplate(
Html.Telerik().Grid<Car>()
.Name("ClientDetails_<#= ClientId #>")
.Columns(columns =>
{
columns.Bound(c => c.Make);
columns.Bound(c => c.Model);
columns.Bound(c => c.Year);
columns.Bound(c => c.Color);
})
.DataBinding(db2 => db2.Ajax().Select("_Cars", "Home", new { ClientID = "<#= ClientId #>", City = "<#= City #>" }))
.Pageable()
.Sortable()
.ToHtmlString()
))
.DataBinding(db1 => db1.Ajax().Select("_Index", "Home"))
.Pageable()
.Sortable()
.Filterable()
)
As you can see from the example I'm also passing a City parameter as well as a ClientId when binding the grid.
Let me know if I missed something.
You are correct that you will need to do this with javascript, and it is a matter of being able to filter cars by customers. Telerik allows you to add additional parameters using the "e.data" argument for most of their controls. So for example if you wanted to filter a city list based on a select state the CSHTML would look like this:
<td valign="top">
#(Html.Telerik().DropDownListFor(m => m.State)
.Name("State")
.ClientEvents(events => events.OnChange("State_Change"))
.BindTo(new SelectList(Model.GetStates()))
.HtmlAttributes(new { style = string.Format("width:{0}px", 160) })
)
</td>
<td valign="top">
#(Html.Telerik().AutoCompleteFor(m => m.City)
.Name("City")
.Encode(false)
.ClientEvents(events => {
events.OnDataBinding("City_AutoComplete");
})
.DataBinding(a => a.Ajax().Select("CityList", "Location"))
.AutoFill(true)
.HighlightFirstMatch(true)
.HtmlAttributes(new { style = string.Format("height: 17px; width:{0}px", 250) })
)
</td>
The javascript would look like this:
function City_AutoComplete(e) {
//pass state as an additional parameter here to filter
//this would be your customer for cars list
e.data = $.extend({}, e.data, { state: $("#State").val() });
}
function State_Change(e) {
//reset when the parent list selection changes
$('#City').data('tAutoComplete').text('');
$('#City').data('tAutoComplete').value('');
}
Nothing to complex, create client event onEdit, you can found sample on telerik demo, than after once created client write down dropedown selection change event code that will filter data for you car dropdown. to do this I would suggest you to call ajax and insert HTml for dropdown. If you have still doubt than let me know I will explain it in detail.
If you you really find this answer best or appropriate please vote it.. it will help...