Jump to content

About SubComponents


RafaelW

Recommended Posts

Hello, i trying to implement a new component Edit with aside button..

 

And internally already implemented OnClick.

 

But this OnClick method is never called.

 

here is the code :

 

for compile the PLUniPesquisa can be removed...

 

 

 

unit PLUniEdit;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, Messages, PLUniSeekButton, Db, Datasnap.DBClient,
  Windows, Forms, Graphics, PLUniUtils, Math, StrUtils, Variants,
  PesquisaConfig, Vcl.ExtCtrls, PLUniPesquisa, System.TypInfo, uniEdit;

type
  TPLUniEditKeyValueChange = procedure(Sender: TObject; Value: Variant) of object;
  TPLUniEdit = class(TUniEdit)
  private
    fKeyValue: string;
    FBtn: TPLUniSeekButton;
    FOnExit: TNotifyEvent;
    FOnKeyValueChange: TPLUniEditKeyValueChange;
    FVisibleButton: Boolean;
    fPesquisa: TPesquisaConfig;
    fRequired: boolean;
    fOnClickButton: TNotifyEvent;
    FControlsOtherFields: TStrings;
    fOtherFieldsRecursive: Boolean;

    function getCtl3D: boolean;
    function getLeft: integer;
    function getTop: integer;
    function getWidth: integer;

    procedure setKeyValue(const Value: string);
    procedure AutoFit;
    procedure SetupInternalButton;
    procedure setCtl3D(const Value: boolean);
    procedure setLeft(const Value: integer);
    procedure setTop(const Value: integer);
    procedure setWidth(const Value: integer);
    procedure SetOnKeyValueChange(const Value: TPLUniEditKeyValueChange);
    procedure SetVisibleButton(const Value: Boolean);
    procedure setPesquisa(Sender: TObject);
    procedure SetControlsOtherFields(const Value: TStrings);

    procedure ValidatePesquisa;
  protected
    procedure Loaded; override;
    procedure OnPLExit( sender: TObject ); virtual;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure SetParent(AParent: TWinControl); override;

    procedure SetName(const Value: TComponentName); override;

    procedure OnClickBtn(Sender: TObject);

    procedure PopulateDataFromPesquisa(ReturnDataset: TClientDataset; Clear: Boolean);
    procedure PopulateOtherControls(control: TPLUniEdit; ReturnDataset: TClientDataset; Clear: Boolean);
  public
    property KeyValue: string read fKeyValue write setKeyValue;

    procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override;


    constructor Create(AOwner: TComponent); override;

    destructor Destroy; override;

    procedure GetUniqueValue;

  published
    property OnExit : TNotifyEvent read FOnExit write FOnExit;
    property OnClickButton: TNotifyEvent read fOnClickButton write fOnClickButton;
    property OnKeyValueChange: TPLUniEditKeyValueChange read FOnKeyValueChange write SetOnKeyValueChange;

    property Required : boolean read fRequired write fRequired default false;
    property Pesquisa: TPesquisaConfig read fPesquisa write fPesquisa;
    property Button : TPLUniSeekButton read FBtn;
    property Top : integer read getTop write setTop;
    property Left : integer read getLeft write setLeft;
    property Ctl3D : boolean read getCtl3D write setCtl3D;
    property Width : integer read getWidth write setWidth;

    property VisibleButton : Boolean read FVisibleButton write SetVisibleButton default False;

    property ControlsOtherFields: TStrings read FControlsOtherFields write SetControlsOtherFields;
    property OtherFieldsRecursive: Boolean read fOtherFieldsRecursive write fOtherFieldsRecursive default True;
  end;

implementation

procedure TPLUniEdit.AutoFit;
begin
  if assigned(FBtn) then
  begin
    FBtn.Top := Top;
    FBtn.Left := Left+Width+1;

    if FBtn.Visible then
    begin
      FBtn.Width := Height;
      FBtn.Height := Height;
    end;

    if assigned(FBtn.JSControl) then
      FBtn.JSControl.SetPosition(FBtn.Left, FBtn.Top);
  end;
end;

constructor TPLUniEdit.Create(AOwner: TComponent);
begin
  inherited Create( AOwner );

  inherited OnExit := OnPLExit;

  fPesquisa := TPesquisaConfig.Create;
  fPesquisa.NotifyPesquisa := setPesquisa;

  self.Ctl3D := False;
  SetupInternalButton;

  TEdit(self).Modified := False;
  fVisibleButton := False;
  fRequired := False;

  FControlsOtherFields := TStringList.Create;
  fOtherFieldsRecursive := True;
end;

destructor TPLUniEdit.Destroy;
begin
  if Assigned(fPesquisa) then
    FreeAndNil(fPesquisa);

  if Assigned(FControlsOtherFields) then
    FControlsOtherFields.Free;

  inherited;
end;

function TPLUniEdit.getCtl3D: boolean;
begin
  result := inherited Ctl3D;
end;

function TPLUniEdit.getLeft: integer;
begin
  Result := inherited Left;
end;

function TPLUniEdit.getTop: integer;
begin
  Result := inherited Top;
end;

procedure TPLUniEdit.GetUniqueValue;
begin
  if (not FVisibleButton) and Assigned(fPesquisa.Pesquisa) then
  begin
    ValidatePesquisa;

    fPesquisa.Pesquisa.BackupConfiguration;
    try
      fPesquisa.Pesquisa.AOWner := self.Owner;
      fPesquisa.Pesquisa.SQL.Text := fPesquisa.SQL.Text;
      fPesquisa.Pesquisa.TagToUpdate := self.Tag;
      fPesquisa.Pesquisa.ExecSQLOnStart := True;

      fPesquisa.Pesquisa.KeyField := getPesquisaFieldId(nil, fPesquisa.FieldId, self);
      fPesquisa.Pesquisa.Column := IfThen(fPesquisa.FieldSearch.IsEmpty, fPesquisa.FieldDisplay, fPesquisa.FieldSearch);

      if not self.KeyValue.IsEmpty then
      begin
        fPesquisa.Pesquisa.Column := fPesquisa.Pesquisa.KeyField;
        fPesquisa.Pesquisa.Value  := self.KeyValue;
      end
      else
      if not trim(self.Text).IsEmpty then
      begin
        fPesquisa.Pesquisa.Column := IfThen(fPesquisa.FieldSearch.IsEmpty, fPesquisa.FieldDisplay, fPesquisa.FieldSearch);
        fPesquisa.Pesquisa.Value  := self.KeyValue;
      end;

      fPesquisa.Pesquisa.MethodAtualizaComp := PopulateDataFromPesquisa;
      fPesquisa.Pesquisa.Execute(True);
    finally
      fPesquisa.Pesquisa.RestoreConfiguration;
    end;
  end;
end;

function TPLUniEdit.getWidth: integer;
begin
  Result := inherited Width;
end;


procedure TPLUniEdit.Loaded;
begin
  inherited;
  FBtn.Visible := Visible and (assigned(fPesquisa.Pesquisa) or FVisibleButton);

  if FBtn.Visible then
  begin
    self.Button.OnClick := self.OnClickBtn;
  end;
end;

procedure TPLUniEdit.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);

  if (AComponent = FBtn) and (Operation = opRemove) then
    FBtn := nil;

end;

procedure TPLUniEdit.OnClickBtn(Sender: TObject);
begin
  if self.ReadOnly then
    Exit;

  if (not FVisibleButton) and assigned(fPesquisa.Pesquisa) then
  begin

      ValidatePesquisa;

      fPesquisa.Pesquisa.BackupConfiguration;
      try
        if self.CanFocus then
          self.SetFocus;

        fPesquisa.Pesquisa.SQL.Text := fPesquisa.SQL.Text;
        fPesquisa.Pesquisa.KeyField := fPesquisa.FieldId;
        fPesquisa.Pesquisa.Column   :=
          IfThen(fPesquisa.FieldSearch.IsEmpty, fPesquisa.FieldDisplay, fPesquisa.FieldSearch);

        fPesquisa.Pesquisa.TitlePesquisa :=
          ifthen(self.FieldLabel.IsEmpty, self.EmptyText, self.FieldLabel);
        fPesquisa.Pesquisa.Value         := self.Text;
        fPesquisa.Pesquisa.AOWner        := self.Owner;
        fPesquisa.Pesquisa.ForcePesquisa := True;
        fPesquisa.Pesquisa.TagToUpdate   := self.Tag;

        fPesquisa.Pesquisa.MethodAtualizaComp := PopulateDataFromPesquisa;
        fPesquisa.Pesquisa.Execute;
      finally
        fPesquisa.Pesquisa.RestoreConfiguration;
      end;

  end
  else
  begin
    if Assigned(fOnClickButton) then
      fOnClickButton(Self);
  end;
end;

procedure TPLUniEdit.onPLExit(sender: TObject);
begin
  if Assigned(FOnExit) then
    FOnExit(Sender);

  if fRequired and trim(self.Text).IsEmpty then
    raise Exception.Create(
      ifthen(self.FieldLabel.IsEmpty, self.EmptyText, self.FieldLabel)+' é um campo obrigatório.');

  if (not FVisibleButton) and Assigned(fPesquisa.Pesquisa) then
  begin
    ValidatePesquisa;

    if TEdit(self).Modified then
    begin
      fPesquisa.Pesquisa.BackupConfiguration;
      try
        fPesquisa.Pesquisa.SQL.Text := fPesquisa.SQL.Text;

        fPesquisa.Pesquisa.Value    := self.Text;
        fPesquisa.Pesquisa.AOWner   := self.Owner;
        fPesquisa.Pesquisa.KeyField := getPesquisaFieldId(nil, fPesquisa.FieldId, self);
        fPesquisa.Pesquisa.Column   := IfThen(fPesquisa.FieldSearch.IsEmpty, fPesquisa.FieldDisplay, fPesquisa.FieldSearch);

        fPesquisa.Pesquisa.TagToUpdate := self.Tag;

        fPesquisa.Pesquisa.MethodAtualizaComp := PopulateDataFromPesquisa;

        if not trim(self.Text).IsEmpty then
          fPesquisa.Pesquisa.Execute
        else
        begin
          self.Clear;
          fPesquisa.Pesquisa.LimpaTela;
          PopulateOtherControls(Self, fPesquisa.Pesquisa.ResultDataSet, True);
        end;
      finally
        fPesquisa.Pesquisa.RestoreConfiguration;
      end;
    end;
  end;
end;

procedure TPLUniEdit.PopulateDataFromPesquisa(ReturnDataset: TClientDataset; Clear: Boolean);
var IdFieldName: string;
begin
  // Key Value

  IdFieldName := getPesquisaFieldId(ReturnDataset, fPesquisa.FieldId, self);

  if (not VarIsNull(ReturnDataset.FieldByName(IdFieldName).Value)) and (not Clear) then
    self.KeyValue := ReturnDataset.FieldByName(IdFieldName).Value
  else
    self.KeyValue := '';

  // Display Value

  if not Assigned(ReturnDataset.FindField(self.Pesquisa.FieldDisplay)) then
    raise Exception.Create('O campo da propriedade '+
                            self.Name+'.Pesquisa.FieldDisplay='+self.Pesquisa.FieldDisplay.ToUpper+' não existe no SQL ou na tabela/view em '+
                            self.Name+'.Pesquisa.SQL');

  if (not VarIsNull(ReturnDataset.FieldByName(self.Pesquisa.FieldDisplay).Value)) and (not Clear) and (not KeyValue.IsEmpty) then
    self.Text := ReturnDataset.FieldByName(self.Pesquisa.FieldDisplay).Value
  else
    self.Text := '';

  // Campos configurados para receberem valor além de CHAVE e DISPLAY
  PopulateOtherControls(Self, ReturnDataset, Clear);
end;

procedure TPLUniEdit.PopulateOtherControls(control: TPLUniEdit; ReturnDataset: TClientDataset; Clear: Boolean);
var i: Integer;
    otherControl: TComponent;
begin
  if (control.Pesquisa.OtherFields.Count > 0) then
  begin
    for i := 0 to control.Pesquisa.OtherFields.Count-1 do
    begin
      if (control.Owner <> nil) then
      begin
        otherControl := control.Owner.FindComponent(control.ControlsOtherFields[i]);

        if Assigned(otherControl) and (otherControl is TPLUniEdit) then
        begin
          if Assigned( ReturnDataset.FindField( control.Pesquisa.OtherFields[i] ) ) and (not clear) then
          begin
            if not TPLUniEdit(otherControl).Pesquisa.FieldId.IsEmpty then
              TPLUniEdit(otherControl).KeyValue := VarToStrDef(ReturnDataset.FieldByName(TPLUniEdit(otherControl).Pesquisa.FieldId).Value,'');

            TPLUniEdit(otherControl).Text := VarToStrDef(ReturnDataset.FieldByName(control.Pesquisa.OtherFields[i]).Value,'');

            if control.OtherFieldsRecursive then
               PopulateOtherControls(otherControl as TPLUniEdit, ReturnDataset, Clear);
          end
          else
            TPLUniEdit(otherControl).Clear;
        end;

        if Assigned(otherControl) and (otherControl is TLabel) then
          if not clear then
            TLabel(otherControl).Caption := VarToStrDef(ReturnDataset.FieldByName(control.Pesquisa.OtherFields[i]).Value,'')
          else
            TLabel(otherControl).Caption := EmptyStr;

        if Assigned(otherControl) and (otherControl is TStaticText) then
          if not clear then
            TStaticText(otherControl).Caption := VarToStrDef(ReturnDataset.FieldByName(control.Pesquisa.OtherFields[i]).Value,'')
          else
            TStaticText(otherControl).Caption := EmptyStr;

      end;
    end;
  end;
end;

procedure TPLUniEdit.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
  inherited SetBounds(ALeft, ATop, AWidth, AHeight);

  AutoFit;
end;

procedure TPLUniEdit.SetControlsOtherFields(const Value: TStrings);
var i: Integer;
begin
  FControlsOtherFields.Assign( Value );

  for i := (FControlsOtherFields.Count-1) downto 0 do
  begin
    if Trim(FControlsOtherFields[i]).IsEmpty then
      FControlsOtherFields.Delete(i);
  end;
end;

procedure TPLUniEdit.setCtl3D(const Value: boolean);
begin
  inherited Ctl3D := Value;
  AutoFit;
end;

procedure TPLUniEdit.setKeyValue(const Value: string);
begin
  fKeyValue := Value;

  if Assigned(FOnKeyValueChange) then
  begin
    if (not fKeyValue.IsEmpty) then
      FOnKeyValueChange(Self,fKeyValue)
    else
      FOnKeyValueChange(Self,Null);
  end;
end;

procedure TPLUniEdit.setLeft(const Value: integer);
begin
  inherited Left := Value;
  AutoFit;
end;

procedure TPLUniEdit.SetOnKeyValueChange(const Value: TPLUniEditKeyValueChange);
begin
  FOnKeyValueChange := Value;
end;

procedure TPLUniEdit.SetParent(AParent: TWinControl);
begin
  inherited SetParent(AParent);

  if assigned(FBtn) then
    FBtn.Parent := AParent;
    
end;

procedure TPLUniEdit.setPesquisa(sender: TObject);
begin
  if Assigned(fPesquisa.Pesquisa) then
    self.VisibleButton := False;

  FBtn.Visible := self.Visible and assigned(fPesquisa.Pesquisa);

  SetupInternalButton;
  self.AutoFit;
end;

procedure TPLUniEdit.setTop(const Value: integer);
begin
  inherited Top := Value;
  AutoFit;
end;

procedure TPLUniEdit.SetupInternalButton;
begin
  if not Assigned(FBtn)then
    FBtn := TPlUniSeekButton.Create(Self);

  FBtn.FreeNotification( Self );
  FBtn.Cursor   := crArrow;
  FBtn.AutoSize := True;
  FBtn.Visible  := Visible and (assigned(fPesquisa.Pesquisa) or FVisibleButton);

  if Assigned(fPesquisa.Pesquisa) then
  begin
    FBtn.OnClick := OnClickBtn;
  end;

//    FBtn.ClientEvents.ExtEvents.Values['click'] :=
//    'function click(sender, e, eOpts) '+
//    '{                                           '+
//    '  ajaxRequest(sender, ''customEvent'',      '+
//    '               {                            '+
//    '                  name: sender.text,        '+
//    '                  width: sender.getWidth()  '+
//    '               }                            '+
//    '             );                             '+
//    '}';
 // end;

  RecreateWnd;
end;

procedure TPLUniEdit.setWidth(const Value: integer);
begin
  inherited Width := Value;
  AutoFit;
end;

procedure TPLUniEdit.ValidatePesquisa;
begin
  if fPesquisa.Pesquisa.Working then
    abort;

  if fPesquisa.SQL.Count = 0 then
    raise Exception.Create(self.Name+'.Pesquisa.SQL precisa ter um SQL');

  if fPesquisa.FieldId.IsEmpty then
    raise Exception.Create(self.Name+'.Pesquisa.FieldId precisa de um campo configurado');

  if fPesquisa.FieldDisplay.IsEmpty then
    raise Exception.Create(self.Name+'.Pesquisa.FieldDisplay precisa de um campo configurado');
end;

procedure TPLUniEdit.SetName(const Value: TComponentName);
begin

  inherited SetName(Value);

  if csDesigning in ComponentState then
    Text := '';
end;


procedure TPLUniEdit.SetVisibleButton(const Value: Boolean);
begin
  FVisibleButton := Value;

  if Assigned(fPesquisa.Pesquisa) and FVisibleButton then
    fPesquisa.Pesquisa := nil;

  FBtn.Visible := (self.Visible and FVisibleButton);

  AutoFit;
end;

end.

 

 

 

And code of the internal button is here:

unit PLUniSeekButton;

interface

uses
  SysUtils, Classes, Controls, Buttons, Messages, Windows, Forms, Graphics,
  uniSpeedButton;

type
  TPLUniSeekButton = class(TUniSpeedButton)
  public
    procedure Loaded; override;
    constructor Create( AOWner : TComponent ); override;
  published
    property AutoSize;
  end;

implementation


constructor TPLUniSeekButton.Create(AOWner: TComponent);
begin
  inherited Create(AOWner);
  Name := AOWner.Name+'SubButton';
  SetSubComponent(True);
  Hint := 'Pesquisar <F2>';
  Height := 0;
  Width := 0;
  caption := '...';
end;

procedure TPLUniSeekButton.Loaded;
begin
  inherited;
  Name := Self.Owner.Name+'SubButton';

  if (self.Hint = '') then
    self.Hint := 'Pesquisar <F2>';

  caption := '...';
end;

end.

Thanks for any help!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...