Questo tutorial nr. 2 è in realtà una variante del tutorial 1 che trovate qua: https://blog.lazaruspascal.it/2022/05/25/pas2js-tutorial-1-progetto-logihttps://blog.lazaruspascal.it/2022/05/25/pas2js-tutorial-1-progetto-login-html-statico-scritto-a-manon-html-statico-scritto-a-mano
Si tratta dunque di realizzare lo stesso progetto di una Browser Application per il login. Così come il tutorial nr. 1, anche questo tutorial 2, si basa su HTML statico e con bind degli elementi del DOM. Mentre però nel tutorial 1 il bind veniva effettuato tramite la classe TJSHTMLInputElement (dichiarato nella unit Web), in questo tutorial 2 il bind verrà effettuato con dei componenti: classi che discendono da TComponent e che vengono mappate nei tag HTML.
Allo stato attuale Lazarus non permette di disegnare in modo visuale delle Web Browser Application come fossero delle Form (però, se non ho capito male, qualcosa bolle in pentola…) e quindi bisognerà scrivere a mano il codice così come faremmo se dovessimo creare dei componenti a runtime nelle Form.
Iniziamo il progetto
Il progetto, come già accennato è identico a quello descritto nel tutorial 1, quindi seguite quelle stesse indicazioni e poi modificate il codice come indicato quì.
La prima cosa da fare è di mettere in uses la unit htmlwidgets
.
Quindi cambiamo il tipo dei puntatori agli elementi del DOM che ci interessano:
edtEmail: TTextInputWidget; edtPassword: TTextInputWidget; btnLogin : TButtonWidget;
A questo punto, cambiamo anche il metodo BindElements come sotto.
procedure TMyApplication.BindElements; begin Writeln('BindElements'); edtEmail:=TTextInputWidget.Create(Self); edtEmail.elementID:='edtEmail'; edtEmail.Refresh; edtPassword:=TTextInputWidget.Create(Self); edtPassword.ElementID:='edtPassword'; edtPassword.Refresh; btnLogin:=TButtonWidget.Create(Self); btnLogin.ElementID:='btnLogin'; btnLogin.Classes:='button is-block is-info is-large is-fullwidth'; btnLogin.Text:='Login <i class="fa fa-sign-in" aria-hidden="true"></i>'; btnLogin.TextMode:=tmHTML; btnLogin.Refresh; end;
Se analizziamo il codice dell’elemento edtEmail:
- per prima cosa viene creata una istanza del componente
- poi viene specificato il nome, questo serve per il bind con l’HTML
- poi viene invocato il metodo Refresh, questo serve a far generare l’HTML necessario
L’elemento edtPassword è praticamente identico, quindi saltiamo a btnLogin.
Potremmo lasciare il tutto così com’è, in questo caso facciamo qualcosa in più: spostiamo la descrizione dell’elemento nel codice pascal. Modifichiamo quindi l’HTML in modo che il bottone abbia la seguente dichiarazione:
<button id="btnLogin">Login</button>
A questo punto se analizziamo il sorgente sopra vediamo come i tag possano essere passati interamente dal codice pascal tramite il componente.
Altra cosa che cambia sono gli eventi: trattandosi di componenti, l’evento OnClick sarà dichiarato come segue:
procedure doLoginClick(sender : TObject; event : TJSEvent);
mentre sarà possibile assegnarlo con:
btnLogin.OnClick:=@DoLoginCLick;
Il codice integrale del progetto.
program project_login_02; {$mode objfpc} uses browserconsole, browserapp, JS, Classes, SysUtils, Web , htmlwidgets ; type { TMyApplication } TMyApplication = class(TBrowserApplication) edtEmail: TTextInputWidget; edtPassword: TTextInputWidget; btnLogin : TButtonWidget; procedure doRun; override; private procedure BindElements; procedure doLoginClick(sender : TObject; event : TJSEvent); procedure doServerLogin(const aUser, aPassword: String); end; procedure TMyApplication.doRun; begin // Your code here BindElements; btnLogin.OnClick:=@DoLoginCLick; Terminate; end; procedure TMyApplication.BindElements; begin Writeln('BindElements'); edtEmail:=TTextInputWidget.Create(Self); edtEmail.elementID:='edtEmail'; edtEmail.Refresh; edtPassword:=TTextInputWidget.Create(Self); edtPassword.ElementID:='edtPassword'; edtPassword.Refresh; btnLogin:=TButtonWidget.Create(Self); btnLogin.ElementID:='btnLogin'; btnLogin.Classes:='button is-block is-info is-large is-fullwidth'; // class="button is-block is-info is-large is-fullwidth" btnLogin.Text:='Login <i class="fa fa-sign-in" aria-hidden="true"></i>'; // <i class="fa fa-sign-in" aria-hidden="true"></i> btnLogin.TextMode:=tmHTML; btnLogin.Refresh; end; procedure TMyApplication.doLoginClick(sender: TObject; event: TJSEvent); begin Writeln('doLoginClick'); DoServerLogin(edtEmail.Value,edtPassword.Value); end; procedure TMyApplication.doServerLogin(const aUser, aPassword: String); begin window.alert('Richiesta login per: '+aUser + ' (pass: ' + aPassword + ')'); end; var Application : TMyApplication; begin Application:=TMyApplication.Create(nil); Application.Initialize; Application.Run; // Application.Free; end.
Conclusioni
Si conclude quì il tutorial, e con questo abbiamo visto tutte le possibilità che abbiamo per “agganciare” nel sorgente pascal gli elementi del DOM presenti in un HTML scritto totalmente a mano.
Quando si dice di separare il design dalla business logic insomma 🙂
Per qualsiasi domanda su questo articolo potete come al solito usufruire del ns forum https://www.lazaruspascal.it/
Buon lavoro
Riferimenti
Questo articolo ed il relativo codice pascal è tratto da un articolo di Mychael Van Canneyt su Blaise Pascal Magazine nr.99/100.