Jump to content

ClientEvents.ExtEvents not fire if added in runtime mode (if control is also created at runtime)


Pep

Recommended Posts

Hello everyone,

When creates a control (ex: uniEdit) in runtime mode and then adds "ClientEvents.ExtEvents" this events don't fire

but If I add the same event in runtime mode but in a control created at design time then fires ok.

Exemple:
 

procedure TMainForm.UniFormCreate(Sender: TObject);

  const after_render_Event = 'afterrender=function afterrender(sender, eOpts)  {  sender.allowBlank = false;}';

begin

  //Works ok
  //************
  // UniEdit Control (Created in Design mode)
  // Add client event in runtime fires ok
  UniEdit1.ClientEvents.ExtEvents.Add(after_render_Event);


  //No Works!!!!!!!!!!
  //*******************
  // UniEdit Control (Created at Rumtime time)
  FRunTimeUniEdit := TUniEdit(InsertControl(TUniEdit.Create(Self)));
  with FRunTimeUniEdit do
  begin
    Left := 72;
    Top := 122;
    Width := 200;
    // Add the same client event in runtime mode not fires
    ClientEvents.ExtEvents.Add(after_render_Event);
  end;
end;

Someone knows why this happens?

Thank you.

 

Sample.jpg

Link to comment
Share on other sites

Hello,

Assign a name to the new creating component

  with FRunTimeUniEdit do
  begin
    Left := 72;
    Top := 122;
    Width := 200;
    Name := 'NewName';  //<----------------
    // Add the same client event in runtime mode not fires
    ClientEvents.ExtEvents.Add(after_render_Event);
  end;

 

  • Like 1
Link to comment
Share on other sites

  • 4 years later...

Hey @Sherzod

I have a similar problem. The differences are that i use component created dynamically in clientEvents of another component :

 

var
  xLabel : TUnimLabel;
begin

  xLabel := TUnimLabel.Create(Form);
  xLabel.Parent := _panel;
  xLabel.Caption := 'TTTTTTTTTTTTTTTTTTTT';
  xLabel.LayoutConfig.Margin := '100 0 0 0';
  xLabel.Left := 0;
  xLabel.top := 30;
  xLabel.Visible := True;
  xLabel.Name := 'Labeltest';//+inttostr(DateTimeToUnix(now));

  _panel.ClientEvents.UniEvents.Values['afterCreate'] :=
      'function afterCreate(sender)'
      +'{'
      +' FormName.Labeltest.getTop();'  <<------------ error here
      +'}';

In getTop() line i get : Cannot read properties of undefined (reading 'getTop');

if i add this label in design then it works.

Can you help me ?

 

I'm using: uniGUI Complete -Professional Edition Build 1.90.0.1568

Link to comment
Share on other sites

1 hour ago, PS1 said:

test_case.zip 108.91 kB · 0 downloads

Thanks.

1 hour ago, PS1 said:

In getTop() line i get : Cannot read properties of undefined (reading 'getTop');

if i add this label in design then it works.

Yes, because this component hasn't been created yet.

Why exactly would you use event afterCreate?

Link to comment
Share on other sites

To create part of ,,Refresh page" functionality in mobile pages(but i refresh only datasets) :

In quick words i create bunch of listeners to get tap movement and show label(with is spinner icon). if user will swipe some distance i refresh page and hide this label.

,,Painted" function used instead of create in below code doesn't execute.

 

  _panel.ClientEvents.UniEvents.Values['afterCreate'] :=
  'function afterCreate(sender)'
  +'{'
  +'    '
  +'   let clientY;'
  +'   let start_top;'
  +'   let new_top;'
  +'   let can_start = true;'
  +'   let is_at_top = true;'
  +'   let curr_touch_move;'
  +'   let label = '+_panel.Owner.Name+'.Labeltest;'

  +'   function sleep (time) {'
  +'      return new Promise((resolve) => setTimeout(resolve, time));'
  +'   };  '
  +'   '

  +'   let scroller = sender.getScrollable();'
  +'   if (scroller) {'
  +'      scroller.on(''scroll'', function(a, b, c) {'
  +'         if (c == 0)  { is_at_top = true;console.log("is_at_top");}'
  +'         else { is_at_top = false }'
  +'      })'
  +'   };'
  +'   '
  +'   sender.el.addListener(''touchstart'', function(e) {'
  +'      if (is_at_top) {'
  +'         can_start = true;'
  +'         start_top = sender.el.getTop();'
  +'         clientY = e.touches[0].pageY;'
  +'         label.setTop(-60);'
  +'      } else {'
  +'         can_start = false;'
  +'      }'
  +'   });  '
  +'   '
  +'   sender.el.addListener(''touchmove'', function(e) {'
  +'      curr_touch_move = e.touches[0].pageY - clientY; '
  +'      if ((can_start) && (curr_touch_move > 0)) {'
  +'      '
  +'         new_top = start_top+curr_touch_move;  '
  +'               '
  +'         if ( label.getTop() < 50 ) {'
  +'            label.setTop(-60 + curr_touch_move/1.5);      '
  +'         }'
  +'      };      '
  +'   });'
  +'   '

  +'   sender.el.addListener(''touchend'', function(e) {'
  +'      if ( label.getTop() >= 50 ) {'
  +'     '
  +'         sleep(300).then(() => {'
  +'            ajaxRequest(sender, "Refresh", []);'
  +'            can_start = true;'
  +'         });   '
  +'         '
  +'      } else {'
  +'         label.setTop(-60);'
  +'      }'

  +'   });      '


  +'}';

Link to comment
Share on other sites

Bingo !

Now it works, Thanks a lot !!

 

But i have another problem i want to assign OnAjaxEvent to the _panel. But i don't want create this function in a class. I want to create it in another unit as simple procedure without any class.

some thing like this:


procedure CreateRefreshFunc(var _panel : TUnimPanel);
var

  procedure Panel_AjaxEvent(Sender: TComponent;
    EventName: string; Params: TUniStrings);
  begin
     //some code
  end;

begin
  _panel.OnAjaxEvent := Panel_AjaxEvent;
end;

 

but i got error : Incompatible types: 'method pointer and regular proedure'

in normal event like onClick (which has only 1 parameter(sender:TObject)) i could use:

var

  ANotifyEvent : procedure of object;

  procedure Panel_OnClick(ASelf: TObject; Sender: TObject);
  begin
     //some code
  end;

begin

  TMethod(ANotifyEvent).Code := @OnClick;
  TMethod(ANotifyEvent).Data := Pointer(_panel);
  _panel.OnClick := ANotifyEvent;

end;

Link to comment
Share on other sites

I can't, i need to make it universal so all forms could use it and i want to change code of it in runtime.

Or maybe is it possible to run procedure(written in delphi) from javascript in ClientEvents, without using onAjaxEvent ?

i need to call refresh function from it.

 

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...