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

Dynamic RadDock interaction with Grid / AJAX-enabled Context Menu

5 Answers 180 Views
Dock
This is a migrated thread and some comments may be shown as answers.
Andy
Top achievements
Rank 1
Andy asked on 09 Nov 2009, 09:24 PM
I have created a dynamic  dashboard for my application using code from the following two examples:


I have modified the My Portal example to fit our data structure, but the way that user-controls are dynamically added into RadDocks to create "widgets" is the same as the My Portal example.  My problem is that about half of my user-controls are using the Grid context menu technique mentioned above.  When one of these user-control/dock objects gets added to the page I get the following JS error which is puzzling to me.  

Message: Sys.WebForms.PageRequestManagerServerErrorException: An unknown error occurred while processing the request on the server. The status code returned from the server was: 500 
Line: 6 
Char: 62099 
Code: 0 
URI: http://localhost:53177/Website/Telerik.Web.UI.WebResource.axd?_TSM_HiddenField_=ctl00_ScriptManagerMain_HiddenField&compress=1&_TSM_CombinedScripts_=%3b%3bSystem.Web.Extensions%2c+Version%3d3.5.0.0%2c+Culture%3dneutral%2c+PublicKeyToken%3d31bf3856ad364e35%3aen-US%3ad0c4ca6e-6b5d-49b6-922d-5244924fb100%3aea597d4b%3ab25378d2 

My guess to as what is happening is that the RowContextMenu function has not been loaded at the time the Grid is looking for it.  I am not using a RadAjaxManager on this page, only an asp:updatepanel with the button that adds the dock set as an AsyncPostBackTrigger.

How can I get this two great code samples to cooperate with each other? Please let me know if more information is needed.  

Thanks, Andy

Edit:  I should also add that this also occurs on a separate page where a user-control that is being loaded dynamically and contains a  RadGrid and is using the RowContextMenu code.

There error I get here is more helpful in deciphering the issue but I do not know how to go about fixing it still:

Message: 'PersonToDoRowContextMenu' is undefined 
Line: 204658269 
Char: 5 
Code: 0 
URI: http://localhost:53177/Website/Contacts/Contacts.aspx 
 

This seems to back up my guessing that the JS is not added when the grid looks for it.

5 Answers, 1 is accepted

Sort by
0
Pero
Telerik team
answered on 12 Nov 2009, 11:58 AM
Hello Andy,

Indeed this is the problem causing the JavaScript exception - the RadGrid cannot find the client-side event handler of the OnRowContextMenu client-side event. To solve this problem you can put  the method in the <head> tag of the .aspx where the UserControl is dynamically added. The only problem that arises is how to find the client-side object of the RadMenu of the corresponding RadGrid.

Here is how I implemented this method. I am finding the ClientId of the Menu with the help of the RadGrid's ClientId (which in our case is the sender of the event).

<head runat="server">
 
    <script type="text/javascript">
        function RowContextMenu(sender, eventArgs)
        {
            var senderID = sender.get_id();
            var menuID = senderID.substring(0, senderID.lastIndexOf('_')) + "_RadMenu1";
            var menu = $find(menuID);
            var evt = eventArgs.get_domEvent();
 
            if (evt.target.tagName == "INPUT" || evt.target.tagName == "A")
            {
                return;
            }
 
            var index = eventArgs.get_itemIndexHierarchical();
            document.getElementById("radGridClickedRowIndex").value = index;
 
            sender.get_masterTableView().selectItem(sender.get_masterTableView().get_dataItems()[index].get_element(), true);
 
            menu.show(evt);
 
            evt.cancelBubble = true;
            evt.returnValue = false;
 
            if (evt.stopPropagation)
            {
                evt.stopPropagation();
                evt.preventDefault();
            }
        }
    </script>
 
</head>


Do not hesitate to contact us, If you have other problems or questions.


Sincerely yours,
Pero
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Andy
Top achievements
Rank 1
answered on 12 Nov 2009, 07:20 PM
Thanks for your response Pero.  Moving the context menu javascript to the page head of the aspx page is easier said than done.

First,  I have a master page where the page header is.  Here is the hierarchy of everything in question.

  • FrameworkMaster.master (RadScriptManager)
  • Dashboard.aspx (RadAjaxManager, RadDockLayout, RadDockZone, RadDock ( UserControl )) 
  • UserControl.ascx (RadGrid w/ ContextMenu and RadScriptBlock containing script for ContextMenuRowIndex)

Secondly, I need the javascript to load only if the dynamic user control has been loaded.  I would like to limit the amount of javascript I need to call upon. If the user only wants only one or two of the dynamic user controls loaded I don't want to have to write all of the javascript to support the dozen or so user controls that the user has the option of adding.

Is there any way around this?  Can I do something with the RadScriptManager I have on my masterpage? Possibly register the context menu script with the ScriptManager on the master page in the page load of the user control?

Thanks, Andy

(Edited for spelling and further clarity)
0
Pero
Telerik team
answered on 17 Nov 2009, 03:23 PM
Hi Andy,

Another way of course is dynamically loading the client-script from the server with the ScriptManager.RegisterStartupScript method. Here is how I registered the client-script from the server:

protected void Page_Load(object sender, EventArgs e)
{
    string menuScript = "function RowContextMenu(sender, eventArgs)" +
"{" +
    "var senderID = sender.get_id();" +
    "var menuID = senderID.substring(0, senderID.lastIndexOf('_')) + '_RadMenu1';" +
    "var menu = $find(menuID);" +
    "var evt = eventArgs.get_domEvent();" +
 
    "if (evt.target.tagName == 'INPUT' || evt.target.tagName == 'A')" +
    "{" +
        "return;" +
    "}" +
 
    "var index = eventArgs.get_itemIndexHierarchical();" +
    "document.getElementById('radGridClickedRowIndex').value = index;" +
 
    "sender.get_masterTableView().selectItem(sender.get_masterTableView().get_dataItems()[index].get_element(), true);" +
 
    "menu.show(evt);" +
 
    "evt.cancelBubble = true;" +
    "evt.returnValue = false;" +
 
    "if (evt.stopPropagation)" +
    "{" +
        "evt.stopPropagation();" +
        "evt.preventDefault();" +
    "}" +
"}";
    ScriptManager.RegisterStartupScript(Page, Page.GetType(), "menuHandler", menuScript, true);
}

And here is the full source code of the .ascx file (with the CodeBehind) that contains the RadGrid:

.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Grid.ascx.cs" Inherits="Dock_Common_Grid" %>
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<%@ Register TagPrefix="sds" Namespace="Telerik.Web.SessionDS" %>
<input type="hidden" id="radGridClickedRowIndex" name="radGridClickedRowIndex" value="1" />
<p>
    Right-click the grid to open context menu.</p>
<div style="margin-right: 20px;">
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <telerik:RadGrid ID="RadGrid1" runat="server" Width="100%" DataSourceID="SessionDataSource1"
                AllowAutomaticDeletes="true" AllowAutomaticInserts="true" AllowAutomaticUpdates="true"
                OnPreRender="RadGrid1_PreRender">
                <MasterTableView AllowSorting="False" PageSize="10" AllowPaging="True" Width="100%"
                    DataKeyNames="ProductID" DataSourceID="SessionDataSource1" EditMode="InPlace">
                    <Columns>
                        <telerik:GridEditCommandColumn UniqueName="EditCommandColumn" Visible="false" />
                    </Columns>
                </MasterTableView>
                <ClientSettings>
                    <ClientEvents OnRowContextMenu="RowContextMenu"></ClientEvents>
                    <Selecting AllowRowSelect="true" />
                </ClientSettings>
                <PagerStyle Mode="NextPrevAndNumeric" />
            </telerik:RadGrid>
            <telerik:RadContextMenu ID="RadMenu1" runat="server" OnItemClick="RadMenu1_ItemClick">
                <Items>
                    <telerik:RadMenuItem Text="Add" />
                    <telerik:RadMenuItem Text="Edit" />
                    <telerik:RadMenuItem Text="Delete" />
                </Items>
            </telerik:RadContextMenu>
        </ContentTemplate>
    </asp:UpdatePanel>
</div>
<br />
<sds:SessionDataSource ID="SessionDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
    SelectCommand="SELECT ProductID, ProductName,UnitPrice, UnitsInStock FROM [Products]"
    DeleteCommand="DELETE FROM [Products] WHERE [ProductID] = ?" InsertCommand="INSERT INTO Products(ProductName, SupplierID, CategoryID, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
    UpdateCommand="UPDATE [Products] SET [ProductName] = ?,[QuantityPerUnit] = ?, [UnitPrice] = ?, [UnitsInStock] = ? WHERE [ProductID] = ? AND [ProductName] = ? AND [UnitPrice] = ? AND [UnitsInStock] = ?"
    PrimaryKeyFields="ProductID" OldValuesParameterFormatString="original_{0}" ConflictDetection="CompareAllValues">
    <DeleteParameters>
        <asp:Parameter Name="original_ProductID" Type="Int32" />
    </DeleteParameters>
    <UpdateParameters>
        <asp:Parameter Name="ProductName" Type="String" />
        <asp:Parameter Name="UnitPrice" Type="Decimal" />
        <asp:Parameter Name="UnitsInStock" Type="Int16" />
        <asp:Parameter Name="original_ProductID" Type="Int32" />
        <asp:Parameter Name="original_ProductName" Type="String" />
        <asp:Parameter Name="original_QuantityPerUnit" Type="String" />
        <asp:Parameter Name="original_UnitPrice" Type="Decimal" />
        <asp:Parameter Name="original_UnitsInStock" Type="Int16" />
    </UpdateParameters>
    <InsertParameters>
        <asp:Parameter Name="ProductName" Type="String" />
        <asp:Parameter Name="SupplierID" Type="Int32" />
        <asp:Parameter Name="CategoryID" Type="Int32" />
        <asp:Parameter Name="UnitPrice" Type="Decimal" />
        <asp:Parameter Name="UnitsInStock" Type="Int16" />
        <asp:Parameter Name="UnitsOnOrder" Type="Int16" />
        <asp:Parameter Name="ReorderLevel" Type="Int16" />
        <asp:Parameter Name="Discontinued" Type="Boolean" />
    </InsertParameters>
</sds:SessionDataSource>

.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Telerik.Web.UI;
 
public partial class Dock_Common_Grid : System.Web.UI.UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string menuScript = "function RowContextMenu(sender, eventArgs)" +
    "{" +
        "var senderID = sender.get_id();" +
        "var menuID = senderID.substring(0, senderID.lastIndexOf('_')) + '_RadMenu1';" +
        "var menu = $find(menuID);" +
        "var evt = eventArgs.get_domEvent();" +
 
        "if (evt.target.tagName == 'INPUT' || evt.target.tagName == 'A')" +
        "{" +
            "return;" +
        "}" +
 
        "var index = eventArgs.get_itemIndexHierarchical();" +
        "document.getElementById('radGridClickedRowIndex').value = index;" +
 
        "sender.get_masterTableView().selectItem(sender.get_masterTableView().get_dataItems()[index].get_element(), true);" +
 
        "menu.show(evt);" +
 
        "evt.cancelBubble = true;" +
        "evt.returnValue = false;" +
 
        "if (evt.stopPropagation)" +
        "{" +
            "evt.stopPropagation();" +
            "evt.preventDefault();" +
        "}" +
    "}";
        ScriptManager.RegisterStartupScript(Page, Page.GetType(), "menuHandler", menuScript, true);
    }
 
    protected void RadGrid1_PreRender(object sender, EventArgs e)
    {
        if (RadGrid1.EditIndexes.Count > 0 || RadGrid1.MasterTableView.IsItemInserted)
        {
            GridColumn col1 = RadGrid1.MasterTableView.GetColumn("EditCommandColumn") as GridColumn;
            col1.Visible = true;
        }
        else
        {
            GridColumn col2 = RadGrid1.MasterTableView.GetColumn("EditCommandColumn") as GridColumn;
            col2.Visible = false;
        }
    }
    protected void RadMenu1_ItemClick(object sender, RadMenuEventArgs e)
    {
        int radGridClickedRowIndex;
 
        radGridClickedRowIndex = Convert.ToInt32(Request.Form["radGridClickedRowIndex"]);
 
        switch (e.Item.Text)
        {
            case "Edit":
                RadGrid1.Items[radGridClickedRowIndex].Edit = true;
                RadGrid1.Rebind();
                break;
            case "Add":
                RadGrid1.MasterTableView.IsItemInserted = true;
                RadGrid1.Rebind();
                break;
            case "Delete":
                RadGrid1.MasterTableView.PerformDelete(RadGrid1.Items[radGridClickedRowIndex]);
                break;
        }
    }
 
}

I tested this code and it works without a problem on my side. Let me know if you have any problems.


Sincerely yours,
Pero
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
OfficeHeart
Top achievements
Rank 1
answered on 29 Sep 2010, 10:15 AM
Hi,

We have the same problem. Is there a better solution then described above?
Because we use many of
var grid = $find('<%= RadGrid1.ClientID %>')
and they all not work.

Thanks in advance!
0
Rumen
Telerik team
answered on 01 Oct 2010, 04:29 PM
Hi Martin,

Using this approach should be used to gain better performance. There is another way to obtain a reference to the array of all Telerik controls described in this KB article: How-to create a javascript array of all particular RadControls on the page.
However, you should note that this way loops through all Telerik controls and could decrease performance.

Kind regards,
Rumen
the Telerik team
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 Public Issue Tracking system and vote to affect the priority of the items
Tags
Dock
Asked by
Andy
Top achievements
Rank 1
Answers by
Pero
Telerik team
Andy
Top achievements
Rank 1
OfficeHeart
Top achievements
Rank 1
Rumen
Telerik team
Share this question
or