I have this Kendo UI Grid in a ASP-NET MVC Web Application with Kendo UI
/*GRID*/
#(Html.Kendo().Grid(Model).Name("contactos")
.Columns(columns =>
{
..........
})
.ToolBar(toolBar =>
{
toolBar.Create();
toolBar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Groupable().Pageable().Sortable().Scrollable().Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
.......
}
)
.Read(read => read.Action("GetAllContactsClientJSON", "CrmCProfile", new { Id_Cliente = #ViewBag.Id_Cliente }))
.Create(create => create.Action("AddContact", "CrmCProfile"))
.Update(update => update.Action("UpdateContact", "CrmCProfile").Type(HttpVerbs.Post))
)
When I do Update, in the next controller Action :
/*Controller Action Update */
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateContact([DataSourceRequest] DataSourceRequest request,IEnumerable<ContactosClientesVM> contactos)
{
if (contactos != null && ModelState.IsValid)
{
...
}
return Json(ModelState.ToDataSourceResult());
}
}
The IEnumerable contactos = null,
Help!
Kendo Grid is not a form element and it cannot be simply posted to the server.
You can take advantage of the templates that the Grid provide and create hidden elements based on the different row models which to be submitted to the server.
Check:
Post the Kendo Grid Data on Form Submit
Related
Telerik MVC grid column not identified until I add
#model IEnumerable<NTI.Data.EDC.LabUnit> as first line of my view. However when I do add this line.
Telerik MVC Grid loads with data and also shows ups all buttons. But Insert, Update and delete events not getting triggered. There is no Javascript error in the browser console window. And I also noticed there is no form action for Insert/Update/Delete buttons created by telerik. Please help.
My code ref: http://www.telerik.com/help/aspnet-mvc/telerik-ui-components-grid-editing-ajax-editing.html
View
#(
Html.Telerik().Grid(Model)
.Name("Grid")
.DataKeys(dataKeys => dataKeys.Add( c.ID))
.ToolBar(commands => commands.Insert())
.DataBinding(dataBinding => dataBinding
//Ajax binding
.Ajax()
//Home.Index renders the grid initially
.Select("LabUnits", "Lab")
//Home.Insert inserts a new data record
.Insert("LabUnitsInsert", "Lab")
//Home.Update updates an existing data record
.Update("LabUnitsUpdate", "Lab")
//Home.Delete deletes an existing data record
.Delete("LabUnitsDelete", "Lab")
)
.Columns(columns =>
{
columns.Bound(c => c.ContactName);
columns.Bound(c => c.Country);
columns.Bound(c => c.BirthDay);
columns.Command(commands => commands
.Edit()
.Delete());
})
)
Controller
public class LabController : Controller
{
public ActionResult LabUnits()
{
IEnumerable<LabUnit> lbUnit = new LabUnitDB().SelectAll();
return View(new GridModel(lbUnit));
}
[HttpPost]
[GridAction]
public ActionResult LabUnitsInsert()
{
//insert
}
[HttpPost]
[GridAction]
public ActionResult LabUnitsUpdate(int id)
{
//update
}
[HttpPost]
[GridAction]
public ActionResult LabUnitsDelete(string id){
// Delete
}
}
I was able to fix the issue. Had to replace
.DataBinding(dataBinding => dataBinding
//Ajax binding
.Ajax()
with
.DataBinding(dataBinding => dataBinding
//Server binding
.Server()
So its server binding and not Ajax.
I have two <section> in the Index view of my MVC application and I want to render two partial views in these sections. There is no problem rendering a Kendo grid to one Index. However, in order to render data on Kendo Grid, could I use the two methods returning Json in the controller as shown below. Could you give me an example how to achieve this?
Controller:
public ActionResult Index()
{
return View();
}
public ActionResult Issues_Read([DataSourceRequest]DataSourceRequest request)
{
IQueryable<Issue> issues = db.Issues;
DataSourceResult result = issues.ToDataSourceResult(request, c => new IssueViewModel
{
ID = c.ID,
ProjectID = c.ProjectID
});
return Json(result);
}
View:
#(Html.Kendo().Grid<IssueViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.ProjectID);
columns.Command(command => { command.Edit(); command.Destroy(); }).Width(180);
})
.ColumnMenu()
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Pageable()
.Navigatable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.ID))
.Read(read => read.Action("Issues_Read", "Issue"))
.Create(create => create.Action("Issues_Create", "Issue" ))
.Update(update => update.Action("Issues_Update", "Issue"))
.Destroy(destroy => destroy.Action("Issues_Destroy", "Issue"))
)
)
In order to use the same partial view multiple times, grid ID should be unique so passing the ID in partial view data is one possible solution. In your case
Partial view first call:
#Html.Partial("grid", new ViewDataDictionary { { "id", "grid1" }})
Partial view second call:
#Html.Partial("grid", new ViewDataDictionary { { "id", "grid2" }})
Partial view content:
#(Html.Kendo().Grid<IssueViewModel>()
.Name(#ViewData["id"].ToString())
...
Problem: When clicking on Update Button it does not call the controller Action. But the same work perfectly fine for Create/Read/Destroy. Anything that i am missing???? Please let me know.
View Code:
#(Html.Kendo().Grid<Model>()
.Name("XGrid")
.HtmlAttributes(new { style = "height: 525px;" })
.Columns(columns =>
{
//Columns...
})
.Editable(editable => editable.Mode(GridEditMode.InLine))
.ToolBar(toolbar =>
{
toolbar.Create();
})
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.Events(events =>
{
events.Edit("onEdit");
events.Save("onSave");
})
.Selectable(selectable => selectable.Type(GridSelectionType.Row))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(12)
.ServerOperation(true)
.Model(model =>
{
model.Id(ex => ex.User_ID);
})
.Update(update => update.Action("UpdateUser", "ViewUser"))
.Read(read => read.Action("UsersRetreive", "ViewUser"))
.Create(create => create.Action("CreateUser", "ViewUser"))
)
)
Controller Code:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateUser([DataSourceRequest] DataSourceRequest request,Login objUpdate)
{
if (ModelState.IsValid)
{
//Saving Code
}
else
return Json(objUpdate);
}
For GridEditMode.Inline, you have to use toolbar.Save() to save the data and hit the controller
Sure, It will not hit until you change event a one letter of any inline cell. It means if you not do modification it will not hit the action.
Try adding the HttpPost attribute to the action method, like this:
[HttpPost]
public ActionResult UpdateUser([DataSourceRequest] DataSourceRequest request,Login objUpdate)
{
}
Kendo is sending a POST and that current method is only accepting GET requests.
Also, make sure that the method is returning:
return Json(objUpdate.ToDataSourceResult(request, ModelState));
I want to use Kendo UI grid with filter option in APS.NET MVC.
In my example I use database as datasource and a student table
When I use student class as
public ActionResult Index()
{
var std = (from p in db.Students
select p).ToList();
return View("Student", std);
}
everything is ok.
But when I want use ViewModel as datasource, in runtime when I click in filter icon filter window open but I can't see anything in dropdown list of filter.
I use automapper and value injecter.
Any suggestion to solve this problem?
Appended
PersonController.cs
public class PersonController : Controller
{
Adventureworks2012DataContext db = new Adventureworks2012DataContext();
public ActionResult Index()
{
/*var prs = (from p in db.Person
select p).ToList();*/
return View(GetPersonViewModel());
}
public ActionResult PersonViewModel_Read([DataSourceRequest]DataSourceRequest request)
{
return Json(GetPersonViewModel().ToDataSourceResult(request));
}
private IList<PersonViewModel> GetPersonViewModel()
{
return db.Person.Project().To<PersonViewModel>().ToList();
}
}
Index.cshtml
#model IList<DevartLinqTestMVC.ViewModel.PersonViewModel>
#{
ViewBag.Title = "Person List";}
<br />
#(Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.Businessentityid);
columns.Bound(p => p.Persontype);
columns.Bound(p => p.Namestyle);
columns.Bound(p => p.Title);
columns.Bound(p => p.Firstname);
columns.Bound(p => p.Middlename);
columns.Bound(p => p.Lastname);
columns.Bound(p => p.Emailpromotion);
})
.Groupable()
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.Selectable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(m => m.Id(s => s.Businessentityid))
.PageSize(20)
.Read(read => read.Action("PersonViewModel_Read", "Person")))
)
everything is good also ajax work perfectly
but where is filter dropdown list?!!!
If you pass a list in your view it only works you want a static list that is loaded once. If you want server side paging or a toolbar, you need to load your data using a server side function that returns a JSON object and link it to your grid with .Read().
For example, in your controller (code not tested):
public ActionResult StudentGrid_Read([DataSourceRequest] DataSourceRequest request)
{
return Json((from p in db.Students select p).ToDataSourceResult(request));
}
And on your grid:
#(Html.Kendo()
.[other stuff]
.DataSource(dataSource => dataSource
.[other stuff]
.Read("StudentGrid_Read", "Controller")
)
)
See the kendo ui grid with toolbar demo for the complete coding example: http://demos.kendoui.com/web/grid/toolbar-template.html
Edit: just noticed there is a filtering demo as well, but the idea is the same:
http://demos.kendoui.com/web/grid/filter-menu-customization.html
i have a telerik grid as follow:
Html.Telerik().Grid<MatchViewModel>().Name("Matches").Columns(cols =>
{
cols.Bound(e => e.Name);
cols.Bound(e => e.Date);
cols.Bound(e => e.GuestTeamId);
cols.Bound(e => e.HostTeamId);
cols.Bound(e => e.PostponedDate);
==> cols.Bound(e => e.RefereeId).EditorViewData(new { RefereeName = '' });
cols.Bound(e => e.StatusId);
})
in the column reffered by arrow i wanna send referee name as additional data for EditorTemplate.i inferred from the EditorViewData method name that it can help me doing this.but i can't get it working.can anyone help me with this?
thanks.
If you have a well defined Model for your page you should not ever need to use ViewBag or ViewData, they are sloppy. EditorViewData allows you to create ViewData on-the-fly to pass extra data to your EditorTemplate.
For example, say you want to have different DropDownList values in the EditorTemplate for each item in your grid, you will need to pass extra data to do this. With EditorViewData you can add additional values from your Model for exactly that purpose without having to resort to coding up any ViewBag or ViewData objects in your Controller.
The first place I used it was a People grid that allowed editing of defined Qualifications added to a Qualifications grid inside a nested TabStrip. The trick was I didn't want the DropDownList for each person to contain any of the qualifications they already had earned. Like this...
People Grid
#using Kendo.Mvc.UI
#model PeopleViewModel
#(Html.Kendo().Grid<PersonModel>()
.Name("PersonGrid")
.Columns(columns => {
columns.Bound(b => b.LastName).EditorTemplateName("_TextBox50");
columns.Bound(b => b.FirstName).EditorTemplateName("_TextBox50");
...
columns.Command(cmd => { cmd.Edit(); cmd.Destroy(); }).Width(180);
})
.ClientDetailTemplateId("personTemplate")
.ToolBar(toolbar => toolbar.Create())
.Selectable()
.Editable(editable => editable.Mode(GridEditMode.InLine))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(a => a.Id);
})
.Create(create => create.Action("CreatePerson", "People"))
.Read(read => read.Action("ReadPeople", "People"))
.Update(update => update.Action("UpdatePerson", "People"))
.Destroy(destroy => destroy.Action("DestroyPerson", "People"))
)
.Events(events => events.DataBound("dataBound"))
)
<script type="text/javascript">
function dataBound() {
this.expandRow(this.tbody.find("tr.k-master-row").first());
}
</script>
<script id="personTemplate" type="text/kendo-tmpl">
#(Html.Kendo().TabStrip()
.Name("TabStrip_#=Id#")
.Items(items =>
{
...
items.Add().Text("Edit Qualifications")
.LoadContentFrom("PersonQualifications", "People", new {personId = "#=Id#"});
...
})
.ToClientTemplate()
)
</script>
PeopleViewModel
Ignore the inheritance stuff, it is beyond this discussion. But note that I use this same Model on all the sub Views related to this top level View.
public class PeopleViewModel : PageViewModel
{
public int PersonId { get; set; }
public PersonModel Person { get; set; }
public IList<QualificationModel> AllQualifications { get; set; }
...
public PeopleViewModel(BaseViewModel baseViewModel) : base(baseViewModel)
{}
}
PersonQualifications Controller
The data providers are injected elsewhere, but note the POCO to Model flattening - just a static method that applies a List to the Model constructor.
public ActionResult PersonQualifications(int personId)
{
SetBaseContext(HttpContext);
var model = new PeopleViewModel(BaseViewModel)
{
PersonId = personId,
AllQualifications = QualificationModel.FlattenToThis(_qualificationDataProvider.Read())
};
return View(model);
}
Nested Grid (View Loaded Inside TabStrip)
#using Kendo.Mvc.UI
#model PeopleViewModel
#{
Layout = null;
}
#(Html.Kendo().Grid<PersonQualificationModel>()
.Name("QualificationEditGrid_" + Model.PersonId)
.Columns(columns =>
{
columns.ForeignKey(f => f.QualificationId, Model.AllQualifications, "Id", "Display")
===> .EditorViewData(new {personId = Model.PersonId})
.EditorTemplateName("PersonQualificationDropDownList");
columns.Command(cmd =>
{
cmd.Edit();
cmd.Destroy();
}).Width(180);
})
.ToolBar(toolbar => toolbar.Create())
.DataSource(dataSource => dataSource
.Ajax()
.Events(events => events.Error("error_handler"))
.Model(model => {
model.Id(a => a.Id);
})
.Create(create => create.Action("CreatePersonQualification", "People"))
.Read(read => read.Action("ReadPersonQualifications", "People", new {personId = Model.PersonId}))
.Destroy(destroy => destroy.Action("DestroyPersonQualification", "People"))
)
)
The EditorTemplate (Finally!)
Ignore the first ViewData reference that helps make this EditorTemplate shared. The one we are interested in is a little further down.
#using Kendo.Mvc.UI
#(Html.Kendo().DropDownList()
.Name(ViewData.TemplateInfo.GetFullHtmlFieldName(""))
.DataValueField("Id")
.DataTextField("Name")
.OptionLabel("Select...")
.DataSource(dataSource => dataSource
===> .Read(read => read.Action("ReadDdlQualifications", "People", new {personId = ViewData["personId"]}))
)
)
Controller Method (Just to be Thorough)
public JsonResult ReadDdlQualifications(int personId)
{
var qualification = _qualificationDataProvider.ReadAvailableToPerson(personId);
IList<IdNamePair> results = IdNamePair.FlattenToThis(qualification);
return Json(results, JsonRequestBehavior.AllowGet);
}
Obviously there is a lot of other stuff going on in this example (I hope I left enough code in for it to make sense), but it should get across the point of when it is needed - and it is REALLY needed.
Enjoy.
I ran into the same issue as Chad and as Trey mentioned, this cannot be done via passing information to EditorViewData. There is no way to pass the row data item, only page data.
As an alternative you can add this script to the editor template. Then you can access a field value from the grid row and pass it to the datasource call, filtering the dropdownlist based on each rows data.
<script type="text/javascript">
function getParentId() {
var row = $(event.srcElement).closest("tr");
var grid = $(event.srcElement).closest("[data-role=grid]").data("kendoGrid");
var dataItem = grid.dataItem(row);
return { EmployeeId: dataItem.EmployeeId };
}
</script>
And then add the data item to the read method on the data source.
#(Html.Kendo().DropDownList()
.Name("Product")
.DataValueField("ProductId")
.DataTextField("ProductName")
.DataSource(ds => ds
.Read(read => read.Action("ProductsRead", "Home")
.Data("getParentId")
))
)