Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UpdatePanel startup script not executing

I'm writing an ASP.NET webpart for use in a SharePoint site and trying to use an UpdatePanel to render query results. I want to use a JQuery plugin to modify the table returned from the asynchronous postback, but I'm having trouble getting the startup script to execute on the asynchronous udpate.

I found this post which indicates that the UpdatePanel won't do an eval() on startup scripts; instead, you must register the startup script block with the ScriptManager. It all makes sense until it doesn't work. The MSDN reference documentation seems to concur with the approach taken there.

My control is too long to post completely, but here's a trimmed-down representation that I think covers anything relevant. Forgive me if there are missing controls in the paste below - I had to remove some parts, and there may be some dangling tentacles, so to speak. The below is the code for the webpart, which is not unlike the SmartPart which loads a user control (.ascx).

As you can see, I am using the ScriptManager.RegisterStartupScript method. I've tried both overloads; once for the Page, and once for the ListView (renamed as 'AspListView') which is in the update panel. In neither case does the startup script execute on the asynchronous update, and I'm at a loss for why.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace MyNamespace
{
    using AspListView = System.Web.UI.WebControls.ListView;

    [Guid("601b3bdb-ed2a-4ec8-8a40-c37de8ab048d")]
    public class ListSearch : StaticTemplateWebPart
    {
        private AspListView resultsList;

        public ListSearch()
        {
        }

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

            ScriptLink.Register(Page, "jquery-1.3.2.js", false);
            ScriptLink.Register(Page, "jquery-ui-1.7.2.custom.min.js", false);
            ScriptLink.Register(Page, "jquery.timepickr.js", false);
            ScriptLink.Register(Page, "jquery.quicksearch.js", false);

            string scriptBlock =
@"
if ($('table#discrepancy-results').length)
{
    $('table#discrepancy-results tr').quicksearch({
        position: 'before',
        attached: 'table.results',
        stripeRowClass: ['odd', 'even'],
        labelText: 'Keyword Search'
    });
}";
            ScriptManager.RegisterStartupScript(Page, typeof(Page), UniqueID, scriptBlock, true);

            /* adding other controls, getting references, databinding, etc. */

        }             

        void searchButt_Click(object sender, EventArgs e)
        {           
            if (Page.IsPostBack)
            {
                var beginDT = DateTime.Parse((beginDateText.Text ?? "") + " " + (beginTimeText.Text ?? ""));
                var endDT = DateTime.Parse((endDateText.Text ?? "") + " " + (endTimeText.Text ?? ""));
                var dataList = SPContext.Current.Web.Lists["MyDataList"].Items;

                var results = SearchListItems(dataList, beginDT, endDT, keywordText.Text ?? "");
                if (results.Count > 0)
                {
                    resultsList.DataSource = results;
                    resultsList.DataBind();
                }
            }
        }
    }
}

And the user control that gets loaded:

<%@ Control Language="C#" ClassName="ListSearchControl" %>

<% if (false)
   { %>
    <script src="../../LAYOUTS/jquery-1.3.2-vsdoc2.js" type="text/javascript"></script>    
<% } %>

<script type="text/javascript">
    $(function() {
        $('id').trigger('click');
        $('#<%= BeginTime.ClientID %>').timepickr({
            handle: '#<%= BeginTimeTrigger.ClientID %>',
            convention: 12,
            trigger: 'nothing' 
        });
        $('#<%= EndTime.ClientID %>').timepickr({
            handle: '#<%= EndTimeTrigger.ClientID %>',
            convention: 12,
            trigger: 'nothing'
        });        
    });
</script>

<asp:Panel ID="ControlPanel" runat="server">
    <asp:Panel ID="Inputs" runat="server">
        <asp:Panel CssClass="DateInputWrapper" runat="server">
            <asp:Panel CssClass="BeginDateInput" runat="server">
                <asp:Label Text="Begin Date: "  runat="server" />   
                <asp:TextBox ID="BeginDate" Columns="14" runat="server"></asp:TextBox>     
                <asp:Image ID="BeginDateImg" ImageUrl="/_layouts/Images/calendar.gif" runat="server" />
                <ajax:CalendarExtender ID="BeginDateExtender" TargetControlID="BeginDate" PopupButtonID="BeginDateImg" 
                                       Format="MMMM d, yyyy" runat="server">
                </ajax:CalendarExtender>
                <asp:Label Text="Begin Time: " runat="server" />
                <asp:TextBox ID="BeginTime" Columns="6" Text="04:00 am" runat="server"></asp:TextBox>
                <asp:Image ID="BeginTimeTrigger" runat="server" ImageUrl="/_layouts/1033/Images/clock.png" />                        
            </asp:Panel>                    
            <asp:Panel CssClass="EndDateInput" runat="server">
                <asp:Label Text="End Date: " runat="server" />                        
                <asp:TextBox ID="EndDate" Columns="14" runat="server"></asp:TextBox>     
                <asp:Image ID="EndDateImg" ImageUrl="/_layouts/Images/calendar.gif" runat="server" />
                <ajax:CalendarExtender ID="EndDateExtender" TargetControlID="EndDate" PopupButtonID="EndDateImg" 
                                       Format="MMMM d, yyyy" runat="server">
                </ajax:CalendarExtender>
                <asp:Label Text="End Time: " runat="server" />
                <asp:TextBox ID="EndTime" Columns="6" Text="03:59 am" runat="server"></asp:TextBox>
                <asp:Image ID="EndTimeTrigger" runat="server" ImageUrl="/_layouts/1033/Images/clock.png" />
            </asp:Panel>   
        </asp:Panel>         
        <asp:Panel CssClass="Submit" runat="server">
            <asp:Button ID="SearchButton" Text="Search" runat="server" />
            <asp:Label CssClass="SearchStatusText" runat="server" />
        </asp:Panel>       
    </asp:Panel>
</asp:Panel>

<asp:Panel ID="ResultsPanel" runat="server">
    <asp:ListView ID="ResultsList" runat="server">
        <LayoutTemplate>            
            <table id="discrepancy-results">
                <tr class="header-row">                    
                    <th>Scheduled Date/Time</th>                   
                    <th>Code</th>     
                    <th>Description</th>               
                </tr>                
                <asp:PlaceHolder runat="server" ID="itemPlaceHolder" />
            </table>            
        </LayoutTemplate>
        <ItemTemplate>
            <tr class="result-row">                
                <td><%# Eval("ScheduledDate") %></td>                
                <td><%# Eval("Code") %></td>         
                <td><%# Eval("Description") %></td>
            </tr>
        </ItemTemplate>
    </asp:ListView>
</asp:Panel>

<asp:Panel ID="DetailsPanel" runat="server">
</asp:Panel>
like image 686
Ben Collins Avatar asked May 29 '26 12:05

Ben Collins


2 Answers

I'd like to add that the updatepanel startupscripts wouldn't work for us unless you used the UpdatePanel's ID, and typeof(UpdatePanel). Using startupscripts elsewhere outside an updatepanel wasn't as fussy. We got this working like this:

ScriptManager.RegisterStartupScript(UpdatePanelId, typeof(UpdatePanel), "myScript",
                    / *
                      * Register a startup script to run 
                      * on the client after running this method on the server
                      * /
                    @" alert('Add your function to replace this.');", true);

The solution presented by Darin would work as well, but in our case the updatepanel has more functionality and would require additional logic to 'track' what was being done so the script wouldn't execute on every single update to the update panel, but only after a certain event. This way the script is only executed on this event.

like image 169
lko Avatar answered Jun 01 '26 01:06

lko


Instead of using ScriptManager.RegisterStartupScript here's something else you might try. Register for the end_request event of the UpdatePanel and execute your jQuery script:

// This could also be done in jQuery's $(document).ready
function pageLoad() {
    Sys.WebForms
       .PageRequestManager
       .getInstance()
       .add_endRequest(endRequestHandler);
}

function endRequestHandler(sender, args) {
    // Shouldn't the next test be: 
    // $('table#discrepancy-results').length > 0 ???
    // and is it necessary at all? I suppose the quicksearch plugin
    // won't apply on empty array

    if ($('table#discrepancy-results').length) {
        $('table#discrepancy-results tr').quicksearch({
            position: 'before',
            attached: 'table.results',
            stripeRowClass: ['odd', 'even'],
            labelText: 'Keyword Search'
        });
    }
}
like image 39
Darin Dimitrov Avatar answered Jun 01 '26 01:06

Darin Dimitrov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!