• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 521
  • Last Modified:

How to Validate User Input into a date field on a delphi form

I have a data entry form that allows users to enter in sales dates. I would like to restrict the date entry field so that they can only enter in anything from today and back up to 7 days. This will prohibit fat-finger mistakes where the user sometimes puts in the wrong year! Thanks!
0
Norm-al
Asked:
Norm-al
  • 5
  • 4
1 Solution
 
epasquierCommented:
if you are using a TDateTimePicker, you can set the MinDate property to Now when you open your form

procedure TForm1.FormShow(Sender: TObject);
begin
 dtPicker.MinDate:=now;
end;

Open in new window

0
 
Norm-alNetwork EngineerAuthor Commented:
There are 10 different date fields and each one will have different restrictions, some with no restrictions. Is there any way to restrict a specific date field to have minimum date of today - 7 days and have maximum date of today?
0
 
epasquierCommented:
yes, exactly the same, using MinDate, and MaxDate


procedure TForm1.FormShow(Sender: TObject);
begin
 dtPicker.MinDate:=now-7;
 dtPicker.MaxDate:=now;
end;

Open in new window

0
Learn to develop an Android App

Want to increase your earning potential in 2018? Pad your resume with app building experience. Learn how with this hands-on course.

 
Norm-alNetwork EngineerAuthor Commented:
Need help finishing this one with an error message saying 'date entered needs to be within the past 7 days':

procedure TfrmJobDataEntry.edBidDatePropertiesChange(Sender: TObject);
begin
  inherited;
  if not (edBidDate.Properties.MinDate:=now-7) or not (edBidDate.Properties.MaxDate:=now)
    then ....?

Thank you so much!
0
 
Norm-alNetwork EngineerAuthor Commented:
I tried this and it gives me the message dialog even if the date I enter is between today and last week...

procedure TfrmJobDataEntry.edBidDatePropertiesChange(Sender: TObject);
begin
  inherited;

  with edBidDate.Properties do begin
  if MinDate < DateOf(Now - 7) then begin
     edBidDate.Clear;
     messagedlg('Please enter a Bid Date between today and 1 week ago.', mtError, [mbOK], 0);
     end;
  end;
end;
0
 
epasquierCommented:
using MinDate and MaxDate will completely avoid that the user select a wrong date, so there will be no onChange event. So you can't use both techniques.

And I find that the better, because if you display messages when the value is changed, that can be quickly annoying for the user, all the more because there can be times where the onChange is triggered without user interaction, or twice, because of internal working of the dtPicker.

just a little change with what I told about setting the MinDate & MaxDate : since you are not using time, and don't want to, you set it to the result of Date function , not now :

procedure TForm1.FormShow(Sender: TObject);
begin
 dtPicker.MinDate:=Date-7;
 dtPicker.MaxDate:=Date;
end;

Open in new window

0
 
Norm-alNetwork EngineerAuthor Commented:
procedure TfrmJobDataEntry.edSalesDateExit(Sender: TObject);
begin
  inherited;

  if dmJobDataEntry.qryPCJobData.FieldValues['Approved_Sales'] < Today-7 then begin
  dmJobDataEntry.qryPCJobData.FieldByName('Approved_Sales').Clear;
  messagedlg('Please enter a Sales Date between today and 1 week ago.', mtError, [mbOK], 0);
  end;

  if dmJobDataEntry.qryPCJobData.FieldValues['Approved_Sales'] > Today then begin
  dmJobDataEntry.qryPCJobData.FieldByName('Approved_Sales').Clear;
  messagedlg('Please enter a Sales Date between today and 1 week ago.', mtError, [mbOK], 0);
  end;
end;
0
 
epasquierCommented:
if you want to do it that way, that can work also.
you can combine both tests , and you can ommit the .FieldValues because it's the default property of a dataset
procedure TfrmJobDataEntry.edSalesDateExit(Sender: TObject);
begin
 inherited; // why do you have an inherited here ? it's from a frame ?
 if (dmJobDataEntry.qryPCJobData['Approved_Sales'] < Today-7)
  Or (dmJobDataEntry.qryPCJobData['Approved_Sales'] > Today)
   then 
  begin
   dmJobDataEntry.qryPCJobData.FieldByName('Approved_Sales').Clear;
   messagedlg('Please enter a Sales Date between today and 1 week ago.', mtError, [mbOK], 0);
  end;
end;

Open in new window

0
 
epasquierCommented:
You might have found another solution in your own code, but does that means that I didn't help at all ?

If you think so, then effectively you can close your question accepting your own answer.

Otherwise, as your question did not talked about the need to display a message, I think my answer was correct. You could also have waited that I give you more tips.

My advice about not bothering the user with letting him input wrong date just to have the pleasure to show him a dialog is something to take into account. In my experience, users don't like to be reminded constantly they have fat fingers if it can be avoided in the first place. But I admit that some users just can't accept not being able to click on a wrong date, if there is not even a warning somewhere. You can use a status bar to display constraints (what you would show in case of entry error) when the user put the focus in certain fields (onEnter to display / onExit to clear). That is my preferred way because it combines best of all options.
0

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now