为什么我的 jQuery UI 日期选择器在初始页面加载时工作正常时不能用于回发?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1987096/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 12:31:52  来源:igfitidea点击:

Why doesn't my jQuery UI datepicker work for postbacks when it works fine on initial page loads?

asp.netjqueryuser-controlsmaster-pagesjquery-ui-datepicker

提问by JeffK

I've been trying to integrate the jQuery UI Datepicker into our ASP.NET WebForms application. The application uses master pages to provide a common look to all pages, and all of the content pages are built inside the ContentTemplate of an UpdatePanel. I've created a user control to wrap the datepicker's functionality and allow setting of the minDate, maxDate, validators, etc. for each date from the codebehind at runtime. I also need to deal with the way ASP.NET generates client element IDs.

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

Over the last week, I've searched high and low, and found lots of tips for getting it to work. Here is a somewhat simplified version of where I'm at right now.

在过去的一周里,我搜索了高低,并找到了很多让它发挥作用的技巧。这是我现在所处位置的简化版本。

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

I've left out the validators and some other markup that I don't think is related to the issue, but that's the meat of the user control--a textbox, and the jQuery script that enables the datepicker functionality. The basic idea is to leverage ASP.NET's client IDs to:

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

  1. Provide a unique function name for the JavaScript function for this specific control
  2. Register that function with jQuery to enable the datepicker after the initial page load
  3. Register that same function with ASP.NET's PageRequestManager to keep the datepickers enabled after postbacks
  1. 为该特定控件的 JavaScript 函数提供唯一的函数名称
  2. 使用 jQuery 注册该函数以在初始页面加载后启用日期选择器
  3. 使用 ASP.NET 的 PageRequestManager 注册相同的函数以在回发后保持启用日期选择器

Items 1 and 2 are working great. However, after a postback, the datepicker functionality is lost and I'm left with just a textbox.

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

But wait! That's not all. A given page consists of multiple panels, only one of which is visible at a time. These are selected by only having the Visible property true for the current panel. The Visible property for all of other panels are set to false.

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

Now get this: The datepickers on the first panel, the one displayed upon initial page load, work as expected. Those on the second panel just don't show up. Going back to the first page, the datepickers show up again.

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

Does anyone have any ideas where I'm going wrong?

有没有人知道我哪里出错了?

回答by Vipin

While $(document).ready() is ideal for one-time initialization routines, it leaves you hanging if you have code that needs to be re-run after every partial postback. The LiveQuery functionality added in jQuery v1.3+ helps with this, but only works for a limited set of functionality.

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

For example, what if we wanted to add a jQueryUI datepicker to the TextBox in the previous example? Adding it in $(document).ready() would work great, untila partial postback occurred. Then, the UpdatePanel's new TextBox element would no longer have the datepicker wired up to it.

例如,如果我们想在前面的示例中为 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>

This above Answer is taken from the below link. I have tested and implemented this in one of my project.

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

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

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

回答by DirtyD77

Sorry for the late reply.

这么晚才回复很抱歉。

Why not try this:

为什么不试试这个:

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

then put the textbox in an updatepanel with the following trigger:

然后使用以下触发器将文本框放入更新面板中:

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

回答by Chetan Sastry

I think a cleaner way to do this is to use ClientScriptManager.RegisterStartupScript.

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

Javascript:

Javascript:

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

In your code behind (OnPreRenderperhaps):

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

Page.ClientScript.RegisterStartupScript(this.GetType(), "SomeName", string.Format("<script>initCalendar('{0}');</script>", txtBox.ClientID));

回答by Mark Henry

Well,

好,

Here is the solution of this problem. Below link explains why the datepicker doesn't work after ajax postback and the solution to make it work within ajax.

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

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

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

回答by Bhaumik Mehta

Just Simply use bellow code in Page_Load code behind..

只需在后面的 Page_Load 代码中使用波纹管代码即可。

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

TextBoxDOB.Text = DOB;

I implemented this and works like a charm

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

回答by Vijay Kumbhoje

if you are using update panel then don't get panic just Click hereand relax. Elaborated answer

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

回答by SLaks

When you set a control's Visibleproperty to false, it doesn't get rendered at all.

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

That means that the Javascript inside the invisible panels did not existwhen the page was first loaded.

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

To solve this, you can hide your panels using CSS (display: none) instead of the Visibleproperty.

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

回答by Manuel Vázquez

Try this inside the update panel

在更新面板中试试这个

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

回答by user7649899

The solution helped me. The date picher values must be in pageLoad() function inorder for the date picker to show on postbacks. Here is my working code

解决方案帮助了我。日期选择器值必须在 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>