I have a simple project in TMS WEB Core.
I want to create a series of buttons at runtime in a loop inside of my TWebHTMLDiv
component and call the Delphi myFunc
function based on the loop index of each button.
The myFunc
function on the Delphi side takes input and sends a ShowMessage
with the button index.
My problem is that I don't know how to call a function with a parameter from the template side
My unit Code:
unit Unit1;
interface
uses
System.SysUtils, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
WEBLib.Forms, WEBLib.Dialogs, Vcl.Controls, WEBLib.WebCtrls;
type
TForm1 = class(TWebForm)
WebHTMLDiv1: TWebHTMLDiv;
procedure WebFormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure myFunc(ACode: string);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.myFunc(ACode: string);
begin
ShowMessage(ACode);
end;
procedure TForm1.WebFormShow(Sender: TObject);
var
i: integer;
begin
WebHTMLDiv1.HTML.Text := '';
for i := 1 to 5 do
WebHTMLDiv1.HTML.Text := WebHTMLDiv1.HTML.Text +
'<button type="button" onclick="myFunc(' + i.ToString +
')" class="btn btn-primary btn-sm">BtnNum' + i.ToString + '</button>';
end;
end.
My HTML template Code:
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>TMS Web Project</title>
<style>
</style>
</head>
<body>
<div id = "htmlDiv">
</div>
</body>
</html>
In your example, to call your Delphi myFunc
procedure from JavaScript code, you can simply call the procedure like this in JavaScript:
pas.Unit1.TForm1.myFunc('1998');
And that would work. So your full WebFormShow
code would be:
procedure TForm1.WebFormShow(Sender: TObject);
var
i: integer;
begin
WebHTMLDiv1.HTML.Text := '';
for i := 1 to 5 do
WebHTMLDiv1.HTML.Text := WebHTMLDiv1.HTML.Text +
'<button type="button" onclick="pas.Unit1.TForm1.myFunc(' + i.ToString +
')" class="btn btn-primary btn-sm">BtnNum' + i.ToString + '</button>';
end;
As an alternative method. You can also assign a click
eventListener
to each button.
I've modified the <button>
to include a data_code
attribute and added a MyBtnClick
class to it. I then also modified your myFunc
function to have a Sender: TJSEvent
parameter.
Here's the full code:
unit Unit1;
interface
uses
System.SysUtils, System.Classes, JS, Web, WEBLib.Graphics, WEBLib.Controls,
WEBLib.Forms, WEBLib.Dialogs, Vcl.Controls, WEBLib.WebCtrls, Vcl.StdCtrls,
WEBLib.StdCtrls;
type
TForm1 = class(TWebForm)
WebHTMLDiv1: TWebHTMLDiv;
procedure WebFormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure myFunc(Sender: TJSEvent);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.myFunc(Sender: TJSEvent);
var
ACode: String;
begin
ACode := Sender.targetElement.getAttribute('data_code');
ShowMessage(ACode);
end;
procedure TForm1.WebFormShow(Sender: TObject);
var
i: integer;
MyBtnClick: TJSHTMLCollection;
begin
WebHTMLDiv1.HTML.Text := '';
for i := 1 to 5 do
WebHTMLDiv1.HTML.Text := WebHTMLDiv1.HTML.Text +
'<button type="button" data_code="' + i.ToString +
'" class="btn btn-primary btn-sm MyBtnClick"' +
'>BtnNum' + i.ToString + '</button>';
MyBtnClick := document.getElementsByClassName('MyBtnClick');
for I := 0 to MyBtnClick.length-1 do
begin
MyBtnClick.Items[I].addEventListener('click', @myFunc);
end;
end;
end.