Recent

Author Topic: Validations and setFocus pain...  (Read 4118 times)

eara

  • Jr. Member
  • **
  • Posts: 84
Validations and setFocus pain...
« on: April 20, 2014, 09:15:50 pm »
In my project a painfull & time consuming process is the ".setFocus" in case a validation fails.

I will  try to explain what i mean...

All the time i write validations (usually on BeforePost) that may fire a MessageDlg or raise an exception, and in case of validation failure i want to focus to the related control, where user can edit it's value and retry...

The validations are performed usually with TFields from TSQLQuery instead of the db controls (yes i use db controls).

Now when a validation fails, and before throwing in the user's face the corresponding error message i try to call the setFocus of the related control (if any exists).

One problem that arrises is to ensure that the control can be focused (is it enabled? or worst ... is it visible ?) and the complexity of this depends on the form's design.

And my case is suffering little from this.

All my forms have 2 PageControls with mutliple tabSheets, so i need also to check page controls and tabsheet if they are visible, enabled in order to select them etc etc...

What i did for this till now...

I wrote a general focusField(f:TField) virtual method in a base form class and i use it all the time....

Now in every descedant form, i must override this and for every field in my form i try to find the related control and set the focus on it.
take an example of what i mean...

Code: [Select]
procedure TfrmTranTypes.focusField(f: TField);
begin
  if pgc.Enabled and pgc.Visible
  and tabRecord.Enabled  and tabRecord.tabVisible then begin

    pgc.ActivePage:=tabRecord;

    if (edt_tran_type.Field=f)
    and edt_tran_type.Enabled
    and edt_tran_type.Visible then
      edt_tran_type.SetFocus

    else if (edt_tran_type_label.Field=f)
    and edt_tran_type_label.Enabled
    and edt_tran_type_label.Visible then
      edt_tran_type_label.SetFocus

    else if (edt_tran_type_desc.Field=f)
    and edt_tran_type_desc.Enabled
    and edt_tran_type_desc.Visible
    and pgcDetails.Enabled
    and pgcDetails.Visible
    and tab_tran_type_desc.Enabled
    and tab_tran_type_desc.tabVisible then begin
      pgcDetails.ActivePage:=tab_tran_type_desc;
      edt_tran_type_desc.SetFocus

    end else if (chk_tran_type_hardcoded.Field=f)
    and chk_tran_type_hardcoded.Enabled
    and chk_tran_type_hardcoded.Visible then
      chk_tran_type_hardcoded.SetFocus

    else if (chk_tran_type_media.Field=f)
    and chk_tran_type_media.Enabled
    and chk_tran_type_media.Visible then
      chk_tran_type_media.SetFocus

    else if (chk_tran_type_member.Field=f)
    and chk_tran_type_member.Enabled
    and chk_tran_type_member.Visible then
      chk_tran_type_member.SetFocus
  end;
end;

One thing that would help this (not sure, only speculate) is to have in TFields a property where i can set the related control in design time or in runtime....

One other is a recursive routine where you give the control and tries to check if it is focus able, or should i just simple call setFocus in a try except ?

currently i must leave with this for my project (time pressure), but i would like to hear also other thoughts ...




« Last Edit: April 20, 2014, 09:17:27 pm by eara »

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: Validations and setFocus pain...
« Reply #1 on: April 20, 2014, 09:23:32 pm »
Did you try
Code: [Select]
CanFocusmethod?
BTW, what platform do you have?
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

eara

  • Jr. Member
  • **
  • Posts: 84
Re: Validations and setFocus pain...
« Reply #2 on: April 20, 2014, 09:44:59 pm »
@Blaazen  :o what have you said right now !!!! :-[
 :-[ No i didn't .... but quick thinking... again in case .CanFocus returns false again i must write the same !@#!@#! for selecting the right tabsheet ...
(lazarus 1.2.0) thank you...

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Validations and setFocus pain...
« Reply #3 on: April 21, 2014, 12:29:09 am »
something along the lines of

Code: [Select]
function IsDBAware(const aControl:TControl):Boolean;
begin
  Result := aControl.InheritsFrom(TCustomDBListBox) or
            aControl.InheritsFrom(TDBRadioGroup) or
            aControl.InheritsFrom(TDBCheckBox) or
            aControl.InheritsFrom(TCustomDBComboBox) or
            aControl.InheritsFrom(TDBMemo) or
            aControl.InheritsFrom(TDBGroupBox) or
            aControl.InheritsFrom(TDBImage) or
            aControl.InheritsFrom(TDBCalendar) or
            aControl.InheritsFrom(TDBEdit) or
            aControl.InheritsFrom(TDBText) or
            aControl.InheritsFrom(TDBLookup);
end;
function IsFieldEditor(const aControl:TControl; const aField:TField):Boolean;
begin
  Result := False;
  if IsDBAware(aControl) then begin
    if (aControl is TDBEdit)          then Result := TDBEdit(aControl).Field = aField;
    if (aControl is TCustomDBListBox) then Result := TCustomDBListBox(aControl).Field = aField;
    if (aControl is TDBRadioGroup)    then Result := TDBRadioGroup(aControl).Field = aField;
    if (aControl is TDBCheckBox)      then Result := TDBCheckBox(aControl).Field = aField;
    if (aControl is TDBMemo)          then Result := TDBMemo(aControl).Field = aField;
    if (aControl is TDBGroupBox)      then Result := TDBGroupBox(aControl).Field = aField;
    if (aControl is TDBImage)         then Result := TDBImage(aControl).Field = aField;
    if (aControl is TDBCalendar)      then Result := TDBCalendar(aControl).Field = aField;
    if (aControl is TDBEdit)          then Result := TDBEdit(aControl).Field = aField;
    if (aControl is TDBText)          then Result := TDBText(aControl).Field = aField;
    if (aControl is TDBLookup)        then Result := TDBLookup(aControl).KeyField = aField;
  end;
end;

function ControlTabSheet(aControl:TWinControl):TTabSheet;
begin
  Result := aControl;
  while not (Result is TTAbSheet) do result := Result.Parent;
end;

procedure ActivateTabSheet(const aTabSheet:TTabSheet);
begin
  if not Assigned(aTabSheet) then exit;
  aTabSheet.PageControl.ActivePage := aTabSheet;
  ActivateTabSheet(ControlTabSheet(aTabSheet);
end;
function ShowForm(const aForm : TForm; const aModal : Boolean):Integer;
begin
  if Assigned(aForm) and (not aForm.Visible) then begin
    Result := 0;
    if aModal then Result := aForm.ShowModal else aForm.Show;
  end;
end;

procedure ActivateControl(aControl:TWinControl);
begin
  If not aControl.CanFocus then begin
    ActivateTabSheet(ControlTabSheet(aControl));
    ShowForm(GetParentForm(aControl), False);
  end;
  aControl.SetFocus;
end;



function TForm1.FocusField(aField: TField): Boolean;
var
  CompCount: Integer;
begin
  for CompCount := 0 to ComponentCount -1 do begin
    if (Components[CompCount] is TWinControl) and IsFieldEditor(TWinControl(Components[CompCount]), aField) then
      ActivateControl(Components[CompCount]);
  end;
end;

This should minimize overriding to exceptions only and probably only if those exceptions should be kept as such and not appended in one of the support procedures. eg tzvDBDateTimePicker is there in my libraries because I use that component too but a Data aware component that is used only in one of my applications in one form and will never be used outside that application and form will never find its way in the routines which I try to keep its external dependencies as minimal as possible.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

eara

  • Jr. Member
  • **
  • Posts: 84
Re: Validations and setFocus pain...
« Reply #4 on: April 22, 2014, 11:34:40 am »
thank you man, i ll check this

 

TinyPortal © 2005-2018