Scenario: I am trying to insert a team (composed by multiple persons) on a single page. I have a web user control to insert each person, and when a team has multiple persons several Web User Controls are displayed at the same time.
Each user has a ValidationSummary and several validators (All grouped to the same validation group, example person1 web user control has the validation group on de Validation summary and on each validator set to "valGroup_Person1").
The problem is when validation occurs all errors are grouped and displayed in all web user controls making each web user control display a very long error list. The expected was individual error lists.
Is there a way to get ValidationSummary to perform this way?
If you are using asp.net 2.0 then you must use validation group this will work.
See the below example it will work
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
ControlToValidate="TextBox1" ErrorMessage="RequiredFieldValidator"
ValidationGroup="1">1</asp:RequiredFieldValidator>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server"
ControlToValidate="TextBox2" ErrorMessage="RequiredFieldValidator2"
ValidationGroup="2">2</asp:RequiredFieldValidator>
<asp:ValidationSummary ID="ValidationSummary1" runat="server"
ValidationGroup="1" />
<asp:ValidationSummary ID="ValidationSummary2" runat="server"
ValidationGroup="2" />
<asp:Button ID="Button1" runat="server" Text="Button" ValidationGroup="1" />
<asp:Button ID="Button2" runat="server" Text="Button" ValidationGroup="2" />
You have to disambiguate the validation groups from each other by giving them separate names on each of the controls. For example, in the user control's page-init:
Private Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
Dim uniqueGroupName = Guid.NewGuid.ToString
valSummary.ValidationGroup = uniqueGroupName
txtFirstName.ValidationGroup = uniqueGroupName
txtLastName.ValidationGroup = uniqueGroupName
btnFind.ValidationGroup = uniqueGroupName
End Sub
(for each control in the group, programmatically give it a validation group)
If you are doing server-side validation, you should call validation for just the group, e.g.
Page.Validate(valSummary.ValidationGroup)
If Not Page.IsValid then Exit Sub
...
Related
I'm retrofitting an older web forms site with Model Binding using asp.net 4.5.
In a DetailsView I have a drop down list that allows selection of a particular 'client' and another that allows selection of a particular 'project' that belongs to that client. So the drop down for project has to be filtered on the client number and if the user changes the client selection, I want to filter the project list by client number.
I couldn't figure out how to get the SelectedIndexChanged method on the client ddl to fire the Select method for the Project, so I concluded the only way to do it was to filter the project ddl by client number in all cases. I am getting an error message when the client selection is made:
NullReferenceException was Unhandled by User Code
which point in my aspx directly to the ddl for Projects.
This is an abbreviated version of the details view, you can see both the clients ddl and the projects ddl (I am operating in Edit mode):
<asp:DetailsView ID="AdministratorDetailsView" runat="server" AutoGenerateRows="False"
DataKeyNames="AdministratorNumber" ItemType="BusinessLogic.Administrator"
Width="99%"
SelectMethod="AdministratorDetailsView_GetItem"
UpdateMethod="AdministratorDetailsView_UpdateItem"
DeleteMethod="AdministratorDetailsView_DeleteItem"
FieldHeaderStyle-Width="30%" EditRowStyle-Width="99%"
InsertRowStyle-Width="70%" RowStyle-Width="99%" CssClass="admin"
AutoGenerateDeleteButton="true" AutoGenerateEditButton="true" >
<Fields>
<asp:TemplateField HeaderText="AdministratorCode" SortExpression="AdministratorCode">
<EditItemTemplate>
<asp:Label ID="AdministratorCode" Text="<%# Item.AdministratorCode%>" runat="server" />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="AdministratorCode" Text="<%# Item.AdministratorCode%>" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ClientNumber" SortExpression="ClientNumber">
<EditItemTemplate>
<asp:DropDownList ID="ddClients" runat="server"
AutoPostBack="true"
DataTextField="ClientName" DataValueField="ClientNumber"
ItemType="BusinessLogic.Client"
SelectMethod="ddClients_GetList"
SelectedValue="<%# Item.ClientNumber%>"
OnSelectedIndexChanged="AdministratorDetailsView_ddlClients_SelectedIndexChanged"/>
</EditItemTemplate>
<ItemTemplate>
<asp:DropDownList ID="ddClients" runat="server" Enabled="false"
DataTextField="ClientName" DataValueField="ClientNumber"
ItemType="BusinessLogic.Client"
SelectMethod="ddClients_GetList"
SelectedValue="<%# Item.ClientNumber%>"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Projects" >
<EditItemTemplate>
<asp:DropDownList ID="ddProjects" runat="server" AutoPostBack="true"
DataTextField="ProjectName" DataValueField="ProjectNumber"
ItemType="BusinessLogic.Project"
SelectMethod="ddProjects_GetList"
SelectedValue="<%# Item.ProjectNumber%>" />
</EditItemTemplate>
<ItemTemplate>
<asp:DropDownList ID="ddProjects" runat="server" Enabled="false"
DataTextField="ProjectName" DataValueField="ProjectNumber"
ItemType="BusinessLogic.Project"
SelectMethod="ddProjects_GetList"
SelectedValue="<%# Item.ProjectNumber%>"/>
</ItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>
There are two SelectMethods, one for each drop down list, and a selectedindexchaneged method for clients:
Public Function ddClients_GetList() As List(Of BusinessLogic.Client)
Dim special As New List(Of Client)
special = CurrentClient.ClientList() 'add whole list
Dim NullClient As New Client()
NullClient.Load(0)
NullClient.ClientName = "<-Not Selected-->"
special.Add(NullClient) 'Had to have a client with 0 in the list since most admins don't have anything but 0 inthis field
Return special
End Function
Public Function ddProjects_GetList(<Control("ddClients")> ByVal ClientNumber As Integer) As List(Of BusinessLogic.Project)
Dim special As New List(Of Project)
If ClientNumber = 0 Then
special = CurrentProject.ProjectList() 'add whole list, refine it if Clients Drop Down selected
Else
special = CurrentProject.ProjectList(ClientNumber) 'add whole list, refine it if Clients Drop Down selected
End If
Dim NullProject As New Project()
NullProject.Load(0)
NullProject.ProjectName = "<-Not Selected-->"
special.Add(NullProject) 'Had to have a Project with 0 in the list since most admins don't have anything but 0 inthis field
Return special
End Function
Protected Sub AdministratorDetailsView_ddlClients_SelectedIndexChanged(sender As Object, e As EventArgs)
Dim ddlProj As DropDownList
ddlProj = AdministratorDetailsView.FindControl("ddProjects")
ddlProj.ItemType = "BusinessLogic.Project"
ddlProj.DataBind()
End Sub
All is well until the user selects a different client which triggers the SelectIndexChanged event and then we get to the DataBind(), where we get the null exception (ddlProj is found).
Need some ideas on how to refresh the projects list based on the new client selection.
How do I force ddProjects to run its SelectMethod again, to avoid the null reference and reload the control?
Turns out this issue is not unique to ModelBinding, but is a General WebForms Issue.
You cannot have cascading dropdowns within another data control where they depend on each other unless you add a bit of code.
In my case, I was trying to bind both dropdowns to the underlying detailsview, and at the same time setting the selected values. Doesn't work because of timing. It seems right until you try to change the selection on the parent dropdown, and then you get null exception on the second because it is not yet loaded. It's all timing. If you try to work around it with saved values, it gets too messy.
My solution is, Bind another item to the underlying details view (you can make it hidden if you wish). Then add some code to keep it in sync with the actual value. DO NOT Bind SelectedValue on the secondary drop down , this is what causes the problem. Manage Selected Value in code using the added field.
<asp:DetailsView ID="AdministratorDetailsView" runat="server" AutoGenerateRows="False"
DataKeyNames="AdministratorNumber" ItemType="BusinessLogic.Administrator"
Width="99%" SelectMethod="AdministratorDetailsView_GetItem" UpdateMethod="AdministratorDetailsView_UpdateItem" DeleteMethod="AdministratorDetailsView_DeleteItem"
FieldHeaderStyle-Width="30%" EditRowStyle-Width="99%" InsertRowStyle-Width="70%" RowStyle-Width="99%" CssClass="admin" AutoGenerateDeleteButton="true" AutoGenerateEditButton="true"
>
<Fields>
<asp:TemplateField HeaderText="Client Name" SortExpression="ClientName">
<EditItemTemplate><asp:DropDownList ID="ddClients" runat="server" AutoPostBack="true" DataTextField="ClientName" DataValueField="ClientNumber" ItemType="BusinessLogic.Client" SelectMethod="ddClients_GetList" SelectedValue="<%# Item.ClientNumber%>" OnDataBound="ddClients_DataBound" OnSelectedIndexChanged="AdministratorDetailsView_ddlClients_SelectedIndexChanged" /> </EditItemTemplate>
<ItemTemplate><asp:DropDownList ID="ddClients" runat="server" Enabled="false" DataTextField="ClientName" DataValueField="ClientNumber" ItemType="BusinessLogic.Client" SelectMethod="ddClients_GetList" SelectedValue="<%# Item.ClientNumber%>"/></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Project Number" >
<EditItemTemplate><asp:Label ID="ProjectNumberLabel" runat="server" Text="<%# BindItem.ProjectNumber%>"></asp:Label></EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Project Name" SortExpression="ProjectNumber">
<EditItemTemplate><asp:DropDownList ID="ddProjects" runat="server" AutoPostBack="true" DataTextField="ProjectName" DataValueField="ProjectNumber" ItemType="BusinessLogic.Project" SelectMethod="ddProjects_GetList" OnDataBound="ddProjects_DataBound" OnSelectedIndexChanged="ddProjects_SelectedIndexChanged" />
</EditItemTemplate>
<ItemTemplate><asp:DropDownList ID="ddProjects" runat="server" Enabled="false" DataTextField="ProjectName" DataValueField="ProjectNumber" ItemType="BusinessLogic.Project" SelectMethod="ddProjects_GetList" SelectedValue="<%# Item.ProjectNumber%>" />
</ItemTemplate>
</asp:TemplateField>
</asp:DetailsView>
And in the code behind, not how we set and get the value of the bound projectnumber:
Protected Sub AdministratorDetailsView_ddlClients_SelectedIndexChanged(sender As Object, e As EventArgs)
''If this selection changes we need to change some flags and perhaps theProject ddl
''This causes null exception for Project ddl, can't figure out how to get it to reload. Tried DataBind(), same effect as having a ValueProvider in the parameters to the Select
Dim ProjectNumberLabel As Label = AdministratorDetailsView.FindControl("ProjectNumberLabel")
ProjectNumberLabel.Text = "0" 'Synchronize to no selection
Dim ddProjects As New DropDownList
ddProjects = AdministratorDetailsView.FindControl("ddProjects") 'Have to use Find Control because ddl is buried in DetailsView
ddProjects.SelectedValue = 0 'Cause it to read Select an Item
ddProjects.DataBind() 'Rebinding it causes the SelectMethod to run.
End Sub
Protected Sub ddProjects_DataBound(sender As Object, e As EventArgs)
'Because of the problem with cascading references, we had to remove the SelectValue declaration from ddProjects.
'So we must make sure that once theddProjects is databound, it points to the selected value from the data
Dim ddlProjects As DropDownList
ddlProjects = AdministratorDetailsView.FindControl("ddProjects")
Dim ProjectNumberLabel As Label = AdministratorDetailsView.FindControl("ProjectNumberLabel")
ddlProjects.SelectedValue = CInt(ProjectNumberLabel.Text)
End Sub
Hope someone else sees this as useful. I couldn't find it anywhere.
Great posting, as I faced a similar conundrum and it made me think. I have done this before outside of the model-binding approach, and the solution is essentially the same, as described. I used a ListView, and added the method:
OnItemDataBound="lvWhatever_ItemDataBound"
to fire an event from which to go and get the relevant ID from another bound control in the list view data item:
if (e.Item.ItemType == ListViewItemType.DataItem)
{
// get the ID from from another control in this item record: lblItemID
ListViewDataItem lvdi = (ListViewDataItem)e.Item;
if (lvdi != null)
{
Label iID = (Label)lvdi.FindControl("lblItemID");
if (iID != null)
where lblItemID.Text contains the relevant ID. Then from that I can query to get the relevant list, and manually bind it to the DDL. Brilliant - thanks very much.
I Got a text box with a Regular Expression validator, to validate if my textbox is numeric.
here's the code :
<asp:TextBox ID="txtAmount" runat="server" CssClass="TextBoxCls"></asp:TextBox>
<asp:RegularExpressionValidator runat="server" ID="valNumbersOnly" ControlToValidate="txtAmount"
SetFocusOnError="true" Display="Dynamic" ErrorMessage="Please enter a numbers only in text box."
Font-Bold="true" ForeColor="Red" ValidationExpression="(^([0-9 ]*|\d*\d{1}?\d*)$)">
</asp:RegularExpressionValidator>
and , if the user accidentally input the wrong data , it'll show the Error Like This :
and i give the user, a clear function to clear all the textbox : with kind of this function :
Public Sub ClearTextBox(ByVal root As Control)
For Each ctrl As Control In root.Controls
ClearTextBox(ctrl)
If TypeOf ctrl Is TextBox Then
CType(ctrl, TextBox).Text = String.Empty
End If
Next ctrl
End Sub
Protected Sub btnClr_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnClr.Click
ClearTextBox(Me)
dropResponse.SelectedIndex = 0
FillData()
End Sub
but , the amount is not cleared, it still show the error. why it still happen?
If you are providing this through another button on the same form it won't ever hit the code-behind.
If you want a button on a validated form that needs to fire regardless of whether the other controls have validated, put it in a separate validation group:
<asp:Button runat="server" ID="btnClr" Text="Clear form" OnClick="btnClr_Click" ValidationGroup="unvalidatedControls" />
Alternatively, put a validation group on your controls that need validating and also the button that submits the form:
<asp:TextBox ID="txtAmount" runat="server" CssClass="TextBoxCls" ValidationGroup="validatedControls"></asp:TextBox>
<asp:RegularExpressionValidator runat="server" ID="valNumbersOnly" ControlToValidate="txtAmount"
SetFocusOnError="true" Display="Dynamic" ErrorMessage="Please enter a numbers only in text box."
Font-Bold="true" ForeColor="Red" ValidationExpression="(^([0-9 ]*|\d*\d{1}?\d*)$)"
ValidationGroup="validatedControls">
</asp:RegularExpressionValidator>
<asp:Button runat="server" ID="btnSubmit" Text="Submit Form" ValidationGroup="validatedControls" />
You could put a ValidationGroup attribute on both your clear button and the main form, as long as they're different, the clear button will work just fine.
Some documentation on Validation Groups: http://msdn.microsoft.com/en-us/library/ms227424.aspx
I suspect that the textbox is contained in a panel or another container control. Only the toplevel controls of a page are available in the controls collection of the page.
I would suggest to change the parameter of the call to ClearTextBox with the correct container control.
I need help in VB (no C# or Javascript, please -- I'm clueless with those languages)
I have also checked all the "questions that may already have your answer -- and those that were in VB didn't match my situation or were resolved by using AutoPostback,coding a textChanged event, or adding ontextchanged= to the textbox field --- I have all of these in my code already.
I can't seem to get the TextChanged event to fire despite setting the AutoPostBack to true.
Even after creating at submit button it still won't fire, what have I left out?
What I'm trying to accomplish:
I want the Finish Date to set to a date 30 days after the Start Date if and only if the user edits a start date.
Otherwise just display in the Finish Date whatever would have originally displayed there.
Both dates are allowed to be null in the database and both are defined as datetime.
In Default.aspx
<asp:FormView ID="FormView1" runat="server" DataKeyNames="MASTERID_Action"
DataSourceID="srcAction">
<EditItemTemplate>
MASTERID_Action:
<asp:Label ID="MASTERID_ActionLabel1" runat="server"
Text='<%# Eval("MASTERID_Action") %>' />
<br />
Action_StartDate:
<asp:TextBox ID="Action_StartDateTextBox" runat="server"
Text='<%# Bind("Action_StartDate") %>'
ontextchanged="Action_StartDateTextBox_TextChanged" AutoPostBack="True" /> <rjs:PopCalendar ID="StartDateCal" runat="server" Control="Action_STartDateTextBox" />
<br />
Action_FinishDate:
<asp:TextBox ID="Action_FinishDateTextBox" runat="server"
Text='<%# Eval("Action_FinishDate") %>' />
<br />
<asp:Button ID="SubmitButton1" runat="server" Text="Refresh"
onclick="SubmitButton1_Click" />
<asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True"
CommandName="Update" Text="Update" />
<asp:LinkButton ID="UpdateCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel" Text="Cancel" />
</EditItemTemplate>
In Default.aspx.vb
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Action_StartDateTextBox_TextChanged(sender As Object, e As System.EventArgs)
Dim txtStartDate As TextBox = Me.FormView1.FindControl("Action_StartDateTextBox")
Dim txtFinishDate As TextBox = Me.FormView1.FindControl("Action_finishdatetextbox")
Dim strNewFinishDate As String
If txtFinishDate.Text = "" And txtStartDate.Text <> "" Then
strNewFinishDate = Convert.ToString(Convert.ToDateTime(txtStartDate).AddDays(30))
ElseIf txtFinishDate.Text <> "" Then
strNewFinishDate = txtFinishDate.Text
Else
strNewFinishDate = ""
End If
txtFinishDate.Text = strNewFinishDate
End Sub
Protected Sub SubmitButton1_Click(sender As Object, e As System.EventArgs)
Dim mytest As String
End Sub
End Class
16/01/2013 edit: had a typo in Protected Sub Action_StartDateTextBox_TextChanged ran the page but it still doesn't fire. Still need help with this, please.
17/01/2013 edit: My question is still unanswered, the response I did receive caused more errors. Please help.
I think you might have been deleted your controls after writing its corresponding events.If so, as a result it will remove all the handlers that you had specified with the events.
'---This is your code, by the way it seems to be missing its handler
... Action_StartDateTextBox_TextChanged(sender As Object, e As System.EventArgs)
try to add its handler like this,
'---Adding hanler
... Action_StartDateTextBox_TextChanged(sender As Object, e As System.EventArgs) Handles Action_StartDateTextBox.TextChanged
If you need more details regarding Event Handler, Just refer this.
No response on this, but I have to keep moving. So, I have chosen what is probably the smarter route -- to take care of my postbacks as client-side javascript. I would have accepted an answer of "asp.net can't do this. Javascript would make your life so much easier" for this issue....
We are working with an ASP.Net DetailsView with a VB.Net code-behind file. We are trying to allow the user to edit and save changes in the DetailsView by allowing the user to click the Edit button and then click the Update button.
Nothing happens when the user clicks the Edit button so we added an OnClick handler for the Edit button. The DetailsView will go into edit mode but only if the user clicks the Edit button twice. (Maybe an ASP.Net bug?)
Once the DetailsView is in Edit mode the Update and Cancel buttons are displayed as expected but nothing happens when the user clicks either of those buttons. We placed an OnClick on the Update button in an attempt to force the DetailsView to Update but the only choices for .ChangeMode(DetailsViewMode. are Edit, Insert, ReadOnly.
I also thought DetailsViews did not need additional OnClicks unless we needed to perform special handling.
Here is the markup for the DetailsView:
<asp:DetailsView
ID="DetailsView"
runat="server"
Height="50px"
Width="218px" AutoGenerateRows="False">
<Fields>
<asp:TemplateField ShowHeader="False">
<EditItemTemplate>
<asp:Button ID="ButtonUpdate" runat="server" CausesValidation="True"
CommandName="Update" Text="Update" OnClick="ButtonUpdate_Click" />
<asp:Button ID="ButtonCancelUpdate" runat="server" CausesValidation="False"
CommandName="Cancel" Text="Cancel" />
</EditItemTemplate>
<ItemTemplate>
<asp:Button ID="ButtonEdit" runat="server" CausesValidation="False"
CommandName="Edit" Text="Edit" OnClick="ButtonEdit_Click"/>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Forename" HeaderText="First Name:" />
</Fields>
</asp:DetailsView>
Here is the coding in the code-behind file:
Public Class StudentDetailsMaintenance
Inherits System.Web.UI.Page
Dim theTableAdapter As New DataSetSingleStudentTableAdapters.StudentsMaintenanceTableAdapter
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' Load the data from the database into the DetailsView.
'------------------------------------------------------
DetailsView.DataSource = theTableAdapter.GetDataByStudentID(StudentMaintenance.IntStudentID)
DetailsView.DataBind()
End Sub
Protected Sub ButtonEdit_Click(sender As Object, e As EventArgs)
' Place the DetailsView into Edit mode.
'--------------------------------------
DetailsView.ChangeMode(DetailsViewMode.Edit)
End Sub
Protected Sub ButtonUpdate_Click(sender As Object, e As EventArgs)
' Place the DetailsView into Update mode.
'----------------------------------------
DetailsView.ChangeMode(DetailsViewMode.)
End Sub
End Class
The ButtonUpdate_Click routine is incomplete because we don't know how to get the DetailsView to do the update.
Addional Note:
This is the first time we are trying to do a DetailsView by not setting up a DataSource in the markup. Instead of doing that we are using the data from a DataSet TableAdapter created in the DataSet designer.
If we did the DetailsView along with the DataSource all in the markup then the Edit and Update buttons work without any problem. We were also doing this in an attempt to eliminate extra coding if possible.
If you want the DetailsView's automatic behaviour for Edit, you need to use a CommandField to show the Edit button:
<asp:DetailsView id="dvDetailsView" runat="server" DataSourceId="sqlDS" DataKeyNames="primaryKey">
<Fields>
<asp:CommandField ButtonType="Button" ShowEditButton="true" />
</Fields>
</asp:DetailsView>
As noted above you need to include the DataKeyNames property to specify the primary key for the datasource so that ASP.NET knows which record in the data source to update. Also as mentioned above, you need to make sure that the Bind("columnName") statements use the same field names as used in your data store.
Also, make sure that you provide an UpdateCommand in your SqlDataProvider (or equivalent for your data store) so that the update can take place.
Now when you place the DetailsView into Edit mode, the Update and Cancel buttons will automatically be displayed where the is. If you need to do some work with the data before the data is updated in the data store, then handle the DetailView's ItemUpdating event in the code behind.
Well, looking real briefly, try wrapping your Page_Load databind in an If Not Page.IsPostback.
Postback wreaks havoc on databound controls.
I have textbox in my asp.net 3.5 VB.net webform
in my textbox1 the text is : 30-Dec-2010, 06:00:00 PM
i want when the date in textbox is greater than textbox1 then the Label text would be "No REfund ! Sorry"
How to do this
You should use ASP.Net CompareValidator for this purpose. You can check both on client- and serverside. Besides i would recommend not to have Date AND Time in one Textbox. That makes it more difficult to validate and it's not standard, so it might be confusing and error-phrone for users.
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:CompareValidator ID="CompareValidator1" runat="server" ControlToCompare="TextBox1" ControlToValidate="TextBox2" Type="Date" Operator="GreaterThan" runat="server" ErrorMessage="No REfund ! Sorry" EnableClientScript="true" ></asp:CompareValidator>
<asp:Button ID="BtnPostback" runat="server" Text="postback" />
On the serverside you should also trigger the validation(f.e. if javascript is disabled):
Private Sub BtnPostback_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles BtnPostback.Click
Page.Validate()
If Me.IsValid Then
'Do something f.e. save'
End If
End Sub
CompareValidator Class
It would be better if you do it using javascript because this functionality does not require postback. A similar question has been posted on stackoverflow which compares two dates using javascript. Check it out here. You just need to extend it to incorporate assigning text to the label.