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.
Related
I am using Kendo UI in my asp.net mvc project.
I have an issue for displaying modal. In my grid, I want to add an extra column that has a button in it.
When the user clicks that button, I need to show a list from another table that has the ID of the current table, and show it in modal.
I would really appreciate if you could help me.
#(Html.Kendo().Grid<ClinicManagement.Models.Reagent>().Name("PersonGrid")
.Name("PersonGrid")
.Columns(columns =>
{
columns.Bound(p => p.Name).Filterable(ftb => ftb.Cell(cell => cell.Operator("contains").SuggestionOperator(FilterType.Contains))).Width(90);
columns.Bound(p => p.Family).Filterable(ftb => ftb.Cell(cell => cell.Operator("contains").SuggestionOperator(FilterType.Contains))).Width(90);
columns.Bound(p => p.CardNumber).Filterable(ftb => ftb.Cell(cell => cell.Operator("contains").SuggestionOperator(FilterType.Contains))).Width(90);
columns.Command(command => command.Custom("ViewDetails").Click("showDetails")).Width(150);
})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Events(events => events.Error("error_handler"))
.Sort(sort => sort.Add(p => p.Name).Ascending())
.Model(model => model.Id(p => p.Id))
.Create(update => update.Action("Create", "Reagents"))
.Read(read => read.Action("ReadReagent", "Reagents"))
.Update(update => update.Action("Edit", "Reagents"))
.Destroy(destroy => destroy.Action("Delete", "Reagents"))
))
OK, your code looks similar to the demo here. You just need to finish it up:
First, create a modal on the page:
#(Html.Kendo().Window().Name("Details")
.Title("Customer Details")
.Visible(false)
.Modal(true)
.Draggable(true)
.Width(300)
)
The sample uses a kendo template to display the details, so you could add a kendo list in there (you would need to use .ToHtmlString() since it is a nested control). I prefer a different approach where I can use a partial view with a view model:
Create a view model with the list items and other properties to display:
public class DetailsViewModel
{
public int PersonId { get; set; }
public string Name { get; set; }
... etc
public List<string> MyListItems;
}
Create a partial view for the details with a list (or grid) on it:
#model DetailsViewModel
<div>
... // Show fields, etc.
#(Html.Kendo().ListBox()
... other list options
.BindTo(Model.MyListItems)
.Deferred() // Need for nested control
</div>
Create a controller action to return the partial:
public PartialViewResult GetDetailsView(int personId)
{
// fetch data
// Fill the viewmodel
var vm = new DetailsViewModel
{
PersonId = data.PersonId,
Name = data.Name,
MyListItems = context.Items.Where(i => i.PersonId == personId).ToList()
}
return PartialView("_Details", vm);
}
The javascript code for the button click will open the window and tell it to load the partial view from controller action:
<script type="text/javascript">
function showDetails(personId) {
var wnd = $("#Details").data("kendoWindow");
wnd.refresh({
url: '#Url.Action("GetDetailsView","Person", new { personId = "__personid__" })'
.replace("__personid__", personId )
});
wnd.open();
}
</script>
Finally, change the custom command to pass in the Id:
.Click("showDetails(PersonId)")
EDIT - or use a template for your button:
columns.Template(t => { }).Width(150)
.ClientTemplate(#"<a class='btn btn-info btn-xs' onclick="showDetails(PersonId)">Details</a>");
I can't use edit and create command of a Kendo Grid, because binding always fails and controller always receives a null object, even though DataSourceRequest is fine.
I used a #html.EditorForModel() and it worked fine and controller received the data. So MVC Model binding and my class aren't the problem.
Also, using F12, I can see the data being posted and it's fine too.
Any Idea about possible problem and debugging? There is an issue with all of my Kendo Grids, sometimes they post a model twice and I receive double Create on the server, which one of them always fails because of repetitive Keys. Or sometimes create will be triggered by edit command too.
I have no idea where I'm going wrong, in most scenarios the user will choose the primary key as well, so my returned model doesn't need an update.
With this particular class, server always receives two create and none of them binds correctly. The first create, posts all of the fields, and the second posts all of the navigation properties' fields too!
This is the action method:
[HttpPost]
public ActionResult Create([DataSourceRequest] DataSourceRequest request, Stock stock){
if (stock != null && ModelState.IsValid)
{
repo.Insert(stock);
return Json(new[] { stock }.ToDataSourceResult(request, ModelState));
}
else
return Json(null);
}
And the Grid:
#(Html.Kendo().Grid<Stock>()
.Name("stock")
.Columns(columns =>
{
columns.ForeignKey(x => x.CGoodCode, (IEnumerable)ViewData["Goods"], "Id", "Text");
///
columns.Command(command => { command.Edit(); command.Destroy(); });
})
.ToolBar(toolbar => {
toolbar.Create();
toolbar.Excel();
toolbar.Pdf();
})
.Editable(edit => edit.Mode(GridEditMode.PopUp))
.Sortable()
.Pageable(p => p.PageSizes(true))
.DataSource(ds =>
ds.Ajax()
.Model(model => {
model.Id(x => x.CGoodCode);
model.Id(x => x.SWhCode);
model.Id(x => x.LiIdPeriod);
model.Field(x => x.CGoodCode).DefaultValue(ViewData["GoodsDefault"]);
////
})
.Read("Read", "Stock")
.Update("Edit", "Stock")
.Create("Create", "Stock")
.Destroy("Delete", "Stock")
)
)
UPDATE
It seems Kendo Grid doesn't support composite primary keys yet!
This question helped me out! I just need to rename the parameter like:
public ActionResult Create([DataSourceRequest] DataSourceRequest request, Stock somethingElse){
Because my class contains some fields with that name, Stock!
Is there a way to find the Grid Name in the Controller?
I am defining the grid name in my page.
<%:
Html.Telerik().Grid<Scout.Server.UI.Web.Mvc.ViewModels.WTO.WTOListViewModel>()
.Name("GridName")
.DataKeys(keys => keys.Add(wto => wto.WTORowID))
.DataBinding(dataBinding => dataBinding.Ajax()
.Select("QueryMyGrid", "GridController")
)
.Columns(columns =>
{
I need to find the Grid name in my Action Method.
[GridAction]
public ActionResult QueryMyGrid(GridCommand command)
{
var transferOrders = transferOrderService.GetActiveTransferOrdersBySubType(
typeService.GetSubTypeByMeaning(ModelDefinitions.TypeClassMeaning.ORDER_TYPES,
ModelDefinitions.TypeMeaning.ORDER_TYPE_TRANSFER_ORDER,
Is there a way to do that?
Why do you need the Grid name ?
When you use Ajax DataBinding, the Grid will call the specified action (Grid/QueryMyGrid) and fill the grid with the returned object.
You need to return something like this
return View(new GridModel<Scout.Server.UI.Web.Mvc.ViewModels.WTO.WTOListViewModel>(transferOrders));
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
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