0

I would like that user could write only numbers from 1 to 49 in edit box. I know how to exclude letters and has possibility to put only numbers but I can't limit it to specific numbers (e.g from 1 to 49 - like in lottery game). I added KeyDown event to edit box and put this code:

   if not (KeyChar in ['1'..'9']) then
   begin
      ShowMessage('Invalid character');
      KeyChar := #0;
   end;

How can I modify it?

astack
  • 161
  • 4
  • 16
  • 4
    This kind of problem has been solved in a lot of spinedit controls that accept max and min bounds - have a look at some of those examples (there's one in the VCL and also a JEDI version) and see how they do it. You've also missed out '0' – Matt Allwood Aug 14 '15 at 08:38
  • 5
    Far better to let the user type whatever they want but show a non-modal message (usually in red) to indicate that there is an error, and stop the user from proceeding while the error state persists. – David Heffernan Aug 14 '15 at 08:50
  • Can you not check in the keydown if the Text property is a number, and if so if the number is between 1 and 49 ? Or even easier, use a SpinEdit in stead of a EditBox. – GuidoG Aug 14 '15 at 11:02
  • [Peter Below's article on borland.public.delphi.vcl.components.writing in 2001](https://groups.google.com/forum/#!original/borland.public.delphi.vcl.components.writing/JjtJZMqd4bg/31xA3YUvtkEJ) should cover everything you need. – Rob Kennedy Aug 16 '15 at 04:20

2 Answers2

3

Following David's advice, a pattern I often use looks something like this :

function Validate1To49(AStr : string; var Value : integer) : boolean;
begin
  result := TryStrToInt(AStr, Value) and
            (Value >= 1) and (Value <= 49);
end;

procedure TForm1.Edit1Change(Sender: TObject);
var
  tmp : integer;
begin
  if Validate1To49(Edit1.Text, tmp) then
    Edit1.Color := clWhite
  else
    Edit1.Color := clRed;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  theValue : integer;
begin
  if Validate1To49(Edit1.Text, theValue) then begin
    // go ahead and do something with "theValue"
  end else
    ShowMessage('Value not valid');
end;   

Here if the user inputs anything invalid there is immediate visual feedback that is not intrusive like a modal message box. Here I coloured the edit box red, but you can also show/hide or change the colour of a warning label above the edit box with a message detailing the expected input, use a green checkmark, or whatever else seems sensible

This has the benefit that the user can see immediately whether or not their inputs are valid. The validation methods can be wrapped up so that they can be re-used when the user attempts to initiate an action requiring those inputs. At this point I feel it's fine to use a modal messagebox because the user has plainly missed the obvious cues already in front of them. Alternatively, when validating in the OnChange handler you can simply disable any action controls (like buttons, etc) that would allow the user to proceed. This requires validating all input controls required for the action - again, usually you would wrap the entire validation action into a single method for sensible re-use.

For simple values like integers, a good SpinEdit control can be useful (the VCL one is included in the Samples package - not always installed by default). The above pattern is more flexible, however and can be used for any type of input. A SpinEdit won't provide any feedback, however - the user will simply type and nothing will show up. They may wonder whether the application is broken if there is no clear guidance visible about what the input element will accept.

J...
  • 30,968
  • 6
  • 66
  • 143
1

The same question can also be answered in this way also by writing a OnKeyPress event for a Edit box. By this way the user will not be able to enter the number greater than the limit which we define.

procedure TfrmCourse.edtDurationKeyPress(Sender: TObject; var Key: Char);
var
  sTextvalue: string;
begin
  if Sender = edtDuration then
  begin
    if (Key = FormatSettings.DecimalSeparator) AND
      (pos(FormatSettings.DecimalSeparator, edtDuration.Text) <> 0) then
      Key := #0;

    if (charInSet(Key, ['0' .. '9'])) then
    begin
      sTextvalue := TEdit(Sender).Text + Key;
      if sTextvalue <> '' then
      begin
        if ((StrToFloat(sTextvalue) > 12) and (Key <> #8)) then
          Key := #0;
      end;
    end
  end;
end;
userhi
  • 553
  • 1
  • 7
  • 27