[英]How do I make the closest future date to today's date the default dropdownlist value?
我們使用數據庫中的多個事件日期動態填充下拉列表。
目前,所有小於今天日期的日期都被禁用,我們的用戶無法查看。
大於今天日期的下一個可用日期將成為默認的下拉列表值,並且所有將來的日期都將可用並在下拉列表中可見。
例如,如果我們在日期數據庫中有以下日期:
2013年2月12日
12/20/203
2014年5月21日
2014年8月8日
2014年10月22日
由於其中三個日期( 2/12 / 2013,12 / 20 / 203,5 / 21/2014 )小於今天的日期,因此這些日期被禁用並且不可見。
大於當前日期的最接近可用日期是2014年8月8日,這成為默認的下拉列表值。
最終,所有將來的日期(如2014年10月22日)也都可以在下拉列表中找到。
這是實現此目的的代碼片段:
//標記
<asp:DropDownList id="txtEventDate" runat="server">
</asp:DropDownList>
//動態填充下拉列表的代碼
Dim cmd As New SqlCommand("Select convert(datetime, dates, 103) dates, CONVERT(VARCHAR(12), dates, 107) as datelist from events", New SqlConnection(ConfigurationManager.ConnectionStrings("Events").ConnectionString))
cmd.Connection.Open()
Dim ddlValues As SqlDataReader
ddlValues = cmd.ExecuteReader()
txtEventDate.DataSource = ddlValues
txtEventDate.DataValueField = "dates"
txtEventDate.DataTextField = "datelist"
txtEventDate.DataBind()
cmd.Connection.Close()
cmd.Connection.Dispose()
//僅顯示未來日期和下一個可用未來日期作為默認下拉列表值的代碼
For Each items As ListItem In txtEventDate.Items
If (DateTime.Parse(items.Value).CompareTo(DateTime.Today)) < 0 Then
items.Enabled = False
End If
Next
我們的用戶希望更改流程,以便允許他們回到較早的日期並根據需要進行一些更改。
任何想法如何解決這個問題?
Public Sub PopulateDates()
Dim cmd As New SqlCommand("Select convert(datetime, dates, 103) dates, CONVERT(VARCHAR(12), dates, 107) as datelist from events", New SqlConnection(ConfigurationManager.ConnectionStrings("events").ConnectionString))
cmd.Connection.Open()
Dim lstDates As New List(Of DateTime)()
Using rdr As SqlDataReader = cmd.ExecuteReader()
If rdr.Read() Then
lstDates.Add(DirectCast(rdr("dates"), DateTime))
End If
End Using
lstDates = lstDates.OrderBy(Function(x) x.[Date]).ToList()
Dim nearestDate = lstDates.OrderBy(Function(t) Math.Abs((t - DateTime.Now).Ticks)).First()
txtEventDate.DataSource = lstDates
txtEventDate.DataBind()
txtEventDate.SelectedIndex = txtEventDate.Items.IndexOf(txtEventDate.Items.FindByValue(nearestDate.ToString()))
cmd.Connection.Close()
cmd.Connection.Dispose()
End Sub
根據您的評論,似乎要讓用戶更改較早的日期。 因此,刪除您的For Each
可以禁用較早的日期。
首先,您需要找到最接近或等於當前日期的日期,如下所示
Dim nearestDate = ddlValues.OrderBy(Function(t) Math.Abs((t.dates - DateTime.Now).Ticks)).First()
然后,在執行數據綁定后,請使用FindByValue
或FindByText
保留最近的默認日期
txtEventDate.SelectedIndex = txtEventDate.Items.IndexOf(txtEventDate.Items.FindByValue(nearestDate.ToString()))
注意:始終嘗試對dbConnection對象(例如SqlConnection
, SqlCommad
等)使用using
語句,以便在使用后釋放這些對象使用的資源。
更新1:根據您在評論中報告的內容,我對日期格式(這不是您最初的問題的一部分)等進行了一些更改,這是PopulateDates()
的完整代碼。 另外,請確保您沒有運行foreach
因為之前設置的日期可能會設置錯誤的值,因此您不得不設置最近的日期。 如果輸入錯誤的值,則最好放置斷點,並查看哪個對象返回意外數據。
Public Sub PopulateDates()
Dim cmd As New SqlCommand("Select dates from events", New SqlConnection(ConfigurationManager.ConnectionStrings("events").ConnectionString))
cmd.Connection.Open()
Dim lstDates As New List(Of DateTime)()
Using rdr As SqlDataReader = cmd.ExecuteReader()
If rdr.Read() Then
lstDates.Add(DirectCast(rdr("dates"), DateTime))
End If
End Using
Dim stDates As List(Of [String]) = lstDates.OrderBy(Function(o) o.[Date]).[Select](Function(x) x.[Date].ToString("MMM dd, yyyy")).ToList()
Dim nearestDate = lstDates.OrderBy(Function(t) Math.Abs((t - DateTime.Now).Ticks)).First()
// Dim nearestDate = lstDates.First(Function(x) x >= DateTime.Now.[Date]) // this does the trick too
txtEventDate.DataSource = stDates
txtEventDate.DataBind()
txtEventDate.SelectedIndex = txtEventDate.Items.IndexOf(txtEventDate.Items.FindByValue(nearestDate.ToString("MMM dd, yyyy")))
cmd.Connection.Close()
cmd.Connection.Dispose()
End Sub
這是指向DEMO的鏈接(不幸的是,它位於C#中),以顯示其如何返回正確的數據。
更新2:這是您完整的工作版本(希望它可以工作)。 我在本地嘗試了此操作,以從數據庫加載數據並通過DataReader
檢索,一切都按照您想要的方式工作。
您在評論中報告說從DataReader訪問時僅返回了一個項目,這是因為您的原始代碼具有If rdr.Read() Then
它將在第一條記錄后退出,但是我們需要使用while
來迭代完整列表。
關於具有不同日期格式的下拉列表的“ Value
字段和“ Text
”,我創建了一個Dictionary
集合來實現此目的。 這是您的PopulateDates()
完整代碼。
Public Sub PopulateDates()
Dim cmd As New SqlCommand("Select dates from events order by dates", New SqlConnection(ConfigurationManager.ConnectionStrings("events").ConnectionString))
cmd.Connection.Open()
Dim list As New Dictionary(Of String, DateTime)()
Using rdr As SqlDataReader = cmd.ExecuteReader()
Dim dt As DateTime
While rdr.Read()
dt = DateTime.Parse(rdr("dates").ToString())
list.Add(dt.ToString("MM/dd/yyyy"), dt)
End While
End Using
txtEventDate.DataSource = list
txtEventDate.DataTextField = "Value"
txtEventDate.DataValueField = "key"
txtEventDate.DataTextFormatString = "{0:MMM dd, yyyy}"
txtEventDate.DataBind()
Dim nearestDate = list.First(Function(x) x.Value >= DateTime.Now.[Date]).Key
txtEventDate.SelectedIndex = txtEventDate.Items.IndexOf(txtEventDate.Items.FindByValue(nearestDate.ToString()))
cmd.Connection.Close()
cmd.Connection.Dispose()
End Sub
HTML標記看起來像您想要的格式。
完全未經測試,但是您想要做什么? 您的項目列表(如果尚未排序)將需要進行排序,但這應該找到今天或以后的第一個項目,並將其設置為下拉列表中的選定項目。
更新 -請改用SelectedValue
!
For Each items As ListItem In txtEventDate.Items
If (DateTime.Parse(items.Value).CompareTo(DateTime.Today)) >= 0 Then
txtEventDate.SelectedValue = items.Value
Exit For
End If
Next
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.