Solving using the ClientOnClickUsingPostBackEvent in ascx UserControls

In my previous post I showed you how to use the LinqDatasource together with the SPGridView. I have since then run into some more “trouble “that I´d like to share with you.
The goal this time is to implement a “Delete” MenuItemTemplate that triggers an event on the server, something that looks like this:

image

The first thing is to is to modify the markup:


<SharePoint:MenuTemplate runat="server"ID="GridViewMenu"
   EnableSorting="true">

    <SharePoint:MenuItemTemplate runat="server"
       Text="Delete contact"
       ClientOnClickUsingPostBackEvent="__page, DELETE, %Id%"
       ClientOnClickPostBackConfirmation="Are you sure you want to delete this item?"
       ImageUrl="\_layouts\images\DELETE.GIF" />           

</SharePoint:MenuTemplate>

…[CODE OMITTED FOR CLARITY - see previous post]

<Columns>
    <SharePoint:SPMenuField HeaderText="FirstName" MenuTemplateId="GridViewMenu"
        TokenNameAndValueFields="Id=Id,DispForm=DispForm,fname=fname"
        TextFields="fname"
        SortExpression="fname"
        NavigateUrlFields="DispForm"
        NavigateUrlFormat="{0}" />
    <asp:BoundField HeaderText="Lastname"
        DataField="lname"
        SortExpression="lname" />
    <asp:BoundField HeaderText="Country"
        DataField="country"
        SortExpression="country" />

</Columns>

 The thing to notice here is the “ClientOnClickUsingPostBackEvent” which is the thing that will send my arguments to the server.
So, the servercode will look something like this with the implementation of the IPostBackEventHandler.


public partial class Linq : System.Web.UI.Page, IPostBackEventHandler 

…[CODE OMITTED FOR CLARITY - see previous post]

public void RaisePostBackEvent(string eventArgument)
{
    string[] events = eventArgument.Split(',');

    switch (events[0].Trim())
    {
        case "DELETE":
            LinqDS.SelectParameters.Add("itemId", events[1]);
            ContactsGridView.DataBind();
            break;
    }
}

This works just fine, I mean this demo code removes the item I select from the SPGridView when I use the menu option “delete”.
I got this idea from the community (Pawlos in the links below) and didn´t really care how it worked until I got problems when I thought I clean up my code a bit and move it to a separate ascx UserControl. Cause, when I did this my code didn´t work any more.

So, I started to investigate why this was.

 

The solution

If you have a look at this line:
ClientOnClickUsingPostBackEvent=”__page, DELETE, %Id%”

This will generate the __doPostback  script with this id of the page as the first parameter, which we can see when using reflector on the MenuItemTemplate class:

image

from: http://forums.asp.net/p/1251278/2324698.aspx#2324698 

“__doPostback is ASP.NET’s way of doing javascript postbacks (i.e. postbacks that can’t be done with a submit button). The first argument is eventTarget, which is the control that is sending the submission; I believe this control must implement IPostBackEventHandler. The second argument contains any additional information you might want to send with your postback.
It’s easiest to generate a call to __doPostBack through Page.GetPostBackClientEvent. “

More reflector (this time GetPostBackEventReference ):

image

OK, so I need to send the Unique Id of the UserControl as the first argument to ClientOnClickUsingPostBackEvent
Unfortunately, we cant use this.Id or something like that. But we can get the Id of the usercontrol with a javascript function, something like:

 

<script type="text/javascript">
    function myfunction(param) {
        __doPostBack("<%= this.UniqueID %>", param);
    }
</script> 

notice that we need to use the Unique Id of the UserControl in order to get the full naming container id (ie PageContainer$IdOfUC).
Then I call that javascript through ClientOnClickScript instead, like so:


<SharePoint:MenuTemplate runat="server" ID="GridViewMenu"
    EnableSorting="true">

    <SharePoint:MenuItemTemplate runat="server"
        Text="Delete contact"
        ClientOnClickScript="myfunction('DELETE,%Id%');"
        ImageUrl="\_layouts\images\DELETE.GIF" />           

</SharePoint:MenuTemplate>

And, now it works….
Some other useful links:
Johan@Avanade
Pawlos

Advertisements

,

  1. #1 by ItsMeSri on December 18, 2009 - 07:27

    It works everything fine, but “ClientOnClickPostBackConfirmation” message not displaying. How to manage that in javascript method?

    • #2 by Johan Leino on December 20, 2009 - 19:40

      Are you looking for something like if(confirm(“You wanna continue?”)) __doPostBack(…)

  2. #3 by ItsMeSri on December 24, 2009 - 19:57

    I am using SPGridView in UpdatePanel. __doPostBack(“”, param); is refreshing whole page. not only updatepanel.

  3. #4 by Leo on July 16, 2011 - 18:00

    Hi,

    I’ve tried your postback article for ASCX. But Somehow when it postback I got ASPX page error saying control ID for my menutemplate cannot be found. Can you give more detail on how to go about implementing IPostbackEventHandler or some working sample code?

    • #5 by Johan Leino on August 1, 2011 - 16:18

      Sorry for the late reply…I’ve been on vacation.
      Have you tried setting the ID of the template. It’s been a while since I wrote that post and the code but have you looked at this post:
      https://johanleino.wordpress.com/2009/05/12/use-unique-ids-for-menutemplates/

      • #6 by Dan Chenier on September 13, 2012 - 18:25

        I had the same problem. Really, the cause is not reading the whole article carefully 🙂
        You can’t use the ClientOnClickUsingPostBackEvent to post back to the ascx control; you hvae to use the ClientOnClickScript, like the article says.

        The reason you can’t use ClientOnClickUsingPostBackEvent is because the MenuItemTemplate uses this.FindControl(/*Id*/) to find for the control to post back to (if you don’t use __page). So it only looks for controls inside the MenuItemTemplate – but the ascx control is a parent of MenuItemTemplate, so it won’t find it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: