TMS WEB Core v1.0 Brescia tips & tricks part 2

Bookmarks: 

Tuesday, August 21, 2018



Even though it is summer & vacation time for many, we make time for two more super useful tips & tricks for everyone developing web client applications with TMS WEB Core.

Inserting controls as child of HTML elements

The first tip concerns dynamically creating a web control as child of an existing HTML element. Normally in a VCL application, when you create a new control, a Delphi developer typically adds the control as child control of a form or container control by setting the Control.Parent property. In a TMS WEB Core application, you can do exactly the same. This code snippet inserts a button in a panel:
var
  btn: TWebButton;

begin
  btn := TWebButton.Create(WebPanel1);
  btn.Parent:= WebPanel1;
  btn.OnClick := myClickHandler;
end;
Every seasoned Delphi developer immediately sees that this is 100% identical to what one would do a in VCL Windows application.
But in a TMS WEB Core application, a web page can not only consist of TMS WEB Core web controls, it can also involve HTML elements from a HTML template or HTML elements that are just part of a more complex TMS WEB Core web control. So, what if we wanted to insert a web control that is a child of a HTML element? TWebControl.Parent is of the type TControl and a HTML element on the page is of the type TJSElement, so clearly, we cannot use the control.Parent property.
TMS WEB Core however comes with an easy and intuitive solution. Other than control.Parent, every web control has a second property control.ParentElement: TJSElement. With this property we can as such make a web control a child of any HTML element.

We will apply this technique to dynamically insert badges in a column of a table, represented by the TWebTableControl. The TWebTableControl is a wrapper around the HTML table and as such it consists of TR and TD HTML elements. The TD element of a table cell is conveniently accessible via WebTableControl.CellElements[Col, Row]: TJSElement. But when we load JSON data in a TWebTableControl, while the table is built-up and the HTML elements are created, TWebTableControl fires the OnGetCellChildren event with event signature:
procedure TForm1.WebTableControl1GetCellChildren(Sender: TObject; ACol,
  ARow: Integer; AField: TField; AValue: string; AElement: TJSHTMLElement);
begin

end;
It returns the column, row, possibly a DB field (when used in the DB-bound TWebDBTableControl), the cell value and AElement which is the HTML TD element of the table cell and exactly what we need to insert a new control into a table cell.

As such, we can write:
procedure TForm1.WebTableControl1GetCellChildren(Sender: TObject; ACol,
  ARow: Integer; AField: TField; AValue: string; AElement: TJSHTMLElement);
var
  badge: TWebBadge;
begin
  if (ACol = 2) and (ARow > 0) then
  begin
    badge := TWebBadge.Create(Self);
    badge.Text := AValue;
    badge.ElementFont:= efCSS;
    badge.ElementClassName := 'badge badge-success badge-pill';
    AElement.innerHTML:= '';
    badge.ParentElement := AElement;
  end;
end;
The result for a TWebTableControl loading JSON via WebTableControl.LoadFromJSON() is :



Using the versatile HTML lists

The HTML list element UL with list items LI is an extremely versatile HTML element, especially when it is in the hands of CSS (like Bootstrap) to transforms such lists into all kinds of magic. With the TWebListControl, TMS WEB Core offers a convenient class to manage such lists. TWebListControl exposes a TListItem collection. What is nice is that the TListItem class has in turn an Items: TListItems collection that can hold sub items etc... When not using CSS, the TWebListControl is used in the following way:
TWebListControl.Items.Add.Text := 'Item 1';
TWebListControl.Items.Add.Text := 'Item 2';
TWebListControl.Items.Add.Text := 'Item 3';
and it results in:

  • Item 1
  • Item 2
  • Item 3

Now, let's unleash the power of CSS, in particular Bootstrap here to magically transform such list control in all kinds of nice web UI. First add the Bootstrap library references to your project with the JavaScript Library manager. To do this, right-click the project in the Delphi IDE project manager and select "Manage JavaScript Libraries" and activate Bootstrap 4.1.1 as well as jQuery 3.3.1. Now we can start exploring how the strength of Bootstrap can be applied to the TWebListControl:

Breadcrumb  https://getbootstrap.com/docs/4.1/components/breadcrumb/


To show a breadcrumb, we set WebListControl.Style := lsBreadcrumb and then add items:
procedure TForm1.WebButton2Click(Sender: TObject);
begin
  WebListControl1.Style := lsBreadcrumb;
  WebListControl1.Items.Add.Text := 'Main';
  WebListControl1.Items.Add.Text := 'Products';
  WebListControl1.Items.Add.Text := 'Software';
  WebListControl1.Items.Add.Text := 'Web development';
  WebListControl1.Items.Add.Text := 'TMS WEB Core';
end;
Thanks to the Bootstrap styling, this results in:

Pagination  https://getbootstrap.com/docs/4.1/components/pagination/

The pagination style turns a list of items into a row of selectable link blocks. The code to create an example list is:
procedure TForm1.WebButton2Click(Sender: TObject);
begin
  WebListControl1.Style := lsPagination;
  WebListControl1.Items.Add.Text := 'Customers';
  WebListControl1.Items.Add.Text := 'Products';
  WebListControl1.Items.Add.Text := 'Orders';
  WebListControl1.Items.Add.Text := 'Stock';
  WebListControl1.Items[0].Active := true;
end;
In the browser, this looks like:

Tabs  https://getbootstrap.com/docs/4.0/components/navs/

The tabs style turns a list of items into a row of tabs. The code to create an example list is exactly the same as for pagination except the style is set to lsTabs:
procedure TForm1.WebButton2Click(Sender: TObject);
begin
  WebListControl1.Style := lsTabs;
  WebListControl1.Items.Add.Text := 'Customers';
  WebListControl1.Items.Add.Text := 'Products';
  WebListControl1.Items.Add.Text := 'Orders';
  WebListControl1.Items.Add.Text := 'Stock';
  WebListControl1.Items[0].Active := true;
end;
With just one property changed, the list now becomes:

List-Group  https://getbootstrap.com/docs/4.0/components/list-group/

Bootstrap defines the 'List-Group' and 'List-Group-Item' CSS class. We set the 'List-Group' CSS class name to TWebListControl.ElementListClassName. Then for each TListItem, set TListItem.ItemClassName := 'List-Group-Item'. The result becomes


The List-Group has a few extra cool features. Let's introduce some sub items, conveniently inserted in Pascal code with listitem.Items.Add. Here we also use the Bootstrap's collapse feature https://getbootstrap.com/docs/4.0/components/collapse/ In the list group, this means that with the collapse feature, the item having sub items can collapse or expand the list of sub items. For the TWebListControl TListItem, this is enabled per item with the AutoCollaps boolean property. In the list group we can further set items as active items to make these appear highlighted. And as finishing touch, let's add some badge controls introduced in the first tip for the subitems.We set the parent HTML element of the badge control to the list control item HTML element, exposed via ListItem.ListElement.
Putting everything together, the code becomes:

var
procedure TForm1.WebButton3Click(Sender: TObject);
var
  li: TListItem;
  badge: TWebBadge;
  i: integer;
begin
  WebListControl1.Style := lsListGroup;
  WebListControl1.DefaultItemLinkClassName := '';
  WebListControl1.DefaultItemClassName := 'list-group-item list-group-item-action  d-flex justify-content-between align-items-center';

  li := WebListControl1.Items.Add;
  li.Text := 'Mercedes';
  li.Active := true;
  li.AutoCollaps := true;
  li.Items.Add.Text := 'S class';
  li.Items.Add.Text := 'SL class';
  li.Items.Add.Text := 'E class';
  li.Items.Add.Text := 'AMG GT class';

  WebListControl1.Items.Add.Text := 'Audi';
  WebListControl1.Items.Add.Text := 'Porsche';
  WebListControl1.Items.Add.Text := 'BMW';

  for i := 0 to li.Items.Count - 1 do
  begin
    badge := TWebBadge.Create(Self);
    badge.ElementClassName:= 'badge badge-warning badge-pill';
    badge.Text := inttostr(random(10));
    badge.ParentElement := TJSHTMLElement(li.Items[i].ListElement);
  end;
end;
Rendered in the browser with Bootstrap, this spectacularly becomes:


Interested in fast RAD component based web client application development with Delphi? Get started today: TMS WEB Core, TMS FNC UI web-enabled controls, web-enabled TMS XData, the first parts under the TMS RADical WEB umbrella are all available separately now or as part of the TMS-ALL-ACCESS subscription!

Bruno Fierens


Bookmarks: 

This blog post has received 8 comments.


1. Thursday, September 13, 2018 at 1:20:36 PM

AN EXCELLENT TIP,
Thank YOU!

Baykal Ertan


2. Monday, September 17, 2018 at 4:22:33 PM

Hi,

I am using trial 1.0.0.3 web core.
When i drop WebListControl to form, it can not complile . The complier say that [Error] TestUnit3.pas(7): can''t find unit "WEBLib.Lists". I search file but i can not find WebLib.List on Core Source directory.

Best Regards
Murat Ak

Murat Ak


3. Monday, September 17, 2018 at 4:46:27 PM

Please install v1.0.3.0, not 1.0.0.3

Bruno Fierens


4. Monday, September 17, 2018 at 5:10:42 PM

Hi,
Sorry id did type wrong.
it is installed 1.0.3.0 and i can not run with WebListControl. Please checking that.

Best Regards

Murat Ak


5. Monday, September 17, 2018 at 6:27:49 PM

If you have the trial version installed, can you verify the file WEBLib.Lists.pju is present under ''Core Source'' subfolder?

Bruno Fierens


6. Monday, September 17, 2018 at 8:04:20 PM

Hi,

I try to say that there is no WEBLib.Lists.pju on Core Source directory.

Best Regards

Murat Ak


7. Monday, September 17, 2018 at 10:52:12 PM

We will investigate.
When you do Help, About, TMS WEB Core, you effectively see v1.0.3.0 mentioned there?

Bruno Fierens


8. Tuesday, September 18, 2018 at 8:08:36 AM

Hi,

Yes I am sure it is v1.0.3.0 on TMS Web Core about.

Best Regards

Murat Ak




Add a new comment:
Author:
Email:
  You will receive a confirmation mail with a link to validate your comment, so please use a valid email address.
Comment:
 
Change Image
Fill in the characters from the image above:
 

All fields are required.
 




Previous  |  Next  |  Index