Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Date validation and Controls

Status
Not open for further replies.

GiacoF

Programmer
May 15, 2024
9
IT
I recently started programming in foxpro and I'm now trying my hand at dates...
So I'm looking for an effective validation method for the date entered in this field, in the sense that based on what the user types, if it's not valid or it's not a date, he is warned.
Basically I'm having difficulty because in the beginning this field is of character type... I don't want to do complex checks and validations on the character, but on the dates. I would like to treat this field as a date and then:
- Check if empty (with "C" I couldn't because it detected "/");
- Check if the date is valid (for example 02/30/2022 would not be valid;
- Check the input, if the user writes various written numbers... example in photo...

Cattura_lewnko.png


I set the inputMask and Format properties to 99/99/9999 and "D". I tried to write the valid() of the field, but I still haven't succeeded..could someone help me to understand how to do it usually?
 
Just set the value to a date or set the controlsource to a field or variable or preropty that is a date, and users can only enter valid dates.

Besides, using an ActiveX calendar control for picking dates (or developing a calendar picker with a grid, for example) is a userinterface commonly used, too.

Chriss
 
I agree with Chris. There is no need for anything complicated. Just give the date control an initial date value. You can do that, for example, in its Init:

THIS.Value = DATE()

That will give it an initial value of today's date, which the user can then edit.

Alternatively, you can bind the control to a date field in a table. You do that by setting its ControlSource to point to a date field.

Either way, once you have done the above, the user will only be able to enter a valid date. There is no need for you to do any specific validation. What's more, the date will respect the format (if any) that you have specified with SET DATE (and related settings such as SET CENTURY and SET MARK).

Chris also mentioned an ActiveX calendar control. That would be an excellent approach, but it really comes under the heading of advanced features. Given that you are just starting out with VFP, I would put that to one side for the time being.

I hope this helps. Welcome to the forum - and to VFP.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thanks for all the support!!

I understood the way on how to give these fields the "Date" type so it's what I've done.
Now the input is better, however I'm wondering if I could optimize and improve, such as...

- If the date is invalid (so Fox throw me the error "Invalid Date"), I would like to show a personal message;
- Similar to this textbox,how can i check in any case if it's empty or not... Tried before EMPTY() but it returned always .f. as it detected " / / ".

Hope I explain well.. and thanks in advance for any add support :)

 
You can't apply your own validation, or display a message, if the user enters an invalid date into a control with a date data type. This is because, when an invalid date is entered, the control does not lose focus, so neither the Valid nor the LostFocus will fire. The user is forced to either correct the error or cancel the edit.

(That said, the Help lists error 2034 as "Invalid date", but it is not clear how or when that arises.)

If you want to do your own validation, you can do it by making the textbox a character string rather than a date data type (for example, by putting [tt]THIS.Value = ""[/tt] in its Init). You can then do something like this:

Code:
lcEntered = THIS.Value
ldDate = CTOD(lcEntered)
IF EMPTY(ldDate)
  * An invalid date was entered; do your message here
ELSE
  * The date was OK
ENDIF

You might put this code in the textbox's Valid, and return .F. if the test fails.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Empty() will return .T. for the empty date, if you test the textbox.value, so what did you check?

If you checked the textbox value with EMPTY(), you didn't set the textbox to a date type, but a string of a date. In other languages and databases like MSSQL or PHP those are often implicitly converted, but in VFP there is no such conversion, of course the string " / / " is not empty, but when a date is empty it is displayed as that, still it is a date type and it is the empty date, to which EMPTY() works.

If you don't like the "invalid Date" wait window message, you'll have a hard time, because
a) it doesn't trigger a VFP error, so no error event will happen
b) it does happen before valid event would trigger, so valid also doesn't help.
c) the only event running before VFP checks the date validity is Keypress, so you have to write code in the textbox.keypress and check whether the key is tab/backtab or return to leave the control.
d) some other cases like a month>13 would also trigger the "invalid date" wait window even before the user leaves the control.

I don't know, I'm fine with that message, the VFP runtime resource DLLs will also display it in whatever language you add to the runtimes in the final EXE. I think of it as effective and least disturbing.
But if you absolutely don't like it the textbox.KeyPress is your only point of prevention. Note, the textbox.value will only be a correct date, while textbox.text is what is entered so far. You should not act too soon. Of course at most times the text isn't yet a complete date but won't cause the "invalid date" wait window. So only act on some cases like month>12, day>31, and when the nKeycode is one of tab, backtab, enter (that's values 9,15,13).

Chriss
 
One way to see how the displayed text is interpreted by VFP is to have 2 textboxes on a form: Text1 and Text2.
In the Text1 textbox Keypress and InteractiveChange events program this line of code:

Code:
Thisform.Text2.Value = This.Value
(You gotta keep the LPARAMETERS in keypress, otherwise any keypress will error, but you only add this one line to beoth events.)

Initialize Text1 and Text2 with the empty date by setting both their values to CTOD(''), for example in Form Init you could do
STORE CTOD('') TO Thisform.Text1.Value, Thisform.Text2.Value

Now using text1 you still will have the "Invalid Date", that code in Keypress doesn't handle that, but cope with that for a while, there are some stages to observe here:
dateentrystages_hqilqd.png


First, remember I put the value of text1 into text2, that way the text2 box just makes visible what the value of text1 is. And you can see an empty date there, as long as the typed in text portion like "11/ / " is not yet a complete date. You also see that VFP autocompletes whenever it can, it does interpret a date for the current year, when no year digit is entered yet, it will expand a year with century, as long as only 1 or 2 digits of the year are entered. You can also try out a number like 89, which will be expanded to 1989. There's a roll over number you can also define with the ROLLOVER clause of SET CENTURY - see the help on that for the details.

Now the good news, unlike I thought the entry of month 13 (as in the 7th stage) or 29th of a February in a non leap year (9th stage) does not in itself trigger the "Invalid Date" messge you can't override, the moment that happens is when you want to leave the textbox while the value is still empty. And as already said, you can check EMPTY(Text.Value) when it's a date type value, which is the case here when initialized with a date, any date, also the empty date. The only case where VFP will allow leaving and not alert with "Invalid Date" is the user actually entered nothing or only spaces and the text1.text is still just the empty date. You could ignore that case, though, if you want a user that activated such a textbox to only get out with a valid date, you can still make that a check of the Text1.Valid event.

Anyway, the focus of this good news is, that you actually now only need to check Keypress for keys that trigger leaving the textbox. If there is a TAB, BBACKTAB, ENTER while the Text1.Value is the empty date, you could stop that from happening by NODEFAULT in the Keypress event. Which means the user will not leave the Textbox and no "Invalid Date" messge appears. And then it's your turn to either display another message, indicate the invalid date with a backcolor change or whatever else.

The bad news is illustrated in the last 9th stage: The text cursor here is before the 3 of 2003, the date is not valid in that year, therefore text1.value (and text2 display) is the empty date, now not only TAB, BACKTAB, and ENTER leave the control at an invalid state, also a RIGHT ARROW key would. You could not always react to a RIGHT ARROW key with your own way of stating the invalid date, though, the user should be allowed to move through the digits with the text cursor to change them and make it a valid date.

So that's now the complicated corner case. Unfortunately there are more: Whenever the user leaves the date textbox with a mouse click, not only to another control but also to another window or even another application. You can't trap that in Keypress, now you'd need to act in all kind of event of any other control and form, which would break encapsulation to do that. So that'll be the Achilles heel, but you can easily trap the case of TAB/BACKTAB/ENTER leaving the textbox when it's text has more than just the spaces and date mark characters and the textbox value is the empty date. That can be prevented and signaled in another way.

PS: There's a good news within that bad news, that even without trying to catch the spilled milk of cases where mouse clicks lead to the "Invalid Date" message, that's not breaking the world, the unfortunate "Invalid Date" message will appear, but that also prevents leaving the textbox in an invalid date state. It's not very likely to happen, if a user is about entering a date, why would he pick up the mouse before he finshes that?

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top