This is a migrated thread and some comments may be shown as answers.

Setting initial value of input inside Edit Popup Template

7 Answers 1278 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Chris
Top achievements
Rank 1
Chris asked on 18 Nov 2016, 04:42 PM

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> 

 

7 Answers, 1 is accepted

Sort by
0
Chris
Top achievements
Rank 1
answered on 18 Nov 2016, 05:09 PM

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

 

0
Chris
Top achievements
Rank 1
answered on 18 Nov 2016, 05:15 PM
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);

        }
    }
0
Konstantin Dikov
Telerik team
answered on 22 Nov 2016, 12:29 PM
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.
0
Chris
Top achievements
Rank 1
answered on 28 Nov 2016, 04:36 PM

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;
    }
0
Chris
Top achievements
Rank 1
answered on 28 Nov 2016, 04:39 PM

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.

0
Konstantin Dikov
Telerik team
answered on 30 Nov 2016, 02:24 PM
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.
0
Chris
Top achievements
Rank 1
answered on 30 Nov 2016, 05:21 PM

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>
Tags
Grid
Asked by
Chris
Top achievements
Rank 1
Answers by
Chris
Top achievements
Rank 1
Konstantin Dikov
Telerik team
Share this question
or