0
votes

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;
2
Debug the EnableSaveButton procedure and see what the value of dtpHolidayDate.Date isKeith Miller
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
TDateTimePicker doens't have a null value by default. You'll have to do something like this.Toribio
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
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

2 Answers

0
votes

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;

-1
votes

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