3

我一直在尝试将 jQuery UI Datepicker 集成到我们的 ASP.NET WebForms 应用程序中。应用程序使用母版页为所有页面提供通用外观,并且所有内容页面都构建在 UpdatePanel 的 ContentTemplate 中。我创建了一个用户控件来包装日期选择器的功能,并允许在运行时从代码隐藏中为每个日期设置 minDate、maxDate、验证器等。我还需要处理 ASP.NET 生成客户端元素 ID 的方式。

在过去的一周里,我到处搜索,找到了很多让它工作的技巧。这是我现在所处位置的稍微简化的版本。

<asp:TextBox ID="txtTB" runat="server"
    MaxLength="10"
    CssClass="dateBox" />

<script type="text/javascript">

    // This function enables the datepicker behavior for this textbox by its ClientID.
    function <%=txtTB.ClientID %>() {
        $("#<%=txtTB.ClientID %>").datepicker({
            changeMonth: true, changeYear: true,
            showOn: 'button',
            buttonImage: "<%=Request.ApplicationPath %>/images/calendarIcon.gif",
            buttonImageOnly: true, buttonText: '', duration: '',
            onSelect: function() { }
        });
    };

    // Register the above function to execute on initial page load...
    $(document).ready(function(){ <%=txtTB.ClientID %>(); }) ;

    // ...and also after any update panel it's on has been refreshed. 
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(<%=txtTB.ClientID %>);

</script>

我省略了验证器和其他一些我认为与问题无关的标记,但这是用户控件的核心——文本框和启用日期选择器功能的 jQuery 脚本。基本思想是利用 ASP.NET 的客户端 ID 来:

  1. 为此特定控件的 JavaScript 函数提供唯一的函数名称
  2. 使用 jQuery 注册该函数以在初始页面加载后启用日期选择器
  3. 使用 ASP.NET 的 PageRequestManager 注册相同的函数,以在回发后保持启用日期选择器

第 1 项和第 2 项效果很好。但是,在回发之后,日期选择器功能丢失了,我只剩下一个文本框。

可是等等!那不是全部。一个给定的页面由多个面板组成,一次只能看到一个。这些是通过仅使当前面板的 Visible 属性为 true 来选择的。所有其他面板的 Visible 属性都设置为 false。

现在得到这个:第一个面板上的日期选择器,在初始页面加载时显示的,按预期工作。第二个面板上的那些只是没有出现。回到第一页,日期选择器再次出现。

有谁知道我哪里出错了?

4

9 回答 9

10

虽然 $(document).ready() 是一次性初始化例程的理想选择,但如果您有代码需要在每次部分回发后重新运行,它会让您束手无策。jQuery v1.3+ 中添加的 LiveQuery 功能对此有所帮助,但仅适用于有限的功能集。

例如,如果我们想在前面的示例中向 TextBox 添加一个 jQueryUI 日期选择器怎么办?在 $(document).ready() 中添加它会很好,直到发生部分回发。然后,UpdatePanel 的新 TextBox 元素将不再连接日期选择器。

<script type="text/javascript">
  function pageLoad() {
    $('#TextBox1').unbind();
    $('#TextBox1').datepicker(); 
  }
</script>

<asp:ScriptManager runat="server" />

<asp:UpdatePanel runat="server">
  <ContentTemplate>
    <asp:Button runat="server" ID="Button1" />
    <asp:TextBox runat="server" ID="TextBox1" />
  </ContentTemplate>
</asp:UpdatePanel>

以上答案摘自以下链接。我已经在我的一个项目中测试并实现了这一点。

http://encosia.com/2009/03/25/document-ready-and-pageload-are-not-the-same/

于 2010-01-28T11:24:08.283 回答
2

我认为更清洁的方法是使用ClientScriptManager.RegisterStartupScript.

Javascript:

function initCalendar(controlId) {
    $("#" + controlId).blahblah(....
}

在你后面的代码中(OnPreRender也许):

Page.ClientScript.RegisterStartupScript(this.GetType(), "SomeName", string.Format("<script>initCalendar('{0}');</script>", txtBox.ClientID));
于 2009-12-31T21:23:06.773 回答
2

这么晚才回复很抱歉。

为什么不试试这个:

<script type="text/javascript">
function <%=txtTB.ClientID %>() {
    $("#<%=txtTB.ClientID %>").datepicker({
        changeMonth: true, changeYear: true,
        showOn: 'button',
        buttonImage: "<%=Request.ApplicationPath %>/images/calendarIcon.gif",
        buttonImageOnly: true, buttonText: '', duration: '',
        onSelect: function() { }
    });
};
$(document).ready(function(){ 
<%=txtTB.ClientID %>();
}) ;
</script>

然后将文本框放入带有以下触发器的更新面板中:

<asp:UpdatePanel id="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="txtTB" runat="server" MaxLength="10" CssClass="dateBox" />
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="txtTB" />
</Triggers>
</asp:UpdatePanel>
于 2012-06-04T15:29:51.070 回答
1

好,

这是这个问题的解决方案。下面的链接解释了为什么日期选择器在 ajax 回发后不起作用以及使其在 ajax 中工作的解决方案。

http://jquerybyexample.blogspot.com/2010/08/jquery-datepicker-does-not-work-after.html

于 2011-10-05T14:28:30.883 回答
0

当您将控件的Visible属性设置为 时false,它根本不会被呈现。

这意味着当页面首次加载时,不可见面板中的 Javascript不存在。

要解决这个问题,您可以使用 CSS ( display: none) 而不是Visible属性来隐藏面板。

于 2009-12-31T21:10:37.390 回答
0

在更新面板中试试这个

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>

        <script type="text/javascript">
        var prm = Sys.WebForms.PageRequestManager.getInstance();

        prm.add_endRequest(function() {
            var customer = document.getElementById("<%=cmbCustomers.ClientID%>").value;

            /* Jquery Functions Here*/
            $(document).ready(function() {
               ...
            });


        });
        </script>
于 2010-06-23T13:15:05.173 回答
0

只需在后面的 Page_Load 代码中使用波纹管代码..

string DOB = Request.Form[TextBoxDOB.UniqueID];

TextBoxDOB.Text = DOB;

我实现了这个并且像一个魅力一样工作

于 2013-12-06T01:51:31.780 回答
0

如果您正在使用更新面板,请不要惊慌,只需单击此处放松一下。详细的答案

于 2015-11-10T09:44:23.133 回答
-1

解决方案帮助了我。日期选择器值必须在 pageLoad() 函数中,以便日期选择器显示在回发中。这是我的工作代码

<script>
    var dateToday = new Date();
    var yrRange = "2000:" + (dateToday.getFullYear()); // the range is from 2003 :2016 etc etc

    //If this datepicker is not in page load , the datepicker will not show after a post back
    function pageLoad() {

        $("#<%= txtDateFrom.ClientID %>").datepicker({ showButtonPanel: true   //Use this to show the today,done and previous and next buttons on the calender
            , changeMonth: true,     //Use this to let the user select the month easily on the calender instead of using next and previous buttons
        changeYear: true
         , yearRange: yrRange
        /***********************************
         u8se these to show the max and min dates yoiu want tio show the user
         //,minDate: "-12Y"
        // , maxDate: "+1M +10D" 
        ******************************/

        // , numberOfMonths: 2                - Use this code to show more than 1 month on the calender

        /*********************
        Use the following code to show the Calender as a Icon next to the textbox.
         showOn: "button",
        buttonImage: "images/calendar.gif",
         buttonImageOnly: true,
        buttonText: "Select date"
        ******************************/                
        });

        $("#<%= txtDateTo.ClientID %>").datepicker({
            showButtonPanel: true   //Use this to show the today,done and previous and next buttons on the calender
            , changeMonth: true,     //Use this to let the user select the month easily on the calender instead of using next and previous buttons
            changeYear: true
             , yearRange: yrRange
            // minDate: -20
            // , maxDate: "+1M +10D" - u8se these to show the max and min dates yoiu want tio show the user
            //In our case
            //, maxDate: "+1Y"
            // , numberOfMonths: 2                - Use this code to show more than 1 month on the calender

            /*********************
           Use the following code to show the Calender as a Icon next to the textbox.
             ,showOn: "button",
             buttonImage: "images/icons/calendarIcon.png" ,
             buttonImageOnly: true,
            buttonText: "Select date"
           ******************************/
        });            
    }       
</script>
于 2017-03-02T20:50:41.587 回答