cheching date consisting from 3 drop boxes Using CompareValidator - asp.net

I have 3 drop boxes which correspond to the Day, Month and A Year. After a user chooses a date I concatenate 3 strings and pass it to database.
My problem is how can I validate the date interactively before I pass it to database. To filter out invalid days like June 31 or Feb 30 which do not exist?
I thought about Comparevalidator. what I will do is I create 2 hidden textboxes, populate one with original user input string, and another one with user input string converted to date(if the date is not valid system should convert it to the nearest possible I think).
Than I compare those textBoxes using CompareValidator if they do not match error will be prompt. However somehow it doesn't work. Does anybody have an I idea why. or maybe someone knows less elaborate technique to check the date which is coming from drop boxes?
Will be grateful for any advice or suggestion.
Front end code:
<asp:DropDownList ID="Dates" runat="server" >
<asp:ListItem></asp:ListItem>
<asp:ListItem>01</asp:ListItem>
<asp:ListItem>02</asp:ListItem>
<asp:ListItem>03</asp:ListItem>
.......
<asp:ListItem>29</asp:ListItem>
<asp:ListItem>30</asp:ListItem>
<asp:ListItem>31</asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="Monthes" runat="server" >
<asp:ListItem></asp:ListItem>
<asp:ListItem>January</asp:ListItem>
.......
<asp:ListItem>December</asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="years" runat="server">
<asp:ListItem></asp:ListItem>
</asp:DropDownList>
<asp:TextBox ID="UserInput" runat="server"></asp:TextBox>
<asp:TextBox ID="ConvertedInput" runat="server"></asp:TextBox>
<asp:CompareValidator ID="CompareValidator1" class="errorMess" runat="server"
ControlToCompare="UserInput" ControlToValidate="ConvertedInput"
ErrorMessage="Invalid Date"></asp:CompareValidator>
Back end code:
If Not Page.IsPostBack Then
For count As Integer = 0 To 60
years.Items.Add(CurYear - count)
Next
End If
ConvertedInput.Visible = False
UserInput.Visible = False
.....
Bday = years.Text & "-" & Monthes.Text & "-" & Dates.Text
Dim TempDate As Date = CDate(Bday)
Dim ConvDate As String = TempDate.ToString("yyyy-MM-dd")
UserInput.Text = Bday
ConvertedInput.Text = ConvDate

you could use a customvalidator, build the date and verify it's a valid date. However I would recommend going with a straight textbox and using a UI library like jquery-ui to convert the textbox into a datepicker. you can then pull use DateTime.TryParse() to pull the date out of the textbox in the code behind.
the biggest advantage is only needing to deal with a single input and no string concatination/formatting.

Related

date Compare Validator issue in asp.net

I have a compare validator which validates on two <telerik:RadDatePicker> Start date and End date. The validation rule is simple, Check if Start Date is greater than the End Date and show the error message to the user to correct it
it works as expected but when the start and end dates are the same it is showing the message which is not expected. Code Below:
<asp:CompareValidator ID="dateCompareValidator" runat="server" ControlToValidate="endDate" ControlToCompare="startDate" Operator="GreaterThan" Type="Date" ErrorMessage="Start Date is greater than the End Date - please correct dates."Display="Dynamic"></asp:CompareValidator>
and the date pickers are as follows for both start date and end date:
<telerik:RadDatePicker CssClass="rcCalPopup" ID="endDate" runat="server"
Skin="Vista">
<DateInput ID="DateInput2" runat="server" LabelCssClass="radLabelCss_Vista" Skin="Vista">
</DateInput>
<Calendar ShowRowHeaders="false" ID="Calendar2" runat="server" UseRowHeadersAsSelectors="False" UseColumnHeadersAsSelectors="False"
ViewSelectorText="x" Skin="Vista">
</Calendar>
<DatePopupButton CssClass="rcCalPopup"></DatePopupButton>
</telerik:RadDatePicker>
The rule you have defined with the Validator is:
Enddate must be greater than Startdate (note the missing equal)
The validator Operator property determines the rule for valid input, not invalid input.
So if you want to allow equal dates you have to use GreaterThanEqual
<asp:CompareValidator ID="dateCompareValidator" runat="server"
ControlToValidate="endDate" ControlToCompare="startDate"
Operator="GreaterThanEqual" Type="Date"
ErrorMessage="End date must be equal or greater than start date - please correct dates."Display="Dynamic">
</asp:CompareValidator>
Note that i've also changed the ErrorMessage accordingly. If the input control is empty, no validation functions are called and validation succeeds. Use a RequiredFieldValidator control to require the user to enter data in the input control.

Using a CalendarExtender with a MaskedEditExtender

I'm trying to have a textbox function exactly like the third textbox down on this page: http://www.asp.net/AJAX/AjaxControlToolkit/Samples/MaskedEdit/MaskedEdit.aspx. I'm trying to use a CalendarExtender control with a MaskedEditExtender, because I don't want the user to be able to enter anything except a valid date into the box. On my maskededitextender I have a mask of "99/99/9999" but it seems to only work when the date is actually 8 digits (e.g. 12/12/2000) and not when the date is 7 or 6 digits (e.g. 1/1/2000 or 1/14/2000). The mask screws up when the date is less than 8 digits. Here is my code:
<asp:TextBox runat="server" ID="txtDateAvailable" Width="150px" maxlength="50"></asp:TextBox>
<asp:CalendarExtender ID="calDateAvailable" runat="server" TargetControlID="txtDateAvailable" format="d" PopupPosition="Right"></asp:CalendarExtender>
<asp:MaskedEditExtender ID="mskDateAvailable" runat="server" targetcontrolid="txtDateAvailable" Mask="99/99/9999" clearmaskonlostfocus="false" MaskType="None"></asp:MaskedEditExtender>
If I could figure out how to get the date format of the CalendarExtender to MM/DD/YYYY instead of just M/D/YYYY that would fix it.
There is a Format property of Calendar Control. Use that to set to
Format="MM/dd/yyyy"
The syntax for it is as follows: Format="MM/dd/yyyy" and change it around as you wish, but you must ensure that the month is in uppercase otherwise it will return zeros i used -
<asp:CalendarExtender ID="CalendarExtender1" runat="server" TargetControlID="TextBox1"
PopupButtonID="ImageButton1" Format="dd/MM/yy">

how to disable previous dates in CalendarExtender control through its render event?

Basically, I just want allow select dates greater than today. I'd prefer this way to avoid show alert messages.
I don't think that it is supported in the current version of the Toolkit to restrict selectable dates. This is a simple workaround handling the ClientDateSelectedChanged-Event and validate the selected date:
How to make sure user does not select a date earlier than today or greater than today
There could be instances where you do not want the user to select a day earlier than the current date. For example: when you are providing the user a form to book tickets, you would not like him to choose an earlier date. To achieve this requirement, use the following javascript code.
Prevent the User from selecting a Date Earlier than today
<head runat="server">
<title>Calendar Extender</title>
<script type="text/javascript">
function checkDate(sender,args)
{
if (sender._selectedDate < new Date())
{
alert("You cannot select a day earlier than today!");
sender._selectedDate = new Date();
// set the date back to the current date
sender._textbox.set_Value(sender._selectedDate.format(sender._format))
}
}
</script>
</head>
Call the code:
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<cc1:CalendarExtender ID="CalendarExtender1"
runat="server" OnClientDateSelectionChanged="checkDate" TargetControlID="TextBox1" />
</div>
</form>
Select Date Greater than today
In the javascript, just change this line
sender._selectedDate > new Date()
Note: You may argue that the user can still change the date by typing into the textbox or entering an invalid date. Well that can be easily handled using a ValidationControl and is covered in the next tip.
Add validation to the CalendarExtender Control
A simple way to add validation to the Calendar is to add a ValidationControl to the textbox associated with a CalendarExtender. You have two choices:
Add an Extender to the ValidationControl. To do so, drag and drop a ValidationControl > click on the smart tag of the ValidationControl > choose Add Extender. From the Extender Wizard, choose ValidatorCalloutExtender. Using this approach makes it extremely easy to discover and attach control extenders to your controls. In VS 2005, you had to do this process manually, by wiring up control extenders.
You can choose not to add the Extender.
We will go ahead with option A. We will be adding two ValidationControls to the TextBox. The first, a CompareValidator to check if the user does not enter an invalid date (Eg: May 32) and second, a RangeValidator to keep the date range as desired.
Adding CompareValidator
<asp:CompareValidator ID="CompareValidator1" runat="server"
ControlToValidate="TextBox1" Display="Dynamic" ErrorMessage="Invalid Date"
Operator="DataTypeCheck" Type="Date">
</asp:CompareValidator>
<cc1:ValidatorCalloutExtender ID="CompareValidator1_ValidatorCalloutExtender"
runat="server" Enabled="True" TargetControlID="CompareValidator1">
</cc1:ValidatorCalloutExtender>
Adding RangeValidator – We will restrict the user to select a date range starting from today to 15 days from now.
<asp:RangeValidator ID="RangeValidator1" runat="server"
ControlToValidate="TextBox1" ErrorMessage="RangeValidator"
Type="Date">
</asp:RangeValidator>
<cc1:ValidatorCalloutExtender ID="RangeValidator1_ValidatorCalloutExtender"
runat="server" Enabled="True" TargetControlID="RangeValidator1">
</cc1:ValidatorCalloutExtender>
In the code behind of your page, add this code
C#
protected void Page_Load(object sender, EventArgs e)
{
RangeValidator1.MinimumValue = System.DateTime.Now.ToShortDateString();
RangeValidator1.MaximumValue = System.DateTime.Now.AddDays(15).ToShortDateString();
}
VB.NET
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
RangeValidator1.MinimumValue = System.DateTime.Now.ToShortDateString()
RangeValidator1.MaximumValue = System.DateTime.Now.AddDays(15).ToShortDateString()
End Sub
Well those were some tips associated with the CalendarExtender. As future versions of the toolkit are released, we should be hopeful that there will exist easier ways, of achieving this functionality.
From: http://www.dotnetcurry.com/ShowArticle.aspx?ID=149
Another advanced approach would be to extend the CalendarExtender javascript, but then you have your own custom version of the ajax toolkit.
http://codegoeshere.blogspot.com/2007/06/extending-calendarextender.html
set StartDate property of the calender extender to DateTime.Now.Date in the page load
this will show the previous dates as unselectable

how to change the label text if date displayed in textbox2 is greater than textbox1?

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.

How to modify Bind("MyValue") in asp.net

I'm having headache with Time values and multiple time zones.
I'm storing new DateTime values in UTC time, but I face problem when I try to modify them using LinqDataSource and GridView.
I can easily show correct time in
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# TimeManager.ToLocalTime((DateTime)Eval("OrderDate")) %>' />
</ItemTemplate>
Currently this will add 1 hour to UTC time stored in DB.
However, binding back to source is not easy. Bind("OrderDate") cannot be modified like TimeManager.ToGlobalTime((DateTime)Bind("OrderDate")).
I was thinking of using OnUpdating event of LinqDataSource to update value to global time, but what if user modified other fields and not date field? Every time he updates record time value would be smaller for one hour.
Comparing old and new values also is not great because user can modify date portion of datetime and not time, which is influenced by time zones?
If I had way to show local time in gridview's all states then I could easily use OnUpdating of LinqDataSource.
Please share your thoughts...
Have you considered making the change to your model? Let's assume that the name of the object you are binding to is CustomerOrder. You could add the following class to your project (in the same namespace as your Linq objects):
public partial class CustomerOrder
{
public DateTime LocalOrderDate
{
get { return TimeManager.ToLocalTime(OrderDate); }
set { OrderDate = TimeManager.ToUTCTime(value); }
}
}
Now instead of binding to OrderDate, bind to LocalOrderDate. This will automatically make the UTC / Local Time conversion to the OrderDate.
(Note: I'm assuming you have TimeManager.ToLocalTime() and TimeManager. ToUTCTime() properly defined)
The way I've handled this sort of thing in the past is to use Eval in the EditItemTemplate as well. Let the user edit the item in local time. Then add OnItemUpdating handler for the gridview and add extract the value of the associated text box, convert it to global time, and add that to the new values dictionary. Bind the original value in (in global time) to a hidden field in the same template, which will populate the old values dictionary with the correct old time. You'll want to do the same thing on insertion in OnItemInserting although you obviously don't need the old value (since there isn't one).
EDIT: Usually I do my updates on a DetailsView not a GridView, thus the ItemUpdating/Inserting instead of RowUpdating/Inserting. Sample code below -- this example uses a pair of dropdown lists that allows the user to specific a location (choose a building and a location in the building, but it actually only maps the location in the database). On the back end it assigns initial values to the dropdowns in OnPreRender (not shown) and extracts the LocationID database field value from the location dropdown on ItemUpdating/Inserting (updating shown). The DetailsView is wrapped in an UpdatePanel and the population of the Location dropdown is done when the building dropdown selection changes. Note that since I'm updating the item (causing an update statement anyway) I don't care if the LocationID field gets overwritten on the update with the same value so I don't bother to keep the old value on the page.
<asp:TemplateField HeaderText="Location:" SortExpression="LocationId">
<EditItemTemplate>
<asp:DropDownList runat="server" ID="buildingDropDownList"
DataSourceID="buildingDataSource"
DataTextField="name"
DataValueField="abbreviation"
OnSelectedIndexChanged=
"buildingDropDownList_SelectedIndexChanged"
AutoPostBack="true" />
<asp:DropDownList runat="server" ID="locationDropDownList"
DataSourceID="locationsDataSource"
DataTextField="Name"
DataValueField="ID">
</asp:DropDownList>
</EditItemTemplate>
<InsertItemTemplate>
<asp:DropDownList runat="server" ID="buildingDropDownList"
DataSourceID="buildingDataSource"
DataTextField="name"
DataValueField="abbreviation"
OnSelectedIndexChanged=
"buildingDropDownList_SelectedIndexChanged"
AutoPostBack="true"
AppendDataBoundItems="true">
<asp:ListItem Text="Select Building" Value="" />
</asp:DropDownList>
<asp:DropDownList runat="server" ID="locationDropDownList"
DataSourceID="locationsDataSource"
DataTextField="Name"
DataValueField="ID"
AppendDataBoundItems="true">
<asp:ListItem Text="Not installed" Value="" />
</asp:DropDownList>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="locationLabel" runat="server"\
Text='<%# Eval("LocationID") == null
? ""
: Eval("Location.Name") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
Codebehind:
void editPrinterDetailsView_ItemUpdating( object sender,
DetailsViewUpdateEventArgs e )
{
// Use a helper method to find the dropdown inside the details view
// and get the selected value.
string locationID = ControlHelper
.GetDropDownValue( editPrinterDetailsView,
"locationDropDownList" );
if (locationID == string.Empty)
{
locationID = null;
}
if (e.NewValues.Contains( "LocationID" ))
{
e.NewValues["LocationID"] = locationID;
}
else
{
e.NewValues.Add( "LocationID", locationID );
}
e.OldValues["LocationID"] = -1;
}

Resources