ASP NET MVC kendo grid and column bound - asp.net-mvc

I have a kendo grid in which I am bounding columns from one table. But when I want to add a column from another table (JobItemModel) data in that column is empty. Please help here. Thanks
#(Html.Kendo().Grid<Modus.Presentation.Models.Jobs.JobModel>()
.Name("#jobs-grid")
.EnableCustomBinding(true)
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(x => x.Id))
.Read(read => read.Action("List", "Jobs"))
)
.Columns(columns =>
{
columns.Bound(x => x.Id).Visible(false);
columns.Bound(x => x.JobItem).Visible(false);
columns.Bound(x => x.JobNumber);
columns.Bound(x => x.Customer.Id).ClientTemplate("#= Customer.Name #");
columns.Bound(x => x.JobItem.Name);
columns.Bound(x => x.JobItem.DateCompletition);
columns.Command(command => command.Custom("View Details").Click("showDetails"));
The model:
public class JobModel
{
//public virtual int Id { get; set; }
public JobModel()
{
JobItems = new List<JobItemModel>();
}
[ModusResourceDisplayName("gp.Job.Fields.JobNumber")]
public string JobNumber { get; set; }
[ModusResourceDisplayName("gp.Job.Fields.Customer")]
public int CustomerId { get; set; }
[ModusResourceDisplayName("gp.Job.Fields.Contact")]
[UIHint("CustomerContact")]
public int ContactId { get; set; }
public List<JobItemModel>JobItems { get; set; }
public CustomerModel Customer { get; set; }
public JobItemModel JobItem { get; set; }
}

Related

Create toolbar function not working with multiselect in Telerik grid for MVC

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);

Bind editable kendo grid items when click save button

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);
})))

Kendo UI Grid grouping - how to set group Title

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();

Kendo ui MVC Grid Popup Editor Template DropDownListFor not working

I am using Kendo UI for ASP.MVC with Razor view and in Grid editing popup mode, EditorTemplate does not display value from Grid in DropDownListFor. What am I missing?
View:
#(Html.Kendo().Grid<CustomerLeadViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.CustomerName).Width(200);
columns.Bound(c => c.CustomerGroup);
columns.Bound(c => c.CustomerActivityField);
columns.Bound(c => c.AgentName);
columns.Command(command =>
{
command.Edit().Text("Edit");
command.Destroy().Text("Delete");
}).Width(250);
})
.HtmlAttributes(new { style = "height: 480px;" })
.Editable(editable => editable.Mode(GridEditMode.PopUp)).TemplateName("_CustomerEdit"))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(c => c.Id);
})
.Read(read => read.Action("Customers_Read", "CustomerLead", new { model = Model }))
.Update(update => update.Action("Customers_Update", "CustomerLead"))
.Destroy(delete => delete.Action("Customers_Destroy", "CustomerLead"))
)
)
and EditorTemplate/_CustomerEdit:
#model CustomerLeadViewModel
#Html.HiddenFor(model => model.Id)
#Html.Kendo().TextBoxFor(model => model.CustomerName)
#(
Html.Kendo().DropDownListFor(model=>model.CustomerGroupId)
.Name("CustomerGroup") //This name has to be the same as the Title on the main grid page
.DataTextField("GroupName")
.DataValueField("Id")
.DataSource(source =>
{
source.Read(read => { read.Action("GetCustomerGroups", "CustomerLead"); });
})
.OptionLabel("Select a group ...")
)
Controller:
public ActionResult Customers_Read([DataSourceRequest]DataSourceRequest request, CustomerLeadSearchViewModel model)
{
var customers = customerLeadRepository.Get(includeProperties: "CustomerSubGroup.CustomerGroup, CustomerActivityField");
if (model.CustomerName != null)
{
customers = customers.Where(c => c.CustomerName.Contains(model.CustomerName));
}
var customersViewModel = customers.Select(customer => new CustomerLeadViewModel
{
Id = customer.Id,
CustomerGroupId = customer.CustomerGroupId,
CustomerGroup = customer.CustomerSubGroup.CustomerGroup.GroupName,
CustomerName = customer.CustomerName,
CustomerActivityField = customer.CustomerActivityField.ActivityName,
AgentName = customer.AgentName,
Phone1 = customer.Phone1,
Mobile = customer.Mobile
});
return Json(customersViewModel.ToDataSourceResult(request));
}
public JsonResult GetCustomerGroups()
{
var customerGroups = customerGroupRepository.GetAll();
return Json(customerGroups.Select(c => new { Id = c.Id, GroupName = c.GroupName }), JsonRequestBehavior.AllowGet);
}
Model:
public class CustomerLeadViewModel
{
[ScaffoldColumn(false)]
public int Id { get; set; }
public string CustomerName { get; set; }
public string AgentName { get; set; }
public string Post { get; set; }
public string CustomerActivityField { get; set; }
public int CustomerGroupId { get; set; }
public string CustomerGroup { get; set; }
}
Change your _CustomerEditor template model field from
#(Html.Kendo().DropDownListFor(model=>model.CustomerGroupId)
to
#(Html.Kendo().DropDownListFor(model=>model.CustomerGroup)
Just as the comment says, "This name has to be the same as the Title on the main grid page"
The field that the DropDownListFor is binding to needs to be the same. Or, depending on your model, change them all to CustomerGroupId. Either way, they need to match.

Kendo UI Grid Foreign Key column empty

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.

Resources