Skip to content

Forms

In TMS WEB Core, the base class for forms is TWebForm.TWebForm is similar to a TForm in the VCL. Controls can be put at design time on the TWebForm and will be displayed. The TWebForm is by default displayed as a full page in the browser. In addition to the controls that the form hosts that are created at design-time or at runtime, there is also the HTML code associated with the form. This HTML can be an empty HTML BODY when all controls are created by Delphi classes or it can contain additional HTML elements or HTML elements to which Delphi classes are mapped.

The default project looks like:

and you see under unit1.pas not only a reference to the DFM file where Delphi class properties are stored but also the HTML file associated with the form in Unit1. The default HTML for this form can be opened & edited from the Delphi IDE but can also be ‘designed' by any other tool for creating HTML files. The default content of the HTML file is:

In the default HTML files, the BODY is empty and the controls defined in Delphi will be put in the BODY upon creation of the form instance. The application creates the main form in the same way as in a VCL application, i.e. with the code:

Application.CreateForm(TForm1, Form1);

It is also possible that the Delphi controls will be created within another HTML element than the HTML BODY element.

If unit1.html contains:

we can specify at form class level Form.FormContainer: string and set this to the HTML element ID of the HTML element in which the form should be rendered, i.e. in this case it could be set to “form”.

Alternatively, there are also forms in the project that have not HTML template file. These are added to the project via the IDE wizard and selecting TMS WEB Direct Form:

This appears in the project manager as:

The big difference here is that when the application opens this form via

Application.CreateForm(TForm1, Form1);
no additional HTML file needs to be loaded and the form will use the HTML as specified in the application HTML file. This type forms as such loads faster. It does not need a server to return the form specific HTML file (meaning such project can also be directly started by double-clicking the application HTML file from Windows Explorer). If you want to use HTML elements linked to form controls, these HTML elements will need to be present in the main application HTML file. As such, when wanting to use this type direct form for applications with multiple forms, it will require a different application management code to handle the HTML file ( possibly programmatically).

Creating forms at runtime

Due to the asynchronous behaviour of loading the HTML for a form, the creation of a form in code is slightly different in the web than in VCL. To create a form, following code can be used:

procedure TForm1.WebButton1Click(Sender: TObject);
var
  newform: TForm2;

  // async called when the form is closed (via form.Close method where
ModalResult can be set)
  procedure AfterShowModal(AValue: TModalResult);
  begin
    ShowMessage('Form 2 closed with new value:'+newform.frm2Edit.Text);
    WebEdit1.Text := newform.frm2Edit.Text;
  end;

  // async called OnCreate for TForm2
  procedure AfterCreate(AForm: TObject);
  begin
    (AForm as TForm2).frm2Edit.Text := WebEdit1.Text;
  end;

begin
  newform := TForm2.CreateNew(@AfterCreate);
  newform.ShowModal(@AfterShowModal);
end;

An alternative way to create forms is using equivalent functions that use promises. With this approach, code can be written as if it is sequential but still, in execution it is asynchronous. The equivalent code to create a form using promises and await() is

procedure TForm1.WebButton1Click(Sender: TObject);
var
  newform: TForm2;
begin
  newform := TForm2.Create(Self);

  // load file HTML template + controls await(TForm2, newform.Load());
  // init control after loading newform.frm2Edit.Text := WebEdit1.Text;

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

Note that there is one additional important difference to make the promise/await based approach work, and that is to make the form method WebButton1Click as async. This can be done via an attribute:

TForm1 = class(TWebForm)
  [async]
  procedure WebButton1Click(Sender: TObject);
end;
By default, the new form TForm2 will replace the page showing the actual form. When this form is closed, the original form from where TForm2 is shown, will be displayed in the browser page again. The procedure AfterCreate is shown when the HTML for TForm2 is loaded and its controls are created. The ShowModal() method will display the actual form in the browser page and a reference to the method that will be called when the form is closed can be passed as parameter as ShowModal is not a blocking method, as such blocking methods are not possible in a browser environment.

In addition to forms displayed in the full browser page, it is also possible to create popup forms. These forms will be displayed on top of other forms, effectively disabling the forms on top of which the new form is displayed till this new form is closed. To display a form as popup, all that is needed is setting form.Popup = true.

Example:

begin
newform := TForm2.CreateNew(@AfterCreate);
 newform.Popup := true;
 newform.PopupOpacity := 0.2; // only needed when main form should
                              // remain visible under a layer with
                              // opacity
  newform.ShowModal(@AfterShowModal);
end;

For popup forms, 2 more settings are relevant.

The popup form can have a caption or not. When the popup form has a caption, the user will be able ot move the popup form on the screen via the caption. The caption of the form is set via WebForm.Caption: string;

The popup form can be resizable (on desktop browsers) via a resizer area in the bottom-right corner of the form.

These extra form settings are done via the TWebForm.Border property:

WebForm.Border setting Description
fbDialogSizeable Popup form has caption and can be sized
fbDialog Popup form has caption and has a fixed size
fbSingle Not sizeable form, no caption

Hosting forms in other controls

Finally, it is also possible to embed other forms in controls or HTML elements in other forms. To do so, create the form with overloads of the CreateForm method of the Application object or via the CreateNew constructor overload of TWebForm:

Via the TApplication object:

    procedure CreateForm(AInstanceClass: TWebFormClass; AElementID: string; var AReference); overload;

    procedure CreateForm(AInstanceClass: TWebFormClass; AElementID: string; var AReference; AProc: TFormCreatedProc); overload;

The AInstanceClass is the class type of the form to be created. The AElementID is the ID of the HTML element (or Delphi class control ID) that is the HTML container in which the form will be created. The AReference is a reference to the form instance that will be created and optionally a referene to a procedure that will be called when the form was effectively created can be passed.

Via the TWebForm CreateNew overload:

constructor TWebForm.CreateNew(AElementID: string; AProc: TFormCreatedProc);

The AElementID is the ID of the HTML element (or Delphi class control ID) that is the HTML container in which the form will be created. Optionally a method can be passed that will be called when the form was created.

Example code:

In this sample code, a new form of the type TSubForm is created. The form will be displayed inside a panel on the form as we use the panel's HTML element ID. When the form is created, and this all controls on the form are accessible, the AfterCreate() procedure is called.

Overview of TWebForm properties, methods, events:

Properties

Property Description
ActiveControl: TCustomControl Get and set the focused/active control on the form
Caption: string Sets the form caption. For a regular form, this is the browser title text, for a popup form, this is the text in the form caption area
CaptionElement: TJSHTMLElement Read-only property giving access to the HTML element used for the form caption
Color Sets the background color of the form
CSSLibrary: TCSSLibrary Can be:
- cssNone
- cssBootstrap
Selects between using a default Bootstrap CSS library use for the form or no default CSS library. When CSSLibrary is set to cssBootstrap, adding new controls at design-time on the form, will automatically preset the control’s ElementClassName property to the best matching Bootstrap class for the control.
ElementCaptionClasssName CSS class for the form caption DIV element, allows to use CSS to customize the caption element
FormContainer: TElementID Sets the ID of the HTML element in the form HTML template serving as the container of the entire form
FormFileName: string Holds the filename of the HTML template for the form. By default this is the unit name with extension .HTML
FormStyle: TFormStyle Unused property for backwards compatibility with VCL forms
Menu: TCustomControl Sets the main menu for the form
ModalResult: TModalResult Holds the modal result when the form closes
Popup: Boolean When true, the form will be shown as popup dialog over the parent form, otherwise it will be displayed in the entire browser window.
PopupOpacity: single Sets the opacity of the layer making the parent form UI elements inaccessible while a popup form is shown
ShowClose: Boolean When true, a close button is shown in the caption right corner of a form displayed as popup form
Shadow: boolean When true, the popup form is shown with a shadow border over the parent form

Methods

Method Description
AddCSS(const id: string; const CSS: string); A Adds new CSS code to the form. The CSS code is added in the STYLE section of the document with given id.
Close Closes the form
Execute: TJSPromise Async method called to show a form modally, waiting for it to be closed
Load: TJSPromise Async method loading the form HTML template
RemoveCSS(id: string); Removes the CSS style element with id
SelectFirst Sets focus to the first element on the form
SelectNext(CurControl: TControl; GoForward: Boolean = true) Sets the focus to the next element on the form (or previous element when GoForward = false)
ShowModal(AProc: TModalResultProc = nil) Shows a form modally and calls the anonymous method returning the modal result when the form is closed
UpdateCSS(const id: string; const CSS: string) Updates the CSS style information for CSS style element id.

Events

Event Description
OnClick: TClickEvent Event triggered when the form is clicked
OnClose: TCloseEvent Event triggered when the form is closed
OnCloseQuery: TCloseQueryEvent Event triggered just before the form is about the be closed. Can be used to prevent actual closing of the form via the CanClose parameter
OnCreate: TNotifyEvent Event triggered when the form instance was created
OnDestroy: TNotifyEvent Event triggered when the form is destroyed
OnDeactivate: TNotifyEvent
OnDblClick: TNotifyEvent Event triggered when the form is doubleclicked
On DOMContentLoaded Event triggered when the form’s HTML template fully finished loading in the browser DOM
OnHashChange: THashChangeEvent Event triggered when the browser navigation hash changed
OnOrientationChange: TOrientationChangeEvent Event triggered when the page orientation changed, typically happening on a mobile device
OnPaint: TOnPaintEvent Event added for compatibility with a VCL form
OnResize: TNotifyEvent Event triggered when the form resizes due to the browser window being resized
OnScroll: TNotifyEvent Event triggered when there is scrolling of the form in the browser window
OnShow: TNotifyEvent Event triggered when the form is shown
OnUnload: TNotifyEvent Event triggered when the browser unloaded the HTML associated with the form

Form inheritance

Just like in a Delphi VCL application, TMS WEB Core web client applications can also work with the concept of visual form inheritance. This means that a TWebForm can be created, UI controls and UI control logic can be applied to this form and then a form descending from this base form class can be created. The difference with a VCL application form is that for a TWebForm, there is also an associated HTML template. As each form has a HTML template, when creating a new descending form, a new HTML template will be created. Note that for a descending form, the HTML template belonging to the descending form will be used to render the form rather than the HTML template belonging to the base form.

The process to create a descending form is done from the context menu in the Delphi IDE project manager:

Frames

In a TMS WEB Core application, the concept for frames can also be used. Frames can encapsulate specific UI control logic in combination with UI controls. A frame in a TMS WEB Core application has no associated HTML template. The template of the form hosting the frame is used. To create a new frame, follow the same steps as for adding a new VCL frame. After the frame is added to the project, TMS WEB Core components can be dropped on the frame and the UI control logic can be written in the frame unit. Then, to use the frame, enter ‘Frames’ on the object inspector and select the frame you want to add to a form from the frames list