Kendo UI Grid Foreign Key column empty - asp.net-mvc

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.

Related

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

Custom editor template not displayed in PopUp edit mode issue

I am using kendo ui grid with Inline editing and it works fine but when i change editor mode to PopUp, it does not display the Customeditor fields(i.e.PickUpLocation) in edit window and show only fields other then customeditor template from model. What I am doing wrong here?
Shipping.cshtml (Main View contains Grid)
#(Html.Kendo().Grid<Comanex.Models.ShippingInstructionViewModel>()
.Name("ShippingGrid")
.Columns(c =>{
c.Bound(m => m.Id).Hidden();
c.Bound(m => m.LocationViewModel)
.ClientTemplate("#=LocationViewModel.LocationName#")
.Title("Pickup Location");
c.Bound(m => m.UnitsShipped)
c.Command(p =>
{
p.Edit();
p.Destroy();
});
})
.ToolBar(toolbar =>{toolbar.Create().Text("").HtmlAttributes(new { #title = "Add" });})
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Events(events =>{events.Edit("edit");events.Save("save");})
.DataSource(dataSource => dataSource
.Ajax()
.Create(create => create.Action("ShippingInstruction_Insert", "InHouseShipping"))
.Read(read => read.Action("ShippingInstruction_Read", "InHouseShipping"))
.Update(update => update.Action("ShippingInstruction_Update", "InHouseShipping"))
.Destroy(destroy => destroy.Action("ShippingInstruction_Delete", "InHouseShipping"))
.Model(m =>{m.Id(p => p.Id);
m.Field(p => p.LocationViewModel).DefaultValue(ViewData["DefaultPickUpLocation"] as Comanex.Models.LocationViewModel);
})
)
)
ShippingInstructionViewModel.cs (Model that display the data to grid)
public class ShippingInstructionViewModel
{
[ScaffoldColumn(false)]
public int Id { get; set; }
[Required]
[UIHint("PickUpLocationEditor")]
public LocationViewModel LocationViewModel { get; set; }
[Required]
[Display(Name = "Units Shipped")]
[DisplayFormat(DataFormatString = "{0:n0}")]
public Nullable<decimal> UnitsShipped { get; set; }
}
PickUpLocationEditor.cshtml (My Custom Editor DropDownListFor)
#model Comanex.Models.LocationViewModel
#(Html.Kendo().DropDownListFor(m => m)
.OptionLabel("Select..")
.DataValueField("LocationId")
.DataTextField("LocationName")
.AutoBind(false)
.DataSource(d =>
{
d.Read(r => r.Action("GetShippingPickUpLocations", "ProductionZone"))
.ServerFiltering(true);
})
.Events(evnt=>evnt.Cascade("onCascade")) //Need to add this Event on Parent Drop Downs
)
#Html.ValidationMessageFor(m => m)
Here in edit window, only UnitShipped field is displayed and PickUpLocation dropdownlist is not showing. Why?
By default the MVC does not generate editor template for nested objects. You can try and do the same in a separate view where EditorForModel is used (the Grid uses exactly this). To customize the popup editor check this code library.

Why doesn't this Kendo Grid URL map to my controller action method?

I'm trying to follow the docs on how to make my kendo mvc grid ajaxified and able to support some in cell editing.
The problem I have is on save, I'm seeing the grid make the following request which is apparently not available. I'm not familiar with the models prefix stuff but it looks like the object is modeled in the URL properly with each property prefixed with &models, then some hash, then the parameter name and then the value.
Why doesn't this URL map to my controller action method?
"NetworkError: 404 Not Found -
http://localhost/MySite/UI/Orders/Update
?models%5B0%5D%5BId%5D=18c12470-0ca3-4e9c-b6d7-af1d6120e03f
&models%5B0%5D%5BNumber%5D=231413+
&models%5B0%5D%5BMod%5D=8ccbf70a-f368-434c-8c05-2e2f5278215d
&models%5B0%5D%5BModName%5D=M6G+++++++++++++++++++++++++++++++++++++++++++++++
&models%5B0%5D%5BDescription%5D=M6G+LMU+TTU1200
&models%5B0%5D%5BPart%5D=105442
&models%5B0%5D%5BPartDescription%5D=M6H+TELEMATICS+CONTROL+UNIT
&models%5B0%5D%5BQuantity%5D=20
&models%5B0%5D%5BDeliveryDate%5D=Tue+Apr+30+2013+00%3A00%3A00+GMT-0400+(Eastern+Daylight+Time)&_=1366818145016"
The Update method sig in the controller looks like this:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update([Kendo.Mvc.UI.DataSourceRequest] Kendo.Mvc.UI.DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<Order> order)
{
//do update
}
And the sample Order object looks like this
public class Order
{
public Guid Id { get; set; }
public string Number{ get; set; }
public Guid Mod{ get; set; }
public string ModName{ get; set; }
public string Description { get; set; }
public int Part{ get; set; }
public string PartDescription { get; set; } // View Model Purposes Only
[Required]
[UIHint("QuantityEditor")] //QuantityEditor is the name of the custom editor template
public int Quantity { get; set; }
public DateTime DeliveryDate{ get; set; }
}
Here's the grid code ala MVC:
#(Html.Kendo().Grid(Model)
.Name("my-grid")
.Columns(columns =>
{
columns.Bound(m => m.Id)
.Hidden(true)
.HtmlAttributes(new { #class = "some-class" });
columns.Bound(m => m.Mod)
.Hidden(true)
.HtmlAttributes(new { #class = "some-class" });
columns.Bound(m => m.ModName)
.Hidden(true)
.HtmlAttributes(new { #class = "some-class" });
columns.Bound(m => m.Description).HtmlAttributes(new { #class = "some-class" });
columns.Bound(m => m.Part).HtmlAttributes(new { #class = "part can-edit" });
columns.Bound(m => m.PartDescription).HtmlAttributes(new { #class = "can-edit" });
columns.Bound(m => m.DeliveryDate).Format("{0:yyyy-MM-dd}").HtmlAttributes(new { #class = "date can-edit" });
columns.Bound(m => m.Quantity).HtmlAttributes(new { #class = "quantity can-edit" }).FooterTemplate("Total:");
})
.Scrollable(s => s.Height("auto"))
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Events(events => events.DataBound("onDataBound"))
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.Update(update => update.Action("Update", "Orders"))
.Read(read => read.Action("GetAllOrders", "Orders").Data("getAdditionalData"))
.Aggregates(aggregates => { aggregates.Add(p => p.Quantity).Sum(); })
.Model(model =>
{
model.Id(m => m.Id);
model.Field(m => m.Id).Editable(false);
model.Field(m => m.Part).Editable(true);
model.Field(m => m.Quantity).Editable(true);
model.Field(m => m.DeliveryDate).Editable(true);
model.Field(m => m.PartDescription).Editable(true);
})
)
)
At 1st glance it would look like,
.Read(read => read.Action("GetAllOrders", "Controller").Data("getAdditionalData"))
Instead of Controller you need to put in the actual name of the Controller so for example "PersonController" would be "Person".
Edit- Ok from the looks of it then you've setup your Read from datasource but not your Update and instead tried to do it in events.
http://demos.kendoui.com/web/grid/editing-inline.html
I find it easier not to use inline edits and instead create a template button to redirect to an edit page thus keeping the kendo related code simple.
Looks like your grid is being called from within an MVC area. If you have Areas setup within your MVC application, it's always a good practice to reference those when making calls with Kendo UI Widgets.
Below assumes an Area called "UI":
.Update(update => update.Action("Update", "Orders", new { Area = "UI" }))

MVC 3 telerik grid edition mode

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

Resources