Ajax webpart: Register scripts on UpdatePanel postbacks

These days I’m developing custom ajax enabled webparts for a sharepoint solution. I’ve created a base webpart class named AjaxEnabledWebpart from which all the webparts inherit. This webpart has an updatepanel control where all the child webparts are supposed to create the controls they need so finally, everycontrol is rendered inside the updatepanel and the webpart has the expected asp.net ajax behaviour of partial rendering the pages. Some of the webparts have to render content created dinamically by javascript code as you will see later in the code, in this case, content is rendered this way because we are supposed to give an accessible front end in our webpart (this is supporting non-script enabled browsers) so we are using the typical <noscript><script> tag approach. However, the problem we faced is that the content rendering script code (or any script code at all) was not executed during Ajax postbacks of the webpart. The solution we found to this problem was to register the scripts with the Sys.WebForms.PageRequestManager.getInstance().add_endRequest() function. Following is the code we used. First, for reference only, I’ll post the main code of the AjaxEnabledWebpart which somebody might find useful

protected override void CreateChildControls()
{
    base.CreateChildControls();

    EnsurePanelFix();

    _updatePanel = new UpdatePanel();

    _scriptHandler = ScriptManager.GetCurrent(this.Page);
    if (_scriptHandler == null)
    {
        //no script manager registered
        _scriptHandler = new ScriptManager();
        _scriptHandler.ID = "scriptManager";
        this.Controls.Add(_scriptHandler);
    }

    _updatePanel.ID = "updatePanel_";
    _updatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional;
    _updatePanel.ChildrenAsTriggers = true;

    CreatePanelControls(_updatePanel.ContentTemplateContainer.Controls);

    this.Controls.Add(_updatePanel);
}

protected virtual void CreatePanelControls(ControlCollection PanelControls)
{
}

The only relevant code from the AjaxEnabledWebpart is the CreateChildControls method, which creates the UpdatePanel control and calls the virtual method CreatePanelControls passing as a parameter the control collection where child pages are supposed to add the controls. Also, you can find the EnsurePanelFix implementation on my previous post at this linkAfter that, here is the code of a custom HtmlTable used in some webparts which contents are rendered using javascript code (if scripting is enabled in the client browser). The posted code is a function which returns the html code to be inserted in a cell’s InnerHtml property of a table:

private string _getSelectAllHtml(HtmlTableCell cell)
{
    string ret = "";

    ret += "" +
                "select all" +
             "" +
             "" +
                "// " +
            "" +
           "";

    string fn = "" +
                    "//<![CDATA[ n" +
                        "function _loadSelectAllHeader() { " +
                            "cab = '<a href="#" title="CellTitle">" +
                            "<img src="_layouts/img/selectall.gif" alt="select all">';" +
                            "var capa = document.getElementById("" + cell.Attributes["Id"] + "");" +
                            "capa.innerHTML = cab;n" +
                        " }" +
                    "//]]> " +
                "";

    Page.ClientScript.RegisterClientScriptBlock(typeof(ResultsTableMod47),
                                "_loadSelectAllHeader",
                                fn);

    Page.ClientScript.RegisterStartupScript(typeof(ResultsTableMod47),
                                "initRequestScriptHandler_loadSelectAllHeader",
                                "Sys.WebForms.PageRequestManager.getInstance().add_endRequest(_loadSelectAllHeader);");

    return ret;
}

The relevant lines of the code are the calls to RegisterClientScriptBlock and RegisterStartupScript methods. The first one register our content-rendering script while the second one adds this function to the end_request handler of the PageRequestManager instance. This will ensure that the script is called after each Ajax postback of the pages.Further scripts can be registered in the end_request handler by calling the add_endRequest method for each script we want to be executed after a postback. However, we have to considered that this script will be executed for all the postbacks and not only for the ones generated by this webpart’s updatepanel control, so if more than one updatepanel is present on the page, we might have to include some checking at the startup of our code to ensure that our script must be executed. In this case this was not necessary since the script could be executed again without any problem.

That’s all for now ! I hope it’s useful…. coments are welcome :-)

About these ads

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

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: