views:

502

answers:

2

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>
A: 

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'
        });
    }
}
Darin Dimitrov
A: 

after playing with it a bit, I got it to work. I think the problem was that I was just using quicksearch() incorrectly somehow. I tried later with a simple alert() and it worked fine. Thanks for the suggestions!

Ben Collins