Editor template drop down not displaying on Edit Popup

5 posts, 0 answers
  1. Brad
    Brad avatar
    13 posts
    Member since:
    Mar 2016

    Posted 03 Mar Link to this post

    I can't seem to get a drop down Editor Template working on my grid's popup editor. I am using a ViewModel rather than using my Entity Model directly, maybe that is part of the problem? I cannot use the Model directly as the database schema does not match the expected pattern, and one is supposed to always use a ViewModel I am told.

    Here is what I've got:

    View Models

    The UIHint is added as required and I have the quarter property linked to  the Quarter object per the pattern.

    public class AquisitionNotesViewModel
        {
        public int noteid { get; set; }
        public int sourceid { get; set; }
        public int? cyear { get; set; }
     
        [UIHint("QuarterDropDown")]
        public Quarter quarter { get; set; }
     
        [Column(TypeName = "text")]
        public string note { get; set; }
        [Column(TypeName = "date")]
        public DateTime? datetime { get; set; }
        }
     
    public class Quarter
    {
        public int? quarter { get; set; }
    }

    Controller

    The controller is returning a List of Quarter objects with valid values as well as the ViewModel to populate the grid.

    public ActionResult AquisitionNotes_Read([DataSourceRequest] DataSourceRequest request, int sourceid)
            {
                IList<Quarter> quartersList = new List<Quarter>();
                quartersList.Add(new Quarter { quarter = 1 });
                quartersList.Add(new Quarter { quarter = 2 });
                quartersList.Add(new Quarter { quarter = 3 });
                quartersList.Add(new Quarter { quarter = 4 });
     
                ViewData["quarters"] = quartersList;
     
                IList<AquisitionNotesViewModel> notesVM = new List<AquisitionNotesViewModel>();
     
                var Query = from notes in db.acquisitionnotes
                            where notes.sourceid == sourceid
                            select new
                                {
                                noteid = notes.noteid,
                                sourceid = notes.sourceid,
                                quarter = notes.quarter,
                                cyear = notes.cyear,
                                note = notes.note,
                                datetime = notes.datetime
                                };
     
                foreach ( var note in Query) {
                    notesVM.Add(new AquisitionNotesViewModel
                    {
                        noteid = note.noteid,
                        sourceid = note.sourceid,
                        quarter = new Quarter { quarter = note.quarter },
                        cyear = note.cyear,
                        note = note.note,
                        datetime = note.datetime,
                    });
                }
                return Json(notesVM.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);

    Editor Template (named QuarterDropDown)

    Since I do not have separate values and IDs I set DataValueField and DataTextField to my field (property) name. And I bind to the List of quarters.

    @(Html.Kendo().DropDownList()
        .Name("quarter") // Name of the widget should be the same as the name of the property
        .DataValueField("quarter") // The value of the dropdown is taken from the EmployeeID property
        .DataTextField("quarter") // The text of the items is taken from the EmployeeName property
        .BindTo((System.Collections.IEnumerable)ViewData["quarters"]) // A list of all employees which is populated in the controller
    )

    And finally my Grid

    @(Html.Kendo().Grid<AquisitionNotesViewModel>()
        .Name(GridID)
        .Columns(columns =>
        {
            columns.Bound(p => p.datetime ).Format("{0:dd/MM/yyyy}");
            columns.Bound(p => p.quarter.quarter ).Width(120);
            columns.Bound(p => p.cyear).Width(50);
            columns.Bound(p => p.note).Width(120);
            columns.Command(command => { command.Edit(); command.Destroy(); }).Width(250);
        })
        .ToolBar(toolbar => toolbar.Create())
        .Editable(editable => editable.Mode(GridEditMode.PopUp))
        .Pageable()
        .Sortable()
        .Scrollable()
        .HtmlAttributes(new { style = "height:350px;" })
        .DataSource(dataSource => dataSource
            .Ajax()
            .PageSize(10)
            .Sort(sort => sort.Add("datetime").Ascending())
            //.Events(events => events.Error("error_handler"))
            .Model(model => model.Id(p => p.noteid ))
            .Create(update => update.Action("AquisitionNotes_Create", "AquisitionNotes"))
            .Read(read => read.Action("AquisitionNotes_Read", "AquisitionNotes").Data("GetCurrentSourceID"))
            //.Read(read => read.Action("AquisitionNotes_Read", "AquisitionNotes", new { sourceid = 383}))
            .Update(update => update.Action("AquisitionNotes_Upodate", "AquisitionNotes"))
            .Destroy(update => update.Action("AquisitionNotes_Destroy", "AquisitionNotes"))
        )
    )

    What am I missing or doing wrong?

    Thanks, Brad

     

  2. Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    1746 posts

    Posted 07 Mar Link to this post

    Hello Brad,

     

    The UIHint attribute is set for the quarter of the AquisitionNotesViewModel, but the column is actually bound to the quarter property of the Quarter. Please try to set the UIHint attribute to the quarter of the Quarter class. 

     

    Also an alternative solution would be to use the EditorTemplateName method that expects a string (the name of the partial view) of the column builder. 

    columns.Bound(e => e.FirstName).EditorTemplateName("partial view name").Width(110);

     

     

    Regards,
    Boyan Dimitrov
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Brad
    Brad avatar
    13 posts
    Member since:
    Mar 2016

    Posted 08 Mar in reply to Boyan Dimitrov Link to this post

    Boyan,

    Neither of those suggestions was working. A little more debugging and I found that the QuarterDropDown editor template was simply not being called. Googling that issue did not yield anything I was not already doing correctly as far as I could tell.

    However, studying a little more about Editor Templates, I realized that your Editor Templates Docs sample was more complicated than it needed to be. I got it working by simply changing the quarter back to an int, essentially flattening the class pattern, and refactoring from there. I still do not know why it did not work using your pattern.

    Here is my new ViewModel. Quarter is now an int. I kept the quarter class to use in the template as you will see below.

    public class AquisitionNotesViewModel
            {
            public int noteid { get; set; }
            public int sourceid { get; set; }
            public int? cyear { get; set; }
     
            [UIHint("QuarterDropDown")]
            public int? quarter { get; set; }
     
            [Column(TypeName = "text")]
            public string note { get; set; }
            [Column(TypeName = "date")]
            public DateTime? datetime { get; set; }
            }
     
        public class Quarter
        {
            public int? quarter { get; set; }
            public string quarterString { get; set; }
        }

    Here is my new controllers code. After the template was finally being called, I did quickly realize that I put the ViewData["quarters"] builder in the wrong controller:

    public class HomeController : Controller
        {
            public ActionResult Index()
            {
                IList<Quarter> quartersList = new List<Quarter>();
                quartersList.Add(new Quarter { quarter = 1, quarterString = "Q1" });
                quartersList.Add(new Quarter { quarter = 2, quarterString = "Q2" });
                quartersList.Add(new Quarter { quarter = 3, quarterString = "Q3" });
                quartersList.Add(new Quarter { quarter = 4, quarterString = "Q4" });
     
                ViewData["quarters"] = quartersList;
                return View();
            }
        }

    public class AquisitionNotesController : Controller
        {
            private DatabaseTrackingDbContext db = new DatabaseTrackingDbContext();
     
            public ActionResult AquisitionNotes_Read([DataSourceRequest] DataSourceRequest request, int sourceid)
            {
     
                IList<AquisitionNotesViewModel> notesVM = new List<AquisitionNotesViewModel>();
     
                var Query = from notes in db.acquisitionnotes
                            where notes.sourceid == sourceid
                            select new
                                {
                                noteid = notes.noteid,
                                sourceid = notes.sourceid,
                                quarter = notes.quarter,
                                cyear = notes.cyear,
                                note = notes.note,
                                datetime = notes.datetime
                                };
     
                foreach ( var note in Query) {
                    notesVM.Add(new AquisitionNotesViewModel
                    {
                        noteid = note.noteid,
                        sourceid = note.sourceid,
                        quarter = note.quarter ,
                        cyear = note.cyear,
                        note = note.note,
                        datetime = note.datetime,
                    });
                }
                return Json(notesVM.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
            }
         }

    And finally the editor template:

    @(Html.Kendo().DropDownList()
        .Name("quarter") // Name of the widget should be the same as the name of the property
        .DataValueField("quarter") // The value of the dropdown
        .DataTextField("quarterString") // The text of the items
        .BindTo((System.Collections.IEnumerable)ViewData["quarters"]) // A list of all quarters which is populated in the index controller
    )

    - Brad

  5. Brad
    Brad avatar
    13 posts
    Member since:
    Mar 2016

    Posted 09 Mar in reply to Brad Link to this post

    I found another gotcha.

    You apparently cannot use UIHint at all, you must use the .EditorTemplateName method.

    If you use UIHint, the Kendo Grid and the popup editor do not wire up correctly so the DataValueField from the Editor Template's DropDown does not get passed to the Grid and also does not get posted back to your controller.

    Using EditorTemplateName to specify your Editor Template tells Kendo Grid wire everything up correctly.

    So remove UIHint and change your grid code to something like this:

    @(Html.Kendo().Grid<AquisitionNotesViewModel>()
        .Name(GridID)
        .Columns(columns =>
        {
            columns.Bound(p => p.datetime ).Format("{0:dd/MM/yyyy}");
            columns.Bound(p => p.quarter).EditorTemplateName("QuarterDropDown").Width(120);
            columns.Bound(p => p.cyear).Width(50);
            columns.Bound(p => p.note).Width(120);
            columns.Command(command => { command.Edit(); command.Destroy(); }).Width(250);
        })
        .ToolBar(toolbar => toolbar.Create())
        .Editable(editable => editable.Mode(GridEditMode.PopUp))
        .Pageable()
        .Sortable()
        .Scrollable()
        .HtmlAttributes(new { style = "height:350px;" })
        .DataSource(dataSource => dataSource
            .Ajax()
            .PageSize(10)
            .Sort(sort => sort.Add("datetime").Ascending())
            //.Events(events => events.Error("error_handler"))
            .Model(model => model.Id(p => p.noteid ))
            .Create(update => update.Action("AquisitionNotes_Create", "AquisitionNotes"))
            .Read(read => read.Action("AquisitionNotes_Read", "AquisitionNotes").Data("GetCurrentSourceID"))
            .Update(update => update.Action("AquisitionNotes_Update", "AquisitionNotes"))
            .Destroy(update => update.Action("AquisitionNotes_Destroy", "AquisitionNotes"))
        )
    )

    - Brad

  6. Brad
    Brad avatar
    13 posts
    Member since:
    Mar 2016

    Posted 09 Mar in reply to Brad Link to this post

    Well, I did not look too closely at the result of removing UIHint, apparently you need both the UIHint and EditorTemplateName. The UIHint shows the Editor Template and EditorTemplateName wires it up. Just using EditorTemplateName does not show the Editor template for some reason.

    I wish I could edit posts on this form.

Back to Top
UI for ASP.NET MVC is VS 2017 Ready