Strange behavior of kendo controls inside a window after reload from Telerik Asp.Net Ajax call

7 posts, 0 answers
  1. Franz
    Franz avatar
    7 posts
    Member since:
    Oct 2013

    Posted 05 Feb 2015 Link to this post

    Hi there,
    I've got the content of my kendo window not rendered correctly the first time after a reload of the usercontrol where the window is defined.
    When I open this window a second time ( only from the client without any ajax call!) the content is rendered correctly.

    So let me explain the structure of my software:

    The existing project was initially developed with Telerik Asp.Net Ajax components. I follows an SPA approach where UserControls are loaded into an RADSplitter Pane.
    Meanwhile we decided to replace RadControls with ASP.NET MVC Kendo UI controls. So we added ASP.NET MVC 5 to our project and defined an Area where all our new Pages/Controls are located.
    The MVC code is injected into an Asp.Net ascx UserControl with this piece of code:
    <telerik:RadScriptBlock ID="RadCodeBlockCompanyAdministrationPermissions" runat="server">
    <script type="text/javascript">
        $telerik.$(document).ready(function () {
            var url = "/MVC/Permission/Index/<%=ParentObject.Id %>";
            $.ajax(
            {
                type: "GET",
                url: url,
                success: function (msg) {
                     $("#mvcpartial").html(msg);
                },
                error: function (state, err) {
                    alert('ERROR: ' +state + ' - ' + err);
                }
            });
        });
    </script>
     </telerik:RadScriptBlock>

    This works just fine and for i.e. displaying data with kendo grid we don't have any problems.
    In this case however, I want to open a kendo window from a custom command inside a kendo grid.

    This is my grid :
    @(Html.Kendo()
                  .Grid(Model)
                  .Name("grdPermissionGroup")
                  .Columns(column =>
                  {
                      column.Bound(p => p.Id).HtmlAttributes(new { @class = "permissionGroupId" }).Hidden(true);
                      column.Bound(p => p.CompanyId).HtmlAttributes(new { @class = "companyId" }).Hidden(true);
                      column.Bound(p => p.Name);
                      column.Command(cmd =>
                      {
                          cmd.Edit().Text(" ").UpdateText(" ").CancelText(" ").HtmlAttributes(new { title = ViewBag.Edit });
                          cmd.Destroy().Text(" ").HtmlAttributes(new { title = ViewBag.Delete });
                          cmd.Custom("ShowRoles").Text(" ").Click("addRole");
                      });
                  })
                  .ClientDetailTemplateId("roleDetails")
                  .DataSource(ds => ds
                      .Ajax()
                      .Model(model =>
                      {
                          model.Id("Id");
                          model.Field(f => f.Id).DefaultValue(Guid.NewGuid());
                          model.Field(f => f.CompanyId).DefaultValue(@Model.First().CompanyId);
     
                      })
     
                      .Create(create => create.Action("PermissionGroupCreate", "Permission"))
                      .Update(update => update.Action("PermissionGroupUpdate", "Permission"))
                      .Read(read => read.Action("PermissionGroups", "Permission").Data("additionalData"))
                      .Destroy(destroy => destroy.Action("PermissionGroupDelete", "Permission"))
                      .Events(e =>
                      {
                          e.Error("permissionGroupGrid_errorHandler");
                           
                      })
                  )
                  .ToolBar(commands => commands.Create().Text("Neue Berechtigungsgruppe"))
                  .Editable(editable => editable.Mode(GridEditMode.InLine))
                  .Selectable()
                  .Scrollable(builder => builder.Height(368))
                  .Sortable()
                  .Events(ev =>
                  {
                      ev.DataBound("onPermissionGroupGridRowBound");
                      ev.Edit("pgEdit");
                      ev.Change("pgChange");
                      ev.Cancel("pgCancel");
                      ev.Remove("pgRemove");
                      ev.Save("pgSave");
                  })
            )

    My window is opend through javascript in function addRole:
    function addRole(e) {
        var row = this.select();
        permissionGroupId = row.find('.permissionGroupId').html();
        var childGridName = 'grdRoleDetails_' + permissionGroupId;
     
        if (!permissionGroupId) {
            alert('Please select permissiongroup!');
            return;
        }
        var childGrid = $("#" + childGridName).data("kendoGrid");
       
        if (childGrid == null) {
            this.expandRow(row);
        }
        
        childGrid = $("#" + childGridName).data("kendoGrid");
        if (childGrid != null) {
            var window = $('#wndAddRole').data("kendoWindow");
            if (window == null) {
                window = $("#wndAddRole").kendoWindow({
                    actions: ["Close"],
                    content: '/MVC/Permission/GetRoleWindowContent/' + permissionGroupId,
                    draggable: true,
                    height: "240px",
                    width: "425px",
                    resizable: false,
                    title: "AssignRole",
                    close: onRoleWindowClose,
                }).data("kendoWindow");
            }
            window.center();
            window.open();
        } else {
            _pendingAddItem = true;
        }
    }

    The content of the window is this:
    @model CargoGuard.WebPortal.Neu.Areas.MVC.Models.RoleViewModel
    @{
         var pgId = ViewBag.PermissionGroupId;
    }
     
    <div class="roleEditContainer">
        @Html.HiddenFor(m => m.Id)
     
        <div class="editor-row">
            <div class="editor-label">
                @Html.Label("Roles")
            </div>
     
            <div class="editor-field role-edit-field">
                @(Html.Kendo().DropDownList()
                      .Name("drpRoleSelection")
                      .AutoBind(true)
                      .HtmlAttributes(new { style = "width:230px;" })
                      .DataTextField("Name")
                      .DataValueField("Id")
                      .DataSource(ds => ds.Read(read => read.Action("GetAllRoles", "Permission", new{id=pgId})))
                      .OptionLabel(HttpContext.GetGlobalResourceObject("GlobalMVC", "OptionSelectRole"))
                      .SelectedIndex(0).Events(evt => evt.Change("onRoleDropDownChange"))
                      )
                 
            </div>
        </div>
     
        <div class="editor-row">
            <div class="editor-label">
                @Html.LabelFor(m => m.Name)
            </div>
     
            <div class="editor-field role-edit-field">
                @Html.Kendo().TextBoxFor(m => m.Name).HtmlAttributes(new { style = "width:250px;" })
            </div>
        </div>
     
        <div class="editor-row">
            <div class="editor-label">
                @Html.LabelFor(m => m.Description)
            </div>
     
            <div class="editor-field role-edit-field">
                @Html.TextAreaFor(m => m.Description, new { @class = "k-textbox", style = "height:100px; width:200px;" })
            </div>
        </div>
    </div>
    <div class="k-edit-form-container">
        <div class="k-edit-buttons k-state-default">
     
            <a id="btnAssignRole" class="k-button k-button-icontext k-primary k-grid-update" href="#" title="Bearbeiten">
                <span class="k-icon k-update"></span>
            </a>
            <a id="btnCancleAssignRole" class="k-button k-button-icontext k-grid-cancel" href="#" title="Bearbeiten">
                <span class="k-icon k-cancel"></span>
            </a>
     
        </div>
    </div>
    <script>
        $(document).ready(function () {
     
            var dropDownList = $('#drpRoleSelection').data('kendoDropDownList');
            dropDownList.dataSource.read();
            dropDownList.refresh();
     
     
            $('#btnAssignRole').click(function() {
                var id = $('#Id').val();
                var name = $('#Name').val();
                if(name == null )
                
                var url = '/MVC/Permission/AssignRole?id=' + id + '&permissionGrpId=' + '@pgId';
                $.ajax(
                   {
                       type: "POST",
                       url: url,
                       success: function (msg) {
                           alert(msg);
                           var gridGroup = $("#grdPermissionGroup").data("kendoGrid");
                           var selectedRow = gridGroup.select();
                           var dataItem = gridGroup.dataItem(selectedRow);
                           var Id = dataItem.Id;
     
                           var grdRoleDetails = $('#grdRoleDetails_' + Id).data("kendoGrid");
                           grdRoleDetails.dataSource.read();
     
                           var window = $("#wndAddRole").data("kendoWindow");
                           window.close();
                            
                       },
                       error: function (state, err) {
                           alert('ERROR: ' + state + ' - ' + err);
     
                       }
                   });
            });
     
            $('#btnCancleAssignRole').click(function () {
                var window = $("#wndAddRole").data("kendoWindow");
                window.close();
            });
        })
    </script>

    The first time this page is loaded and I click the button to open the window everything is rendered as expected: see Attachment CorrectWindow.png
    When reloading the usercontrol from outside via an ajax call defined by RadAjaxManager, the window will be opened and centered, but the content  is not rendered the kendo way as you see in BrokenWindow.png. If I then close the window and click the button a second time without any reload (only client side actions) the content is rendered correctly again.
    I have googled a long time and found some postings that this could come from jquery defined twice. So I checked my project for this issue and took care that jquery is loaded only once, but the problem still exists.
    I suppose, that this may derive from a timing problem, but this is hard to find out.
    Thanks in advance for your support!






  2. Franz
    Franz avatar
    7 posts
    Member since:
    Oct 2013

    Posted 05 Feb 2015 in reply to Franz Link to this post

    Please don't worry about this if(name == null ). It's a fragment I forgot to remove. But the problem exists without that line of code.
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 09 Feb 2015 Link to this post

    Hello Franz,

    From the provided information it seems that possible reason for current behavior could be the "Change" event handler of the DropDownList. In the provided code sample it's not clear where the handler is loaded, however if it's loaded after the DropDownList widget it will not be initialized corectly. Could you please make sure the handler is loaded before the DropDownList and let us know of the result? 

    Regards,
    Vladimir Iliev
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  5. Franz
    Franz avatar
    7 posts
    Member since:
    Oct 2013

    Posted 10 Feb 2015 in reply to Vladimir Iliev Link to this post

    Hi Vladimir,
    what do you mean with 'handler is loaded before the DropDownList'?  This Line .Events(evt => evt.Change("onRoleDropDownChange"))
    calls a function in a javascript file that is loaded on top of my view. <script src="~/Areas/MVC/Views/Permission/PermissionManagement.js"></script>.
    Putting it in the success callback of my ajax function
    $.ajax(
           {
               type: "GET",
               url: url,
               success: function (msg) {
                    
                   $("#mvcpartial").html(msg);
                   debugger;
                   var dropDownList = $('#drpRoleSelection').data('kendoComboBox');
                   dropDownList.readonly(true);
                   dropDownList.on('change',
                       function (evt, params) {
                           alert('change');
                           onRoleDropDownChange(evt);
                           //.Events(evt => evt.Change("onRoleDropDownChange")
                       });
                   dropDownList.dataSource.read();
                   dropDownList.refresh();
     
                   
               },
               error: function (state, err) {
                   alert('ERROR: ' +state + ' - ' + err);
     
               }
           });

    gives me the error: TypeError: dropDownList.on is not a function

    It seems that there is a problem with jquery.
    But the mysterious part is, that without reload (just only clientside) the next time the window is loaded everything is ok.

    Regards

    Franz
  6. Franz
    Franz avatar
    7 posts
    Member since:
    Oct 2013

    Posted 10 Feb 2015 in reply to Franz Link to this post

    UPDATE: I've found a solution for this problem:
    When adding following script at the end of my content page scriptblock every time the winow is opend the rendering is correct.
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
       function EndRequestHandler(sender, args) {
        
               var window = $("#wndAddRole").data("kendoWindow");
               if (window) {
                   window.destroy();
               }
       }
    I don't know why this behaviour occurs without destroy, because the content is loaded dynamically every time the window is opend.
    Seems, that there is some garbage remaining when opening the window after an ajax postback.  It is astonishing, that I was able to execute the ajax postback 2 times with the correct behaviour of my dropdownlist, but the third time something's going wrong.
  7. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 12 Feb 2015 Link to this post

    Hi Franz,

    1) What do you mean with 'handler is loaded before the DropDownList'? - I mean that the event handler defined for the widget should be loaded to the page before the DropDownList (from your explanation it seems that is correctly loaded).

    2) From the provided information it's not clear for us if the issue that you are facing is now resolved - could you please clarify?

    Regards,
    Vladimir Iliev
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  8. Franz
    Franz avatar
    7 posts
    Member since:
    Oct 2013

    Posted 12 Feb 2015 in reply to Vladimir Iliev Link to this post

    Hi, Vladimir,
    yes this issue is solved with the explanation of my last post.

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