TMS WEB Core tips & tricks : Small sample with lots to learn about its versatility
TWebResponsiveGrid intro
TWebResponsiveGrid is a responsive grid control. This means that it contains a number of items displayed in a 2D grid layout and this layout, i.e. number of columns will be controlled by the device screen size. This number of columns is determined by the setting TWebResponsiveGrid.Options.ItemMinWidth. This sets the minimum width of items in pixels. So, the grid will automatically show as much columns as allowed to still have this minimum width of items respected. And this also takes the TWebResponsiveGrid.Options.ItemGap in account that specifies the gap between items also in number of pixels. Other than this, there is not much to do. When the TWebResponsiveGrid is resized or displayed on a big or small screen, it will use these settings to automatically render the right number of columns for items. To see this directly live, you can also visit this online demo
An item can be displayed in normal state, hover state and selected state. Therefore
TWebResponsiveGrid.Options has settings for normal state, selected state and hover state colors. In addition or as alternative to setting colors (and other settings) for items, CSS can be used. TWebResponsiveGrid.Options.ItemClassName is the name of the CSS class that can be assigned to the item (outer HTML element of the item is a DIV).
Beyond simple HTML in items
The items one can add in a TWebResponsiveGrid are of the type TWebResponsiveGridItem and have a property HTML: string to set the HTML the item should contain and the generic Tag property. When the TWebResponsiveGrid.Options.ItemTemplate is set, this is preset for the item HTML when a new item is added. Note that when loading data from JSON or a dataset, the template can hold specifiers (%SPECIFIER%) and this is merged at runtime with hthe JSON attribute or dataset record field.
The purpose of this article though is on programmatically filling the items collection. The initial code to fill the TWebResponsiveGrid as such is:
for i := 0 to 20 do begin WebResponsiveGrid1.Items.Add.HTML := 'Grid item '+i.ToString+'
This shows how we have added some text and a button to a responsive grid item. The result is very simple. It does not look nice but the responsive behavior is there. The TWebResponsiveGrid is set to top aligned and when resizing the browser, the items automatically flow in the container.
Before diving into making the HTML button react, let’s visually enhance the responsive grid items. We do this with some CSS for the TWebResponsiveGrid as well as the TWebResponsiveGridItem. While we could add the CSS style in the HTML file associated with the form or application (which is probably the best place), we wanted to take the opportunity here to introduce the TWebForm.AddCSS() method that allows to dynamically insert CSS at runtime (or remove it later and replace it). Doing so is simple as demonstrated with this code snippet:
AddCSS('respgriditem','.mygriditem { background-color: aliceblue; border-radius: 4px; border: 1px solid darkgray; padding:10px; font-name: Arial; font-size: 12pt;}'); AddCSS('respgrid','.mygrid {padding:10px;}'); WebResponsiveGrid1.ElementClassName := 'mygrid'; WebResponsiveGrid1.Options.ItemClassName := 'mygriditem';
Here you can see a CSS class for the item with some border rounding, padding, font, …is set and also a CSS based padding added to the TWebResponsiveGrid control itself. The result becomes already a lot nicer:
Blending the Object Pascal world with HTML elements
Now comes the more interesting part of this article. It explains two techniques that might not be well-known to bring the RAD component based development world we Delphi developers love so much and the HTML/CSS web world together.
First we are going to use a technique to bind a TWebButton control to the HTML in the responsive grid item. By doing this binding, we can do everything we want, including handling events, with the HTML button via the TWebButton class without bothering with the HTML and JavaScript. And doing so is surprisingly simple:
TForm3 = class(TWebForm) public { Public declarations } procedure ButtonClick(Sender: TObject); end; procedure TForm3.WebFormCreate(Sender: TObject); var i: integer; btn: TWebButton; begin for i := 0 to 20 do begin WebResponsiveGrid1.Items.Add.HTML := 'Grid item '+i.ToString+'
'; btn := TWebButton.Create('btn'+i.ToString); btn.Tag := i; btn.OnClick := ButtonClick; end; end;
As you can see, a TWebButton instance is created passing the HTML element unique ID value as argument for the constructor. Doing so will wrap the TWebButton class on the existing HTML button element. When wrapped, we can simple access this HTML element via the Pascal class properties and handle events via the Pascal class events. Here we bind the form’s ButtonClick method to the button OnClick. The event handler that can be used is:
procedure TForm3.ButtonClick(Sender: TObject); begin if (Sender is TWebButton) then WebListbox1.Items.Add('Clicked button ' +(Sender as TWebButton).Tag.ToString); end;
Via the button Tag property we could easily identify what item’s button was clicked.
We could use this technique to bind any other type of HTML element to a corresponding TMS WEB Core Pascal class. But, the goal of this article was to introduce lesser known techniques, hence, we will add a checkbox to the item as well with another technique (that could have been used for the button as well).
Clearly, the HTML of the item does not have a HTML INPUT element of the checkbox type, so we are going to add it as a TWebCheckBox. The code to do so is:
for i := 0 to 20 do begin chk := TWebCheckBox.Create(Self); chk.ShowFocus := false; chk.ParentElement := WebResponsiveGrid1.Items[i].ElementHandle; chk.Tag := i; chk.OnClick := ButtonClick; WebResponsiveGrid1.Items[i].ItemObject := chk; end;
This code snippet contains a number of noteworthy items. First of all, the TWebCheckBox instance is created with specifying the form as its owner which is what we are typically used to as Delphi developers. In a VCL application, the control would be effectively created as Windows window handle based control and become visible when setting Control.Parent. The same applies to a TMS WEB Core control. If we would set chk.Parent := Self, the checkbox would become visible but would be a child control of the form and this is not what we want. We want the checkbox to be a child of the item in the TWebResponsiveGrid, thus the HTML DIV representing this TWebResponsiveGridItem. And this is exactly what is achieved via:
chk.ParentElement := WebResponsiveGrid1.Items[i].ElementHandle;
Note that WebResponsiveGrid1.Items[i].ElementHandle is a reference to the HTML DIV element for the responsive grid item! The TMS WEB Core control property ParentElement allows to specify the parent HTML as another HTML element. What happens in the control logic is that TWebCheckBox.Create(Owner) creates a HTML INPUT element of the type CHECKBOX and setting the ParentElement property will perform (in pseudo code) at DOM level ParentHTMLElement.appendChild(CheckBoxElement).
By using a simple trick here associating the created checkbox instance in WebResponsiveGrid1.Items[i].ItemObject, we can later in code manipulate the HTML INPUT CHECKBOX element via the TWebCheckBox class and actually not bother about all the HTML behind. To preset all checkboxes for example, the code is simply:
for i := 0 to 20 do begin (WebResponsiveGrid1.Items[i].ItemObject as TWebCheckBox).Checked := true; end;
The result is:
As you can see we have associated the same ButtonClick event handler also to the checkbox OnClick, so we can extend this handler to:
procedure TForm3.ButtonClick(Sender: TObject); begin if (Sender is TWebButton) then WebListbox1.Items.Add('Clicked button ' +(Sender as TWebButton).Tag.ToString); if (Sender is TWebCheckBox) then begin if (Sender as TWebCheckBox).Checked then WebListbox1.Items.Add('Checked checkBox ' +(Sender as TWebCheckBox).Tag.ToString) else WebListbox1.Items.Add('Unchecked checkBox ' +(Sender as TWebCheckBox).Tag.ToString); end; end;
It will add the checkbox checked state in a listbox on the form.
Summary
We hope this small demo you can download here will learn you not only a few handy techniques for working in a flexible way with the TWebResponsiveGrid but as these techniques are generally applicable to all TMS WEB Core controls, will help you to get more out of TMS WEB Core than you already do. Note that everything explained here is also applicable in TMS WEB Core for Visual Studio Code, in fact, the exact same demo project created for Delphi can be directly opened in TMS WEB Core for Visual Studio Code!
We look forward to learn how you apply these techniques and what wonderful applications you are creating with TMS WEB Core! If you have suggestions for more in depth looks at TMS WEB Core techniques like this article, let us know and our team will be happy to explore and uncover these in follow-up articles.