tags:

views:

37

answers:

2

I am attempting to construct my own date picker using code from several sources.

Why won't the calendar hide when visible?

myDate.ascx

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="myDate.ascx.vb"
    Inherits="Website.myDate" %>

<asp:TextBox ID="dateText" runat="server" > </asp:TextBox>
<asp:Button ID="dateBtn" runat="server" UseSubmitBehavior="false" Text="x" />
<asp:Calendar ID="dateCal" runat="server" ></asp:Calendar>

myDate.ascx.vb

Partial Public Class myDate
    Inherits System.Web.UI.UserControl

    Protected Sub dateCal_SelectionChanged(ByVal sender As Object, ByVal e As EventArgs) Handles dateCal.SelectionChanged
        dateText.Text = dateCal.SelectedDate ' Update text box'
        dateCal.Visible = False              ' Hide calendar'
    End Sub

    Protected Sub dateCal_VisibleMonthChanged(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.MonthChangedEventArgs) Handles dateCal.VisibleMonthChanged
        dateCal.Visible = True ' For some reason, changing the month hides the calendar (so show it)'
    End Sub

    Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        dateCal.Visible = False ' Hide calendar on load'
    End Sub

    Protected Sub dateBtn_Click(ByVal sender As Object, ByVal e As EventArgs) Handles dateBtn.Click
        dateCal.Visible = Not dateCal.Visible ' On button press, toggle visibility'
    End Sub
End Class
+1  A: 

First of all, if you want to toggle controls between page postbacks, you need to use ViewState. Check, is your page uses ViewState.

EnableViewState for the page must be set to true in your case.

Also, check your Page_load function.

On every loading of the page you are hiding your calendar

Page_load is calling every time before any button or calendar even rises. So, you are changing visibility to true and then using changed visibility value in events:

dateCal.Visible = Not dateCal.Visible

That's making calendar always be visible when you are clicking on dateBtn

To make it clear to you i will order events in your code in the order they are calling:

Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        dateCal.Visible = False ' Hide calendar on load'
    End Sub

Protected Sub dateCal_SelectionChanged(ByVal sender As Object, ByVal e As EventArgs) Handles dateCal.SelectionChanged
        dateText.Text = dateCal.SelectedDate ' Update text box'
        dateCal.Visible = False              ' Hide calendar'
    End Sub

Protected Sub dateCal_VisibleMonthChanged(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.MonthChangedEventArgs) Handles dateCal.VisibleMonthChanged
        dateCal.Visible = True ' For some reason, changing the month hides the calendar (so show it)'
    End Sub

Protected Sub dateBtn_Click(ByVal sender As Object, ByVal e As EventArgs) Handles dateBtn.Click
        dateCal.Visible = Not dateCal.Visible ' On button press, toggle visibility'
    End Sub

Now you may see that every time when the page is loading, the page_load event is calling and hides the calendar.

You should either set Visible="false" in the ascx file for the calendar. Or call

dateCal.Visible = False 

only when its first loading of the page (!IsPostback property)

so, in C# it will be

protected void Page_Load(object sender, EventArgs args) {
   if (!IsPostback)
      dateCal.Visible = false;
}
Andrey Tagaew
So, postback is the page actually refreshing with a new appearance. Is that correct? How can I code my control to not refresh the page on each calendar interaction, like most date pickers (for example: www.delta.com)?
Steven
Do it client side using Jquery - http://stackoverflow.com/questions/94729/need-a-free-datepicker-for-aspx
Richard Harrison
For this purpose you need to use javascript datapicker instead of server side one. Try to use http://docs.jquery.com/UI/API/1.8/Datepicker. That page contains example and code needed to build it
Andrey Tagaew
+1  A: 

It won't hide when visible because Page_Load runs every time the page is loaded including postbacks (button clicks etc).

So you need to use the IsPostBack property to set the visiblity in Page_load:

if Not Page.IsPostBack then
    dateCal.Visible = False ' Hide calendar on load'
end if

Sometimes getting the initialization right in page_load with IsPostBack can lead to a mass of strange conditions so use it wisely.

I think I'd be inclined to set the property in the ascx file rather than in Page_load.

Richard Harrison