Setting initial value of input inside Edit Popup Template

8 posts, 0 answers
  1. Chris
    Chris avatar
    26 posts
    Member since:
    Mar 2016

    Posted 18 Nov 2016 Link to this post

    Hi, 

    I am attempting to set the initial value of an input control inside the Popup editor by using a hierarchical grid's Edit event. The popup displays correctly, but the MVVM binding is not updating the model. This is the case for any of the input controls i try to set the value of. However, if i manually (non-programmatically) change the input value, the model is successfully updated. I have also tried to use the .data("").trigger("change") method to fire off the change event of the input control to no avail. I have tried setting the value on several other controls (not just a dropdownlist) and the result is the same-the display text is shown correctly but the value is not updated in the model. Any ideas on how to update the model?

    Below is the Grid Helper, Javascript function, and Editor Template. Attached is a screenshot of the form data; notice how CourseID is set to 0 (CourseID is non-nullable).

     

    MVC Grid Helper: 

    <script id="childTemplate" type="text/kendo-tmpl">
            @(Html.Kendo().TabStrip()
                        .Name("tabStrip_#=CourseID#")
                        .SelectedIndex(0)
                        .Animation(a => a.Open(o => o.Fade(FadeDirection.In)))
                        .Items(i =>
                        {
                            i.Add().Text("Classes").Content(@<text>
                                @(Html.Kendo().Grid<LMS_Web_MVC.Models.ClassFull>()
                                .Name("grid_#=CourseID#")
                                .ToolBar(t => t.Create().Text("Add Class"))
                                .Columns(columns =>
                                {
                                    columns.Bound(o => o.ClassID);
                                    columns.Bound(o => o.BeginDate).Format("{0:yyyy-MM-dd HH:mm}");
                                    columns.Bound(o => o.EndDate).Format("{0:yyyy-MM-dd HH:mm}");
                                    columns.Bound(o => o.Enrollees);
                                    columns.Bound(o => o.Active);
                                    columns.Command(c => { c.Edit(); }).Title("Actions");

                                })
                                .Editable(e => e.Mode(GridEditMode.PopUp).Window(w => w.Width(600)).TemplateName("ClassEditor"))
                                .DataSource(dataSource => dataSource
                                    .Ajax()
                                    .PageSize(10)
                                    .Read(read => read.Action("Get_ClassesByCourse", "Class", new { courseID = "#=CourseID#" }))
                                    .Update(u => u.Action("SaveClass", "Class"))
                                    .Create(c => c.Action("SaveClass", "Class"))
                                    .Model(m => { m.Id(c => c.ClassID); m.Field(c => c.Active).DefaultValue(true);
                                    })
                                )
                                .Events(ev => ev.Edit("onEdit"))
                                .Pageable()
                                .Sortable()
                                .ToClientTemplate())
                            </text>);
                        }
            ).ToClientTemplate())
    </script>

     

    Javascript Function

    <script>

        function onEdit(e) {
            if (e.model.ClassID == null) {
                var courseGrid = $("#grid").data("kendoGrid");
                var parentRow = courseGrid.dataItem(this.wrapper.closest("tr").prev());
                var id = parentRow.CourseID;
                $("#CourseID").data("kendoDropDownList").value(id);
                $("#CourseID").data("kendoDropDownList").trigger("change");
            }

    </script>

     

    Editor Template

    @model LMS_Web_MVC.Models.ClassFull

    <div data-container-for="CourseID" class="k-edit-field">
        @Html.Kendo().DropDownListFor(model => model.CourseID).OptionLabel("Choose Course").Filter(FilterType.Contains).HtmlAttributes(new { style = "width:400px" }).DataTextField("CourseTitle").DataValueField("CourseID").ValuePrimitive(true).DataSource(ds => {
        ds.Custom()
        .ServerFiltering(true)
        .ServerPaging(true)
        .PageSize(100)
        .Type("aspnetmvc-ajax")
        .Transport(t =>
        {
            t.Read("Get_SimpleCourseList", "Course", new { filterActive = false });
        })
        .Schema(s =>
        {
            s.Data("Data").Total("Total");
        });
    }).Virtual(v => v.ItemHeight(26).ValueMapper("valueMapper"))
    </div> 

     

  2. Chris
    Chris avatar
    26 posts
    Member since:
    Mar 2016

    Posted 18 Nov 2016 Link to this post

    Ok, i seemed to figure out a work around, albeit a hack-ey one which also gives insight to the issue. I really do not like these types of workarounds, since they seem unstable, especially ones that rely on timing. Since this works, i figure the root cause of the initial issue is that the MVVM mechanism has not yet been bound to the model when the onEdit function is called. So even though the trigger method is called, there is no MVVM observable bound to update. Is there anyway to check to see if the binding mechanism has been bound to the viewModel?

    Amended Javascript Function

        function onAddEdit(e) {
            if (e.model.ClassID == null) {
                var courseGrid = $("#grid").data("kendoGrid");
                var parentRow = courseGrid.dataItem(this.wrapper.closest("tr").prev());
                var id = parentRow.CourseID;
                $("#CourseID").data("kendoDropDownList").value(id);

                setInterval(function () {
                    $("#CourseID").data("kendoDropDownList").trigger("change");
                }, 1000);

               clearTimeout(5000);
            }
        }

     

  3. Chris
    Chris avatar
    26 posts
    Member since:
    Mar 2016

    Posted 18 Nov 2016 Link to this post

    Ok, i seemed to figure out a work around, albeit a hack-ey one, which also gives some insight to the root cause of the issue. I really dont like these types of workarounds, since they seem unstable, especially when it involves timers. Since this works, i figure the root cause of the initial issue is that the MVVM mechanism has not yet been bound to the model when the onEdit function is called. So even though the trigger method is called, there is no viewmodel bound to update values to. I understand that the kendo MVVM binding occurs synchronously, so i should be able to call the .trigger method immediately after binding. Is there anyway to check to see if the binding mechanism has been bound to the viewmodel?



    Amended Javascript Function

        function onAddEdit(e) {
            if (e.model.ClassID == null) {
                var courseGrid = $("#grid").data("kendoGrid");
                var parentRow = courseGrid.dataItem(this.wrapper.closest("tr").prev());
                var id = parentRow.CourseID;
                $("#CourseID").data("kendoDropDownList").value(id);

                setInterval(function () {
                    $("#CourseID").data("kendoDropDownList").trigger("change");
                }, 1000);
               clearTimeout(5000);

            }
        }
  4. Konstantin Dikov
    Admin
    Konstantin Dikov avatar
    2466 posts

    Posted 22 Nov 2016 Link to this post

    Hi Christopher,

    Can you please try the following instead and let me know if it works in your scenario:
    function onAddEdit(e) {
           if (e.model.ClassID == null) {
               var courseGrid = $("#grid").data("kendoGrid");
               var parentRow = courseGrid.dataItem(this.wrapper.closest("tr").prev());
               var id = parentRow.CourseID;
               e.model.set("CourseID", id);
           }
       }

    I am looking forward to your reply.


    Regards,
    Konstantin Dikov
    Telerik by Progress
    Telerik UI for ASP.NET MVC is ready for Visual Studio 2017 RC! Learn more.
  5. Chris
    Chris avatar
    26 posts
    Member since:
    Mar 2016

    Posted 28 Nov 2016 in reply to Konstantin Dikov Link to this post

    Hi Konstantin,

    Thank you for the reply. I attempted the solution your proposed, but still the Model's CourseID value was 0.

    I then tried this instead and the CourseID value was successfully posted to the model.

    function onAddEdit(e) {
        if (e.model.ClassID == null) {
            var courseGrid = $("#grid").data("kendoGrid");
            var parentRow = courseGrid.dataItem(this.wrapper.closest("tr").prev());
            var id = parentRow.CourseID;
     

     

            $("#CourseID").data("kendoDropDownList").value(id);
            e.model.CourseID = id;
        }
  6. Chris
    Chris avatar
    26 posts
    Member since:
    Mar 2016

    Posted 28 Nov 2016 in reply to Konstantin Dikov Link to this post

    Konstantin, 

    Why do you think explicitly assigning the model's CourseID worked, but not the set() method?

    Also, i had to still set the drop down list div value or else the drop down list would not populate.

     

    Thank you for putting me on the right path.

  7. Konstantin Dikov
    Admin
    Konstantin Dikov avatar
    2466 posts

    Posted 30 Nov 2016 Link to this post

    Hello Christopher,

    On my side, using the set method works correctly, but the example that I have tested was not using the Virtual functionality of the DropDownList, which might be the cause of the problem. As for the solution that you have found, setting the model value and the value directly to the DropDownList is a valid solution.

    Just for testing purposes only, could you please test the set method with removed Virtual scrolling of the DropDownList and see if that will make any difference. 

    Looking forward to your reply with the result.


    Regards,
    Konstantin Dikov
    Telerik by Progress
    Telerik UI for ASP.NET MVC is ready for Visual Studio 2017 RC! Learn more.
  8. Chris
    Chris avatar
    26 posts
    Member since:
    Mar 2016

    Posted 30 Nov 2016 in reply to Konstantin Dikov Link to this post

    Hi Konstantin,

    I have attempted the solution again, this time by removing the .Virtual functionality from the template and re-applying the .set method in the JS code to no avail. I am satisfied with my previous solution.

    Thank you for your help.  Much appreciated! 

    Here is my snippets for review. Maybe something is off.

    Controller:

    public JsonResult Get_SimpleCourseList()
    {
        return Json(_service.Get_Courses(false).Select(c => new CourseSimple(c)).OrderBy(c => c.CourseTitle), JsonRequestBehavior.AllowGet);
    }

     

    View

    @(Html.Kendo().Grid<LMS_Web_MVC.Models.ClassFull>()
    .Name("grid_#=CourseID#")
    .ToolBar(t => t.Create().Text("Add Class"))
    .Columns(columns =>
    {
        columns.Bound(o => o.ClassID);
        columns.Bound(o => o.BeginDate).Format("{0:yyyy-MM-dd HH:mm}");
        columns.Bound(o => o.EndDate).Format("{0:yyyy-MM-dd HH:mm}");
        columns.Bound(o => o.Enrollees);
        columns.Bound(o => o.Active);
        columns.Command(c => { c.Edit(); }).Title("Actions");
     
    })
    .Editable(e => e.Mode(GridEditMode.PopUp).Window(w => w.Width(600)).TemplateName("ClassEditor"))
    .Events(ev => ev.Edit("onNewCourseClass"))

     

    View Function

    function onNewCourseClass(e) {
        if (e.model.ClassID == null) {
            var courseGrid = $("#grid").data("kendoGrid");
            var parentRow = courseGrid.dataItem(this.wrapper.closest("tr").prev());
            var id = parentRow.CourseID;
            e.model.set("CourseID", id);
        }
    }

     

    ClassEditor Template

    <div data-container-for="CourseID" class="k-edit-field">
        @Html.Kendo().DropDownListFor(model => model.CourseID).OptionLabel("Choose Course").HtmlAttributes(new { style = "width:400px" }).DataTextField("CourseTitle").DataValueField("CourseID").ValuePrimitive(true).DataSource(ds => {
        ds.Read(r =>
        {
            r.Action("Get_SimpleCourseList", "Course");
        });
    })
    </div>
Back to Top