It is on the oven a tool named TMS Web Core that actually use the Delphi XE7 and its form designer to create web applications. You Just drop components onto a form and set up at the objector inspector, the events and the properties.
All of the above is great and it will no doubt give us the same benefits as Delphi/Lazarus developers currently enjoy. The pas2js compiler will auto generate
the components for you.
It has been said in Delphi it works absolutely splendid. I was recently analyzing the generated code of the so called TMS Web Core framework, and and quite a bit of effort, doing some reverve engineering I believe I created a clone!
Since Delphi/Lazarus comes with a bunch of ready to use UI elements and widgets like modals, popups, popover, searchbar, side panels, headerBar, jsut been thinking to create lightweight kind of "fake" web widgets to be used into the Lazarus designer.
Michael Van Canneyt has suggested: "All you need to do is create a web-widgetset for the LCL."
I've spent a few minutes reflecting on this, what's the hack is widgetset for the LCL? I've been using Lazarus less than one month. Anyway, using Package/New Package... I've created some visual web "dummy" components (TWebLabel, TWEBEdit, TWebButton, TWebComboBox and TWebMemo) all those components inherits from the TCustomControl. The idea would be drag'n drop the components on the form. After all, the main form unit looks like this:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
SysUtils, Classes, JS, Web,
WEBLib.Graphics, WEBLIB.Controls, WEBLib.StdCtrls, WEBLib.ExtCtrls,
WEBLib.Forms, WEBLib.Dialogs;
type
TForm1 = class(TWebForm)
private
{ Private declarations }
WebLabel1: TWebLabel;
WebEdit1: TWebEdit;
WebButton1: TWebButton;
WebMemo1: TWebMemo;
WebComboBox1: TWebComboBox;
WebPanel1: TWebPanel;
WebLabel2: TWebLabel;
WebImageControl1: TWebImage;
public
{ Public declarations }
procedure LoadDFMValues; override;
procedure WebButton1Click(Sender: TObject);
procedure WebComboBox1Change(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.LoadDFMValues;
begin
inherited;
//LoadDFMFromStream('Unit1.dfm');
end;
procedure TForm1.WebButton1Click(Sender: TObject);
begin
console.log('button clicked');
WebComboBox1.Items.Add(WebEdit1.Text);
WebComboBox1.ItemIndex := WebComboBox1.Items.Count - 1;
WebMemo1.Lines.Add(WebEdit1.Text);
end;
procedure TForm1.WebComboBox1Change(Sender: TObject);
begin
WebLabel1.Caption := WebComboBox1.Items[WebComboBox1.GetItemIndex];
end;
end.
It is a little bit different from win32 app. Notice the LoadDFMValues method.
TMS Web Core does crazy things such
auto generates the LoadDFMValues method. If you don't know what the hell I'm talking about, in the web application world the DFM/LFM forms are embedded on the javascript, so the method should have such content:
procedure TForm1.LoadDFMValues;
begin
inherited;
WebLabel1 := TWebLabel.Create(Self);
WebEdit1 := TWebEdit.Create(Self);
WebButton1 := TWebButton.Create(Self);
WebMemo1 := TWebMemo.Create(Self);
WebComboBox1 := TWebComboBox.Create(Self);
WebPanel1 := TWebPanel.Create(Self);
WebLabel2 := TWebLabel.Create(WebPanel1);
WebImageControl1 := TWebImage.Create(WebPanel1);
WebLabel1.BeginUpdate;
WebEdit1.BeginUpdate;
WebButton1.BeginUpdate;
WebMemo1.BeginUpdate;
WebComboBox1.BeginUpdate;
WebPanel1.BeginUpdate;
WebLabel2.BeginUpdate;
WebImageControl1.BeginUpdate;
try
Self.Name := 'Form1';
Self.Left := 0;
Self.Top := 0;
Self.Width := 640;
Self.Height := 480;
Self.Font.Charset := 1;
Self.Font.Color := 0;
Self.Font.Height := -13;
Self.Font.Name := 'Tahoma';
Self.Font.Style := [fsBold];
Self.FFormContainer := 'appcontent';
Self.TabOrder := 1;
WebLabel1.Parent := Self;
WebLabel1.Name := 'WebLabel1';
WebLabel1.Left := 64;
WebLabel1.Top := 232;
WebLabel1.Width := 40;
WebLabel1.Height := 16;
WebLabel1.Caption := '-Label-';
WebEdit1.Parent := Self;
WebEdit1.Name := 'WebEdit1';
WebEdit1.Left := 64;
WebEdit1.Top := 42;
WebEdit1.Width := 121;
WebEdit1.Height := 24;
WebEdit1.TabOrder := 0;
WebEdit1.TextHint := 'Add some text ...';
WebButton1.Parent := Self;
WebButton1.Name := 'WebButton1';
WebButton1.Left := 204;
WebButton1.Top := 40;
WebButton1.Width := 75;
WebButton1.Height := 25;
WebButton1.Caption := 'Add';
WebButton1.OnClick := @WebButton1Click;
WebButton1.TabOrder := 1;
WebMemo1.Parent := Self;
WebMemo1.Name := 'WebMemo1';
WebMemo1.Left := 64;
WebMemo1.Top := 88;
WebMemo1.Width := 215;
WebMemo1.Height := 89;
WebMemo1.AutoSize := false;
WebMemo1.SelLength := 0;
WebMemo1.SelStart := 0;
WebMemo1.TabOrder := 2;
WebComboBox1.Parent := Self;
WebComboBox1.Name := 'WebComboBox1';
WebComboBox1.Left := 64;
WebComboBox1.Top := 197;
WebComboBox1.Width := 215;
WebComboBox1.Height := 24;
WebComboBox1.ItemIndex := -1;
WebComboBox1.TabOrder := 3;
WebComboBox1.Text := 'WebComboBox1';
WebComboBox1.OnChange := @WebComboBox1Change;
WebPanel1.Parent := Self;
WebPanel1.Name := 'WebPanel1';
WebPanel1.Left := 64;
WebPanel1.Top := 272;
WebPanel1.Width := 513;
WebPanel1.Height := 89;
WebPanel1.WidthStyle := TSizeStyle.ssPercent;
WebPanel1.WidthPercent:= 80;
WebPanel1.BorderStyle := TBorderStyle.bsSingle;
WebLabel2.Parent := WebPanel1;
WebLabel2.Name := 'WebLabel2';
WebLabel2.Left := 3;
WebLabel2.Top := 29;
WebLabel2.Width := 411;
WebLabel2.Height := 32;
WebLabel2.Caption := 'This demo shows the use of basic controls like TWebEdit, TWebButton, TWebComboBox, TWebMemo and TWebLabel.';
WebLabel2.WordWrap := true;
WebLabel2.WidthStyle := TSizeStyle.ssPercent;
WebImageControl1.Parent := WebPanel1;
WebImageControl1.Name := 'WebImageControl1';
WebImageControl1.Left := 6;
WebImageControl1.Top := 7;
WebImageControl1.Width := 16;
WebImageControl1.Height := 16;
WebImageControl1.AutoSize := true;
WebImageControl1.Picture.LoadFromFile('Picture.png');
finally
WebLabel1.EndUpdate;
WebEdit1.EndUpdate;
WebButton1.EndUpdate;
WebMemo1.EndUpdate;
WebComboBox1.EndUpdate;
WebPanel1.EndUpdate;
WebLabel2.EndUpdate;
WebImageControl1.EndUpdate;
end;
end;
Exactly, they're using kinda magical trick, scan and parse the .DFM then generates the creation code for the current form and its owned components, pretty close to GExpert feature "Components to Code" plugin.
Any idea how to implement the "Components to Code" using Lazarus?
Regards,
warleyalex