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

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

6 Answers 474 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Franz
Top achievements
Rank 1
Franz asked on 05 Feb 2015, 10:26 AM
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!






6 Answers, 1 is accepted

Sort by
0
Franz
Top achievements
Rank 1
answered on 05 Feb 2015, 10:35 AM
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.
0
Vladimir Iliev
Telerik team
answered on 09 Feb 2015, 08:37 AM
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.

 
0
Franz
Top achievements
Rank 1
answered on 10 Feb 2015, 10:55 AM
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
0
Franz
Top achievements
Rank 1
answered on 10 Feb 2015, 12:57 PM
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.
0
Vladimir Iliev
Telerik team
answered on 12 Feb 2015, 08:35 AM
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.

 
0
Franz
Top achievements
Rank 1
answered on 12 Feb 2015, 08:45 AM
Hi, Vladimir,
yes this issue is solved with the explanation of my last post.

Regards Franz
Tags
General Discussions
Asked by
Franz
Top achievements
Rank 1
Answers by
Franz
Top achievements
Rank 1
Vladimir Iliev
Telerik team
Share this question
or