WebForm OnCreate potential bug

Hello,

I believe I have found a bug with the OnCreate routine.

Given the following example:

type
  TForm1 = class(TWebForm)
    WebHTMLDiv1: TWebHTMLDiv;
    WebHTMLDiv2: TWebHTMLDiv;
    WebHTMLDiv3: TWebHTMLDiv;
    WebHTMLDiv4: TWebHTMLDiv;
    [async] procedure WebFormShow(Sender: TObject);
  private
    { Private declarations }
    f2:TForm2;
    f3:TForm3;
    f4:TForm4;
    f5:TForm5;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.WebFormShow(Sender: TObject);
begin
  f2:=TForm2.CreateNew(WebHTMLDiv1.ElementID, nil);
  await(TForm2, f2.Load);

  f3:=TForm3.CreateNew(WebHTMLDiv2.ElementID, nil);
  await(TForm3, f3.Load);

  f4:=TForm4.CreateNew(WebHTMLDiv3.ElementID, nil);
  await(TForm4, f4.Load);

  f5:=TForm5.CreateNew(WebHTMLDiv4.ElementID, nil);
  await(TForm5, f5.Load);
end;

Where each WebForm has the OnCreate routine:

procedure WebFormCreate(Sender: TObject);
begin
writeln(Self.ClassName+' created.');
end;

The behaviour is as expected except for the last object, where the TForm5 OnCreate will fire as many times as there are other extant WebForms.

This behaviour will occur with whichever WebForm is created last.

I'm not sure why you added the call await(TFormX, fX.Load);
I have modified the demo under Demo\Basics\FormHosting to mimic this setup with 2 forms and added an extra panel where to host the 2nd created form.

The code to create the forms in the panels;:

procedure TFrmMain.btCreateSubF2Click(Sender: TObject);
begin
  frm1 :=  TSubForm1.CreateNew(WebPanel1.ElementID, nil);
end;

procedure TFrmMain.btCreateSubF2Click(Sender: TObject);
begin
  frm2 :=  TSubForm2.CreateNew(WebPanel1.ElementID, nil);
end;

and I couldn't see anything wrong with the OnCreate event handler set for both forms:

procedure TSubForm1.WebFormCreate(Sender: TObject);
begin
  console.log(Self.ClassName+' created.');
end;

procedure TSubForm2.WebFormCreate(Sender: TObject);
begin
  console.log(Self.ClassName+' created.');
end;

So, please use the technique as demonstrated in this demo.

Hi Bruno,

Thanks for the reply.

I am aware of using callbacks as you have described (that's what I'm currently doing).
I heavily dislike using callbacks to achieve this as I find it makes code harder to read and maintain.

I saw an old topic from years ago where the idea of an async CreateNew was mentioned. Could this be a possibility in the future?

If you do not want to use callbacks, modifying the code in the demo Demo\Basics\MultiForm to show the created form in a WebPanel1 on the form becomes:

var
  newform: TForm2;

begin
  newform := TForm2.Create(WebPanel1.ElementID);
  TAwait.ExecP<TForm2>(newform.Load());

  // init control after loading
  newform.frm2Edit.Text := WebEdit1.Text;

  try
    // excute form and wait for close
    TAwait.ExecP<TModalResult>(newform.Execute);
    ShowMessage('Form 2 closed with new value:"'+newform.frm2Edit.Text+'"');
    WebEdit1.Text := newform.frm2Edit.Text;
  finally
    newform.Free;
  end;
end;

so, here you can further modify the created form after the await() on the async load function.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.