0

I have these controls TDateTimePicker, TComboBox, Tedit and TButton. TButton is disabled by default. What I would like to achieve is to enable TButton when all the other controls are filled or not null.

With the following codes, all the 3 controls starting with TDateTimePicker when filled I don't have any issues it works as expected.

The error comes when I fill TComboxBox followed by TEdit, it enables the TButton even TDateTimePicker is not filled yet. Or vise versa, I will fill TEdit followed by TComboBox, it enables the TButton.

From the codes below, I expect the TButton will not enable unless all the 3 controls are filled.

I've been trying to figure out (all day) how this error come to happen.

I will appreciate anyone there help me figure this out.

procedure TfrmHolidays.EnableSaveButton;
begin
if (edtHolidayName.Text <> NullAsStringValue) and (cmbHolidayType.ItemIndex <> -1)and (dtpHolidayDate.Date <> 0) then
  begin
    btnHolidaySave.Enabled := True;
  end
  else
  begin
    btnHolidaySave.Enabled := False;
  end;
end;

procedure TfrmHolidays.dtpHolidayDateChange(Sender: TObject);
begin
  EnableSaveButton;
end;

procedure TfrmHolidays.cmbHolidayTypeChange(Sender: TObject);
begin
  EnableSaveButton;
end;

procedure TfrmHolidays.edtHolidayNameChange(Sender: TObject);
begin
  EnableSaveButton; // triggers enable btnHolidaySave button
end;

By the way, I have more code related to making TDateTimePicker a blank and I supposed there's no issues with that. I also tried nesting within If Statement each condition and I am still getting the error. Further, I tested each condition at a time and It works fine.

Updates: Here's how I initialized the dtpHolidayDate.Date:

procedure TfrmHolidays.FormCreate(Sender: TObject);
begin
  DateTime_SetFormat(dtpHolidayDate.Handle, ' ');
  FDTMDateEmpty := True;
end;

procedure TfrmHolidays.dtpHolidayDateCloseUp(Sender: TObject);
begin
  DateTime_SetFormat(dtpHolidayDate.Handle, PChar('MMM dd yyyy (ddd)'));
end;

procedure TfrmHolidays.dtpHolidayDateChange(Sender: TObject);
begin
  FDTMDateEmpty := False;
  EnableSaveButton; // same and updated procedure above
end;
Mel
  • 101
  • 1
  • 9
  • Debug the EnableSaveButton procedure and see what the value of dtpHolidayDate.Date is – Keith Miller Sep 19 '19 at 13:40
  • 1
    AFAIK, TDateTimePicker is initialized with the current date time. We cannot see code that initializes TDateTimePicker, so dtpHolidayDate.Date <> 0 might return true right from the beginning. You should also tell us your Delphi version, because some controls behave differently depending on the Delphi used. – Uwe Raabe Sep 19 '19 at 13:40
  • TDateTimePicker doens't have a null value by default. You'll have to do something [like this](https://stackoverflow.com/a/35974955/260411). – Toribio Sep 19 '19 at 13:42
  • Not related to the issue you are describing, but I'd write `edtHolidayName.Text <> ''` instead of `edtHolidayName.Text <> NullAsStringValue`. No need to involve variants here. – Andreas Rejbrand Sep 19 '19 at 13:58
  • 1
    Use a debugger to inspect the values of the various variables and properties as your program is executing. If you had done so then you'd know what was happening, so I can only assume that you have not yet learnt how to debug. Without this skill it will be impossible to become an effective programmer. Make it your mission to learn how to debug. – David Heffernan Sep 19 '19 at 14:52
  • @DavidHeffernan I did some debugging like showmessage() to know the values of the variables and no issues about that, particularly the dtpHolidayDate which I intentionally want it at zero (the original date Dec 30 1899). I will appreciate more if you can suggest a better way to debug other than the one I did. – Mel Sep 19 '19 at 19:19
  • @UweRaabe I am using Delphi 10.3 Rio. – Mel Sep 19 '19 at 19:20
  • Use the integrated debugger – David Heffernan Sep 19 '19 at 19:57
  • @DavidHeffernan Many thanks. – Mel Sep 19 '19 at 20:49
  • @Mel - Can you please post how do you initialize edtHolidayName.Date? That has been asked several times in the comments and there is an answer that nearly entirely depends on a guess about how you initialize it and there's another answer that depends on a guess that you're not initializing it at all. It's about time that you reveal the mystery.. :) In the meantime I voted to close as not reproducible. – Sertac Akyuz Sep 20 '19 at 13:54
  • @SertacAkyuz apologies for not able to reply soon. I have updated the above with my initialization of dtpHolidayDate.Date (I supposed this is the one you were asking). – Mel Sep 21 '19 at 23:36
  • @Mel, thanks, yes probably that is the missing part. It looks like my assumption was not correct, your code does not initialize the date. It only sets the format so that it shows empty. But the value remains whatever set in object inspector, most probably the date you put the control on the form. – Sertac Akyuz Sep 22 '19 at 01:07
  • @SertacAkyuz Exactly. However, I still haven't resolved the issue pertaining to cmbHolidayType and edtHolidayName at OnChange event which gives me the error during runtime. I will create a small project specifically for this and try. Let me get back to you on this. – Mel Sep 23 '19 at 22:55

2 Answers2

0

As pointed out in the comments above, you do not have an initialised value for the TDateTimePicker.

What you want is to have it default to a sensible date, rather than set to 0 - that is not at all helpful to users.

I would introduce a Boolean flag that you set yourself once the TDateTimePicker has been set.

You could set this flag in the OnChange event handler.

So something like:


interface

protected
  blMyDTFlag: Boolean;
...

implementation
  function TfrmHolidays.dtpHolidayDateChange(Sender: TObject);
  begin
    Self.blMyDTFlag:=True;
  end

procedure TfrmHolidays.EnableSaveButton;
begin
if (edtHolidayName.Text <> '') and
   (cmbHolidayType.ItemIndex <> -1) and
   (Self.dtMyDTFlag) then
    btnHolidaySave.Enabled := True
  else
    btnHolidaySave.Enabled := False;
end;

Rob Lambden
  • 2,175
  • 6
  • 15
  • just a quick one. I having trouble with the self declaration, an error is syaing the TfrmHolidays doesn't have a member. I know this is so basic but I will appreciate any help. – Mel Sep 19 '19 at 21:27
  • @Mel - Self is the object (so the form for a form method) and is optional (I have it drummed in to me to use it) so it should work fine without it. Did you declare your flag in the interface section of the form? – Rob Lambden Sep 19 '19 at 21:33
  • Thank you for clarifying. From your code, you gave a new approach of coding —. appreciate it. Though, I am looking this time a more not so complex to me. – Mel Sep 21 '19 at 23:41
-1

Although not shown in the question, I can guess that you initialize the date by

dtpHolidayDate.Date := 0;

After this, testing the date against 0 will (most likely) fail because the time portion still contains the time that the control is created.

You can initialize by

dtpHolidayDate.DateTime := 0;

then you can test the date as you do.

Alternatively you can use SameDate to do the comparison.

uses
  dateutils;


if (edtHolidayName.Text <> NullAsStringValue) and (cmbHolidayType.ItemIndex <> -1)
    and (not SameDate(dtpHolidayDate.Date, 0)) then
Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
  • Initializing the TDatePickers DateTime to 0 is not helpful to users - it sends the calendar to 1899-12-30 00:00:00 ! Users have to scroll from then on to a more recent and applicable date. (See http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/System_TDateTime.html ) – Rob Lambden Sep 20 '19 at 15:30
  • @Rob - That's what the poster wants as stated in this [comment](https://stackoverflow.com/questions/58012215/error-on-if-statement-with-multiple-and-conditions/58018232#comment102438899_58012215). – Sertac Akyuz Sep 20 '19 at 15:38
  • thanks for pointing this out ... it makes no sense to me, but if that's what they want then fair enough! – Rob Lambden Sep 20 '19 at 15:40
  • @SertacAkyuz Looks your edited one makes sense to me. I'll try it. – Mel Sep 21 '19 at 23:40
  • From your edit to the question it shouldn't work, unless you set the date in object inspector to 30-12-1899. – Sertac Akyuz Sep 22 '19 at 01:12
  • BTW, you already have the flag that Rob suggested, it is FDTMDateEmpty. You just need to test if it is set instead of the date. – Sertac Akyuz Sep 22 '19 at 01:26