TWebForm.Parent don't work in this case

I have some forms that I show inside a TWebHTMLDiv.
But If use the following technique for create and show forms, Parent is ignored.
Example:
...
frm := TForm1.Create(self);
// procedures to execute before form loading
frm.Popup := false;
await(TForm1, frm.Load());
// procedures to execute after form loading
frm.Parent := WebHTMLDiv1;
try
await(frm.Execute);
// procedures to execute after form close
finally
frm.Free;
end;

How to solve?

Ps.: (I don't want use CreateNew() because this case permits to launch the procedures between the creation, the show and the release of the forms).
Thanks!

With this particular order, it is indeed not currently supported.
We'll further investigate and consider this for a future version.

Thanks Bruno.
I will try to be clearer though.
By implementing this feature or simply correcting it (Form.parent=xxx) you maintain a very convenient and intuitive "procedural" approach, avoiding the use of callbacks. The code is thus more readable and easier to implement, thanks to "await".
The forms that we already use with this approach (but which are popups) are perfect, and above all appear...fast. So just extend it to the forms with the parent to be able to use it everywhere, perhaps adding a "variant" Form.Create(parent).

But the main reason for my request is this:

If I use CreateNew() I can manage the data, via parameters in callbacks, only after the form has been created and displayed (@AfterCreate). So I get the form displayed in 2 shots, first the form is showed... and then the data arrives. This is not a nice effect, especially with slow connections.
Instead, with the system mentioned above, I can manage all the necessary phases BEFORE the form is visible, with a nice instant display effect.
I hope I was clear, otherwise I'll make a demo :-)
Thanks

As I mentioned, we'll investigate what we can do in the future.

Is there any update on potential improvements?

It would be extremely helpful to have a consistent creation method for all types of forms: standard, popups, container‑based and so on. A unified approach would make it much easier to build repeatable structures that behave predictably.

Right now, I have to check how the form was created in order to know when it’s safe to call certain procedures. When using the CreateNew() method, there doesn’t seem to be any way to run code inside the newly created form before it’s displayed, which forces these extra checks.

To further explain the "issue", here's an example:

IN PARENT FORM:
Popup Creation

[...]
   frm :=   TChildForm.Create(self);
   // This is a call to the server 
   // ( I have to wait for this before displaying the form )
   await((frm as TChildForm).CreateParam;
   frm.Popup := true;
   frm.Border := fbDialogSizeable;
   frm.PopupOpacity:= 0.2;
   TAwait.ExecP<TChildForm>(frm.Load());
   try
   TAwait.ExecP<TModalResult>(frm.Execute);
   await(TModalResult, frm.Execute);
   finally
[...]

Creation inside a container

[async] procedure AfterCreate(AForm:TObject);
begin
await((AForm as TChildForm).CreateParam;
end;

begin
[...]
if assigned(frm) then
   frm.free;
frm := TChildForm.CreateNew(myFormContainer.ElementID, @AfterCreate);
[...]

Since for the creation inside a container/normal creation there's no way to launch a procedure of the child form before it's created, I'm forced to run checks like this:

IN CHILD FORM:


procedure TChildForm.WebFormShow(Sender: TObject);
begin
if self.Popup then
   customProcedure;
end;

procedure TChildForm.CreateParam;
begin
await(callServer);

if self.Popup = false then
   customProcedure;
end;

We have been working on this and have an experimental version for allowing form parent change in this creation sequence. Next update will have this adaption.

I arn not sure whether or not the feature has been implemented but I have encountered an issue in this creation sequence:

procedure TMainFrm.btnCreateClick(Sender: TObject);
begin
if Assigned(frm) then
   frm.free;

frm := TChildFrm.Create(Self)
frm.Popup := false;
frm.Border := fbNone;

await(TChildFrm, frm.Load());

// I HAVE ALSO TRIED DOING THIS BEFORE .LOAD
frm.Parent := destDiv;

   try
   {$IFDEF PAS2JS}
   await(TModalResult, frm.Execute);
   {$ENDIF}
   finally
   console.log('Out of child form');
   frm.Free;
   end;
end;

When assigning .Parent, the <body> of the page takes the id of TChildFrm and results in the following error:
Uncaught HierarchyRequestError: Failed to execute 'appendChild' on 'Node': The
new child element contains the parent.

When you want to map a form on a HTML element instead of a control, you cannot use form.Parent. The HTML element is not a control, hence, it can't be used to set the parent.

The demo under Demo\Basics\FormHosting, shows how you can use the HTML element ID to map a control on this element via passing its ID in the form constructor.

I should have specified that the destDiv element is a TWebHTMLDiv. Even though it is ultimately an HTML element, the class inherits from TControl; shouldn't that mean it would work?

With a TWebHTMLDiv I would expect it to work.
Alternatively, try the approach as demonstrated in the Demo\Basics\FormHosting sample

I expected it to work too, but as I mentioned above, it does not. I have used the approach demonstrated in the FormHosting demo, but as I explained in post #6, there are a few significant inconveniences with that method:

  • UI Flickering: With CreateNew, the form is injected into the DOM immediately. This means the user sees an empty or half-loaded form before the AfterCreate data arrives. Using the Create + await Load approach allows us to prepare the data before the form is visible, creating a much smoother "instant" display which in the other way would only be possible by manually hiding the form and then making it visible after the data is loaded.

  • Logic Pollution: We are forced to add conditional checks like if self.Popup then... inside the Child Form’s logic. The child form shouldn't need to know how it was created; it breaks encapsulation and makes the code harder to maintain.

  • Async Inconsistency: Mixing the await pattern with the older @AfterCreate callback pattern makes the codebase inconsistent and harder to debug compared to a unified async/await flow for all form types.

I am not sure if implementing this method of creation is actually achievable, so in the meantime, I am using a workaround. However, a unified approach for standard, popup, and container-based forms would be a huge improvement.

A possible alternative is to load the form into an element that has a hidden attribute and make it visible once all data of the form is loaded?