on one of my views i am using teleriks open source grid for MVC 3. i have 3 columns in the grid :
-Name
-Email
-Roles
the problem which ive got is: i want my Roles column as a dropdownlist, which is already editable when page load (so i dont want any Edit/Update buttons or stuff), so when admin change selected item in dropdownlist role of user gonna be updated.
Any idea how to make that?
View
#model IEnumerable<UserViewModel>
#(Html.Telerik().Grid(Model)
.Name("Grid").TableHtmlAttributes(new { width="800"})
.Columns(columns =>
{
//if (userIsInWhateverRole){
// columns.Template(o => Html.Action(GenerateYourLinkStuffHere));
//}
columns.Bound(o => o.Name).Width(150);
columns.Bound(o => o.Email).Width(120);
columns.Bound(o => o.Roles).Width(120);
})
.Sortable()
.Scrollable()
.Groupable()
.Filterable()
.Pageable(paging =>
paging.PageSize(5)
)
)
ViewModel
public class UserViewModel
{
public int Id { get; set; }
[Microsoft.Build.Framework.Required]
[Display(Name = "User name")]
public string Name { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
public string[] Roles { get; set; }
public string Email { get; set; }
public bool Admin { get; set; }
}
Control
public ActionResult ManageRoles()
{
var users = Membership.GetAllUsers().Cast<MembershipUser>().Select(x=> new UserViewModel{ Name = x.UserName, Email = x.Email, Roles = Roles.GetAllRoles()});
return View(users);
}
You need to use a template column and define the template as a dropdown list:
#(Html.Telerik().Grid(Model)
.Name("Grid").TableHtmlAttributes(new { width="800"})
.Columns(columns =>
{
//if (userIsInWhateverRole){
// columns.Template(o => Html.Action(GenerateYourLinkStuffHere));
//}
columns.Bound(o => o.Name).Width(150);
columns.Bound(o => o.Email).Width(120);
columns.Template (
#<text>
#Html.DropDownList("Roles", new SelectList(item.Roles))
</text>
).Width(120);
})
.Sortable()
.Scrollable()
.Groupable()
.Filterable()
.Pageable(paging => paging.PageSize(5))
)
I'm not able to test the code but it should be very close.
You want every item in the grid to be editable? Just use a template for a column that renders a textbox. See this demo: http://demos.telerik.com/aspnet-mvc/grid/templatesserverside
Related
I've gotten the multiselect to work inside the grid for existing items but when I select "Add New Record" I get a ReferenceError: Roles is not defined in the javascript.
I'm trying to populate it with a list of IdentityRoles (the build in EF ones).
Controller:
public class ManageAccountController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
public ActionResult Index()
{
List<RoleViewModel> roles = new List<RoleViewModel>();
foreach(var _role in db.Roles)
{
roles.Add(new RoleViewModel { Id = _role.Id, Name = _role.Name });
}
ViewData["roles"] = roles;
ViewData["defaultRoles"] = roles;
return View();
}
public ActionResult ApplicationUsers_Read([DataSourceRequest]DataSourceRequest request)
{
var roleManager = new ApplicationRoleManager(new RoleStore<IdentityRole>(db));
IQueryable<CustomUser> applicationusers;
applicationusers = (from u in db.Users
select new CustomUser
{
Email = u.Email,
UserName = u.UserName,
PhoneNumber = u.PhoneNumber,
AccessFailedCount = u.AccessFailedCount,
LockoutEnabled = u.LockoutEnabled,
Password = "New",
Roles = (ICollection<IdentityRole>)db.Roles.Where(x => x.Users.Select(r => r.UserId).Contains(u.Id))
});
DataSourceResult result = applicationusers.ToDataSourceResult(request, applicationUser => new {
Email = applicationUser.Email,
PhoneNumber = applicationUser.PhoneNumber,
LockoutEnabled = applicationUser.LockoutEnabled,
AccessFailedCount = applicationUser.AccessFailedCount,
UserName = applicationUser.UserName,
Password = applicationUser.Password,
Roles = applicationUser.Roles
});
return Json(result);
}
//other non interesting stuff
}
Razor view:
#(Html.Kendo().Grid<GrindrodDataCapture.Models.CustomUser>
()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.Email).ClientTemplate("<div class=\"forTooltips\">#=Email#</div>").HtmlAttributes(new { #class = "overridePadding" });
columns.Bound(c => c.PhoneNumber);
columns.Bound(c => c.LockoutEnabled).Width(110).ClientTemplate("<input type='Checkbox' disabled />");
columns.Bound(c => c.AccessFailedCount).Filterable(false).Sortable(false);
columns.Bound(c => c.UserName);
columns.Bound(c => c.Password).ClientTemplate("<input type='Password' style='width: 90px' disabled />").Filterable(false).Width(120);
columns.Bound(p => p.Roles).ClientTemplate("#=rolesTemplate(Roles)#").Width(200);/*.ClientTemplate("#=Roles.Name#").Width(120);*/
columns.Command(command => { command.Edit(); command.Destroy(); }).Width(200);
})
.ToolBar(toolbar =>
{
toolbar.Create();
})
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Pageable()
.Sortable(sortable =>
{
sortable.SortMode(GridSortMode.SingleColumn);
})
.Filterable()
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(p => p.UserName);
model.Field(p => p.AccessFailedCount).Editable(false);
model.Field(p => p.Roles).DefaultValue(ViewData["roles"] as Microsoft.AspNet.Identity.EntityFramework.IdentityRole);
})
.Read(read => read.Action("ApplicationUsers_Read", "ManageAccount"))
.Create(create => create.Action("ApplicationUsers_Create", "ManageAccount"))
.Update(update => update.Action("ApplicationUsers_Update", "ManageAccount"))
.Destroy(destroy => destroy.Action("ApplicationUsers_Destroy", "ManageAccount"))
)
)
#(Html.Kendo().Tooltip()
.For("#grid")
.Filter(".forTooltips")
.ContentHandler("getEmailTooltip")
.Position(TooltipPosition.Right)
.AutoHide(true)
)
<script type="text/kendo" id="rolesTemplate">
<ul>
#if(data){#
#for(var i = 0; i< data.length; i++){#
<li>#:data[i].Name#</li>
#}#
#}#
</ul>
</script>
<script type="text/javascript">
var rolesTemplate = kendo.template($("#rolesTemplate").html(), { useWithBlock: false });
</script>
<script>
function getEmailTooltip(e) {
var dataItem = $("#grid").data("kendoGrid").dataItem(e.target.closest("tr"));
var content = dataItem.Email;
return content;
}
</script>
Model:
public class CustomUser
{
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Required]
[Display(Name = "Email")]
public string Email { get; set; }
[Phone]
[Display(Name = "Phone Number")]
public string PhoneNumber { get; set; }
[Required]
[Display(Name = "User Name")]
public string UserName { get; set; }
[Required]
[Display(Name = "Failed Logins")]
public int AccessFailedCount { get; set; }
[Required]
[Display(Name = "Locked?")]
public bool LockoutEnabled { get; set; }
[UIHint("ClientRoles")]
[Display(Name = "Roles")]
public ICollection<IdentityRole> Roles { get; set; }
}
public class RoleViewModel
{
public string Id { get; set; }
public string Name { get; set; }
}
I've got an EditorTemplate saved in the right place caled ClientRoles:
#model Microsoft.AspNet.Identity.EntityFramework.IdentityRole
#(Html.Kendo().MultiSelect()
.Name("Roles") //The name of the MultiSelect is mandatory. It specifies the "id" attribute of the widget.
.DataTextField("Name") //Specify which property of the Roles to be used by the MultiSelect as a text.
.DataValueField("Id") //Specify which property of the Roles to be used by the MultiSelect as a value.
.BindTo((System.Collections.ICollection)ViewData["roles"]) //Pass the list of Roles to the MultiSelect.
)
Not too sure but your Roles seem to be incorrectly cast across your implementation. ViewData["roles"] is a List<RoleViewModel>.
In your editor template change
.BindTo((System.Collections.ICollection)ViewData["roles"])
to something like:
.BindTo((Models.RoleViewModel)ViewData["roles"])
Also
.Model(model => {
model.Id(p => p.UserName);
model.Field(p => p.AccessFailedCount).Editable(false);
model.Field(p => p.Roles).DefaultValue(ViewData["roles"] as Microsoft.AspNet.Identity.EntityFramework.
}
should possibly be of type List<RoleViewModel>.
I see that your CustomUser model has a public ICollection<IdentityRole> Roles { get; set; } property, so it could get a bit confusing.
I finally figured it out! One creating a row the multi select data is null and Telerik doesn’t create the parameter on creating a new row.
I had to change the following:
columns.Bound(c => c.Roles).ClientTemplate("#=rolesTemplate(Roles)#").Width(200).Filterable(false);
To:
columns.Bound(c => c.Roles).ClientTemplate("#=(data.Roles) ? rolesTemplate(Roles) : ''#").Width(200).Filterable(false);
I have the following model
public class CreateUserModel : DetailLayoutModel
{
public string UserName { get; set; }
public string Email { get; set; }
public List<UserSettingModel> Settings { get; set; }
}
public class UserSettingModel : BaseModel
{
public string Name { get; set; }
public int MaxPercentage { get; set; }
public int MaxValue { get; set; }
public int MinPercentage { get; set; }
public int MinValue { get; set; }
}
I have use for user settings editable kendo grid like the following:
the problem that when i press to create list the user setting list is null!
I want method to bind the kendo grid when I click save button.
I use Bind["models"] but not work
in my case I want to bind user setting list that exist in user model.
Edit 1:
the kendo grid in view ,
note: the kendo grid is filled when open. its bind the user settings to grid
My problem is :
1- when user fill values in grid and sort it or paginate the values is reset
2- when user click to submit button the the settings list not filled when received to action create , only the user name and email filled
#(Html.Kendo().Grid<UserSettingModel>(Model.Settings).Name("settings")
.Resizable(resize => resize.Columns(true))
.Pageable(a => a.ButtonCount(5).Numeric(false).Input(true))
.Scrollable(a => a.Enabled(true))
.Sortable(a => a.SortMode(GridSortMode.MultipleColumn))
.Selectable(a => a.Mode(GridSelectionMode.Single))
.Filterable(a => a.Extra(true))
.Editable(x=>x.Mode(GridEditMode.InCell))
.DataSource(dataSource => dataSource.Ajax()
.PageSize(5)
.ServerOperation(false)
.Read(read => read.Action("GetSettings", "User"))
.Model(model =>
{
model.Id(o => o.Id);
model.Field(p => p.Name).Editable(false);
}))
.BindTo(Model.Settings)
.Columns(columns =>
{
columns.Bound(p => p.Name).Title(GlobalResources.Name);
columns.Bound(p => p.MinValue);
columns.Bound(p => p.MinPercentage);
columns.Bound(p => p.MaxValue);
columns.Bound(p => p.MaxPercentage);
})))
I have a Kendo UI Grid with grouping on RoleName property. I am trying to set title on the grouped property and can't seem to figure out how to do that.
The view model is below.
public class UserMembershipViewModel
{
[Display(Name = "Username")]
[UIHint("UsersDropdown")]
public string UserId { get; set; }
[Display(Name = "Group")]
[UIHint("RolesDropdown")]
public string RoleId { get; set; }
[Display(Name = "Group")]
public string RoleName { get; set; }
[HiddenInput(DisplayValue = false)]
[Display(Name = "Username")]
public string UserName { get; set; }
[HiddenInput(DisplayValue = false)]
[Display(Name = "Email")]
public string Email { get; set; }
}
The Kendo Grid is set up as follows.
Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.UserName);
columns.Bound(p => p.Email);
columns.Command(command =>
{
command.Destroy();
}).Title("Actions").Width(200);
})
.Editable(editable => editable
.Mode(GridEditMode.PopUp)
.Window(window => window
.Title("Add Group Member")
.Draggable(true)))
.ToolBar(toolbar => toolbar.Create().Text("Add Group Member"))
.Pageable()
.Sortable()
.Groupable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(user => user.UserId);
model.Field(user => user.UserId).Editable(false);
})
.Events(events => events
.Sync("sync_handler"))
.Group(group => group.Add(model => model.RoleName))
.Create(create => create.Action("MembershipCreate", "UserManagement"))
.Read(read => read.Action("MembershipRead", "UserManagement"))
.Destroy(destroy => destroy.Action("MembershipDestroy", "UserManagement"))
)
And the result is this..
The RoleName property in view model has Display attribute on it. This attribute does work for setting title on column headers (you can see the Username column header in the image), but does not work on Group headers.
So the RoleName in the image should be Group. Any ideas on how to set the group title?
add group field as hidden column with ClientGroupHeaderTemplate:
columns.Bound(p => p.RoleName).ClientGroupHeaderTemplate("#=value#").Hidden();
I have tried to follow an example to get a foreign key into a grid. I followed this example:
http://demos.telerik.com/aspnet-mvc/grid/foreignkeycolumn
I have altered it a little bit because I want to use a Popup Editor.
Here is the Grid implementation in the View.
#(Html.Kendo().Grid<Example.Web.UI.ViewModels.ExampleItem>()
.Name("ExampleGrid")
.Columns(columns =>
{
columns.Bound(p => p.Name);
columns.Bound(p => p.Label);
columns.Bound(p => p.Type);
columns.Bound(p => p.InputType);
columns.ForeignKey(p => p.ParentId, (System.Collections.IEnumerable)ViewData["items"], "Id", "Name").Title("Parent");
columns.Command(command => { command.Edit(); command.Destroy(); });
})
.Scrollable()
.Groupable()
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Events(events => events.Error("error_handler"))
.Model(model =>
{
model.Id(p => p.Id);
model.Field(p => p.Id).DefaultValue(Guid.NewGuid());
model.Field(p => p.ParentId).DefaultValue(null);
})
.Create(update => update.Action("EditingPopup_Create", "Example"))
.Read(read => read.Action("EditingPopup_Read", "Example"))
.Update(update => update.Action("EditingPopup_Update", "Example"))
.Destroy(update => update.Action("EditingPopup_Destroy", "Example"))
)
)
Here is the ExampeItem Model:
public class ExampleItem
{
[ScaffoldColumn(false)]
public Guid Id { get; set; }
public string Name { get; set; }
public string Label { get; set; }
public string Type { get; set; }
[DisplayName("Input Type")]
public string InputType { get; set; }
public ExampleItem Parent { get; set; }
public Guid ParentId { get; set; }
}
In my Controller I set the foreign key items like this:
ViewData["items"] = exampleItems; // This is a List<ExapleItem>
But for some reason the Parent column is empty when the Grid is loaded.
When I click on Edit a window pops up and shows me the Guid of the parent.
That Guid should be a drop down list of items. And the Parent column should show the name of the Parent item.
The idea of this grid is that you can add items to the grid, and when you do, you can choose any of the all ready added grid items as a parent item. Then creates an hierarchy in the Grid which can be sorted later on by the Parent.
Anyone know where I have gone wrong?
Not sure but as per my experience, you forgot to add editor template for the foreign key column.
As per your code you have to add default editor templates into your project.
For default editor template detail please check this for full code/demo.
You can also create your own editor template.
For ex:-
column definition for the Product
c.ForeignKey(x => x.ProductID, (List<Product>)ViewData["products"], "ID", "ProdName").EditorTemplateName("ProductIDEditor");
Here is the editor template for Product, ProductIDEditor.cshtml
#using Kendo.Mvc.UI
#(Html.Kendo().DropDownListFor(m => m)
.AutoBind(false)
.OptionLabel("Select a value...")
.DataTextField("ProdName")
.DataValueField("ID")
.DataSource(dataSource =>
{
dataSource.Read(read => read.Action("FilterProducts", "Home").Data("filterProducts"))
.ServerFiltering(true);
})
)
#Html.ValidationMessageFor(m => m)
Let me know if any concern.
So after trial and error I found the issue.
I changed my model to:
public class ProposalItem
{
[ScaffoldColumn(false)]
public int Id { get; set; }
public string Name { get; set; }
public string Label { get; set; }
public string Type { get; set; }
[DisplayName("Input Type")]
public string InputType { get; set; }
public ProposalItem Parent { get; set; }
[UIHint("GridForeignKey")]
public int? ParentId { get; set; }
}
So removed the Guid datatype from the Id. Also Decorated the ParentId with [UIHint("GridForeignKey")] which now gives me a DropdownList in the popup window.
It looks like there is a lack of Support for Guid's in KendoUI.
I will post another question as to why Guid's don't work.
Just add in :
.DataSource(source => source.Ajax()
.Model(model =>
{
model.Id(o => o.Id);
model.Field(o => o.Id).Editable(false);
model.Field(p => p.Id).DefaultValue(Guid.NewGuid());
model.Field(p => p.ParentId).DefaultValue(Guid.NewGuid());
**model.Field("ParentId", typeof(Guid));**
})
It has to do new Guid.
I have got parent grid and child grid and I am using kendo UI Grid(Hierarchy grid format)
to bind the child grid data to corresponding row in parent grid for that I am able to show child grid for only first row and not able to show same details for another rows ...
This is my view for that grid ...
#model IEnumerable<KendoSampleMVCApp.Models.EmployeesDetailsModel>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm())
{
#(Html.Kendo().Grid<KendoSampleMVCApp.Models.EmployeesDetailsModel>()
.Name("ParentGrids")
.Columns(columns =>
{
columns.Bound(e => e.EmployeeID).Width(100);
columns.Bound(e => e.EmployeeFirstName).Width(100);
columns.Bound(e => e.EmployeeSecondName).Width(100);
columns.Bound(e => e.EmployeeCity).Width(100);
})
.Sortable()
.Pageable()
.Scrollable()
.ClientDetailTemplateId("template")
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(5)
.Read(read => read.Action("HierarchyBinding_Employees", "HierarchyGridDisplay"))
)
)
<script id="template" type="text/kendo-tmpl">
#(Html.Kendo().Grid<KendoSampleMVCApp.Models.ShipDescriptionModel>()
.Name("ChildGrids")
.Columns(columns =>
{
columns.Bound(o => o.ShipAddress).Width(70);
columns.Bound(o => o.ShipCountry).Width(70);
columns.Bound(o => o.ShipName).Width(70);
})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(6)
.Read(read => read.Action("HierarchyBinding_Orders", "HierarchyGridDisplay"))
)
.Pageable()
.Sortable()
.ToClientTemplate()
)
</script>
<script>
function dataBound() {
this.expandRow(this.tbody.find("tr.k-master-row").first());
}
</script>
}
and this is my model
public class EmployeesDetailsModel
{
public string EmployeeID { get; set; }
public string EmployeeFirstName { get; set; }
public string EmployeeSecondName { get; set; }
public string EmployeeCity { get; set; }
}
public class ShipDescriptionModel
{
public string ShipCountry { get; set; }
public string ShipAddress { get; set; }
public string ShipName { get; set; }
}
public class EmployeeShipModel
{
public EmployeesDetailsModel employeesshipments { get; set; }
public ShipDescriptionModel shipinfo { get; set; }
}
would you pls suggest any ideas and any changes need to be done in view for showing child grid data to another rows as well... Many thanks
pls look at the images attached below
I believe that this is because you have a static id for the grid. You should try and give it a dynamic one, so different child grids can be created. This is why it only works on the first record, because you have no variation for the name of the grid.
Try to do this instead:
#(Html.Kendo().Grid<KendoSampleMVCApp.Models.ShipDescriptionModel>()
.Name("ChildGrid_#=EmployeeID#")
What is happening is that the EmployeeId from the parent grid is being pulled down, and being used for the naming convention of the grid. This way you can have as many child grids as like you like.