I am trying to create a procedure that shows an error message if the input doesn't match the condition.
Here is my code:
procedure TForm_Main.Input(Edit: TEdit; I: Integer);
var
Error_Text: TLabel;
begin
if (Assigned(Error_Text)) then
begin
Error_Text.Text := '';
Error_Text.Visible := False;
end
else
begin
Error_Text := TLabel.Create(Edit);
Error_Text.Parent := Edit;
Error_Text.TextSettings.FontColor := TAlphaColors.Red;
Error_Text.Position.Y := 25;
Error_Text.AutoSize := True;
Error_Text.Visible := False;
end;
if Edit.Text.IsEmpty then
begin
Error_Text.Text := '';
Error_Text.Visible := False;
end
else
begin
case I of
1:
begin
if not TRegEx.IsMatch(Edit.Text, '^\d+$') then
begin
Error_Text.Text := 'Error: Input must contain only numbers.';
Error_Text.Visible := True;
end
else
begin
Error_Text.Text := '';
Error_Text.Visible := False;
end;
end;
2:
begin
if not TRegEx.IsMatch(Edit.Text, '^[A-Za-z]+$') then
begin
Error_Text.Text := 'Error: Input must contain only characters.';
Error_Text.Visible := True;
end
else
begin
Error_Text.Text := '';
Error_Text.Visible := False;
end;
end;
3:
begin
if not TRegEx.IsMatch(Edit.Text, '^[A-Za-z0-9]+$') then
begin
Error_Text.Text := 'Error: Input must contain only characters and numbers.';
Error_Text.Visible := True;
end
else
begin
Error_Text.Text := '';
Error_Text.Visible := False;
end;
end;
end;
end;
And I am calling it with ontyping
event:
procedure TForm_Main.Edit_Code_TypeTyping(Sender: TObject);
begin
Input(Edit_Code_Type, 1)
end;
This is the expected result:
And this is the result I get instead:
I tried everything I know so far, but I either get an error message or it starts to create labels infinitely.
You have Error_Text
as a local variable within the method. Local variables are not preserved between calls to the method, and their value is not set to any default. So Error_Text
may be nil each time the method is called, in which case your test for it being assigned will result in a new label each time, or it may be some random value, in which case you will attempt to set the text of a control that isn't valid.
Why are you creating the label at run time? Why not create the label at design time? You also have a lot of unnecessary code. There is little point in hiding an empty label, as you won't see it in any case.
I'd create the label at design time, and rewrite your code to something like this:
procedure TForm_Main.Input(Edit: TEdit; I: Integer);
begin
Error_Text.Text := '';
if not Edit.Text.IsEmpty then
begin
case I of
1: if not TRegEx.IsMatch(Edit.Text, '^\d+$')
then Error_Text.Text := 'Error: Input must contain only numbers.';
2: if not TRegEx.IsMatch(Edit.Text, '^[A-Za-z]+$')
then Error_Text.Text := 'Error: Input must contain only characters.';
3: if not TRegEx.IsMatch(Edit.Text, '^[A-Za-z0-9]+$')
then Error_Text.Text := 'Error: Input must contain only characters and numbers.';
end; {case}
end; {if}
end;