<h1 id="mb_pseudoform">MB_PseudoForm</h1>
<p>MB_PseudoForm consente di organizzare degli elementi input, select e textarea compilabili dall&#39;utente in un contenitore (tipicamente un elemento div) e di inviare dati inseriti dall&#39;utente ad un server per l&#39;elaborazione utilizzando un &quot;Ajax Request&quot;. </p>
<p>MB_PseudoForm può essere utile:</p>
<ul>
<li>In tutte le situazioni in cui desidero inviare l&#39;input dell&#39;utente al server senza scaricare la pagina.</li>
<li>In particolare se voglio creare dei moduli di immissione in applicazioni .net di tipo WebForm senza utilizzare il form principale (vedi l&#39;esempio nella cartella demo)</li>
</ul>
<p>MB_PseudoForm invia i dati sotto forma di lista di oggetti. Questo consente di costruire lato server handlers generici, indipendenti dalla struttura del modulo di input da elaborare. Ad esempio, il demo allegato è una applicazione WebForm dove un API controller trasforma un qualsiasi gruppo di dati compilati dall&#39;utente in una email formattata che viene inviata allo staff del sito.</p>
<h2 id="getting-started">Getting started</h2>
<p>È possibile caricare MB_PseudoForm direttamente da CDN</p>
<pre><code>&lt;script src=&quot;https://cdn.jsdelivr.net/npm/@magicbruno/mb_pseudoform@1.0.0/dist/MB_PseudoForm.min.js&quot;&gt;&lt;/script&gt;
</code></pre>
<p>o installato con NPM </p>
<pre><code>npm install @magicbruno/mb_pseudoform@1.0.0
</code></pre>
<p>o clonare il repository da Github: </p>
<pre><code>git clone https://github.com/magicbruno/MB_PseudoForm.git
</code></pre>
<h2 id="come-funziona">Come funziona</h2>
<p>Uno pseudo form è un elemento HTML (per esempio un elemento div) che contiene degli elementi <code>input</code>, <code>select</code> e <code>textarea</code> e almeno un elemento cliccabile (<code>&lt;button&gt;</code> o <code>&lt;a&gt;</code>) che ha la funzione di inviare i dati.</p>
<p>Condizioni minime perché un elemento HTML diventi uno pseudo form  sono:</p>
<ul>
<li>Che sia definito l&#39;<em>handler</em> destinato a ricevere i dati lato server utilizzando l&#39;attributo <code>data-mb-action</code> da applicare all&#39;elemento stesso</li>
<li>Che l&#39;elemento contenga un <em>submit button</em> definito assegnando ad un elemento <code>&lt;button&gt;</code> o a un elemento <code>&lt;a&gt;</code> l&#39;attributo <code>data-mb-toggle=&quot;submit&quot;</code>.</li>
</ul>
<pre><code>&lt;div id=&quot;sample1-en&quot; data-mb-action=&quot;api/PseudoForm&quot;&gt;
  &lt;!-- Campi di input --&gt;
  &lt;button type=&quot;button&quot; data-mb-toggle=&quot;submit&quot;&gt;Invia dati&lt;/button&gt;
&lt;/div&gt;
</code></pre>
<h3 id="attivazione">Attivazione</h3>
<p>Si può attivare lo pseudo form via Javascript (<code>pForm</code> può essere indifferentemente un selettore CSS o un elemento HTML)</p>
<pre><code>const myPseudoForm = new MB_PseudoForm(pForm) ;
</code></pre>
<p>o semplicemente assegnando all&#39;elemento l&#39;attributo <code>data-mb-ride=&quot;pseudo-form&quot;</code>.</p>
<pre><code>&lt;div id=&quot;sample1-en&quot; data-mb-action=&quot;api/PseudoForm&quot; data-mb-ride=&quot;pseudo-form&quot;&gt;
  &lt;!-- Campi di input --&gt;
  &lt;button type=&quot;button&quot; data-mb-toggle=&quot;submit&quot;&gt;Invia dati&lt;/button&gt;
&lt;/div&gt;
</code></pre>
<h2 id="proprietà-e-metodi">Proprietà e metodi</h2>
<p>Può essere utile illustrare alcune caratteristiche base del funzionamento dello pseudo form. Per maggiori dettagli consigliamo di esaminare direttamente il codice che è scritto in modo molto chiaro e ampiamente commentato.</p>
<p>MB_PseudoForm si basa sul funzionamento di tre classi Javascript:</p>
<ul>
<li><code>MB_PseudoForm</code>, la classe principale</li>
<li><code>MB_PseudoFormValue</code> che definisce l&#39;oggetto in cui vengono trasformati i campi compilati dell&#39;utente per l&#39;invio al server</li>
<li><code>ValuesList</code> che fornisce alcuni metodi per gestire una lista di <code>MB_PseudoFormValue</code> </li>
</ul>
<h3 id="mb_pseudoformvalue">MB_PseudoFormValue</h3>
<p>MB_PseudoFormValue espone 5 proprietà che riflettono caratteristiche e valore dei campi compilati dall&#39;utente.</p>
<table>
<thead>
<tr>
<th>Proprietà</th>
<th>Tipo</th>
<th>Descrizione</th>
</tr>
</thead>
<tbody><tr>
<td><code>Name</code></td>
<td><code>string</code></td>
<td>Riflette il contenuto dell&#39;attributo <code>name</code> dell&#39;elemento. Nel caso l&#39;attributo <code>name</code> non sia presente, viene usato l&#39;<code>id</code> dell&#39;elemento.</td>
</tr>
<tr>
<td><code>Type</code></td>
<td><code>string</code></td>
<td>Riflette il contenuto della proprietà <code>type</code> dell&#39;elemento.</td>
</tr>
<tr>
<td><code>Value</code></td>
<td><code>any</code></td>
<td>Se l&#39;elemento è una <code>checkbox</code> è <code>true</code> se selezionata, altrimenti <code>false</code>. Se l&#39;elemento è un <code>input</code> di tipo <code>file</code> restituisce il contenuto del file codificato come DataUrlBase64. Negli altri casi riflette il contenuto della proprietà <code>value</code> dell&#39;elemento.</td>
</tr>
<tr>
<td><code>Label</code></td>
<td><code>string</code></td>
<td>Riflette il contenuto dell&#39;attributo <code>aria-label</code> dell&#39;elemento. Nel caso l&#39;attributo <code>aria-label</code> non sia presente restituisce lo stesso valore di <code>Name</code></td>
</tr>
<tr>
<td><code>Detail</code></td>
<td><code>string</code></td>
<td>Se l&#39;elemento è un <code>input</code> di tipo <code>file</code> restituisce in nome originale del file. Negli altri casi può essere usata per passare al server informazioni aggiuntive su quel campo (vedi demo)</td>
</tr>
</tbody></table>
<p>I campi che compongono lo pseudo form sono trasformati in oggetti MB_PseudoFormValue utilizzando il metodo statico asincrono <code>MB_PseudoFormValue.createAsync</code> che restituisce una Promise che si risolve con l&#39;oggetto creato. </p>
<h3 id="valueslist">ValuesList</h3>
<p>Il valore restituito dal metodo  <code>MB_PseudoForm.collectData</code> (vedi sotto), che raccoglie i campi compilati dall&#39;utente come lista di oggetti <code>MB_PseudoFormValue</code> è un&#39;istanza della classe <code>ValueList</code>.</p>
<p>La classe <code>ValueList</code> espone una sola proprietà, <code>length</code>, che restituisce la lunghezza della lista e offre alcuni metodi che aiutano a gestirla.</p>
<table>
<thead>
<tr>
<th>Metodo</th>
<th>Tipo restituito</th>
<th>Descrizione</th>
</tr>
</thead>
<tbody><tr>
<td><code>item(i)</code></td>
<td><code>MB_PseudoFormValue</code></td>
<td><strong>Parametro</strong>: <em>i</em> <code>number</code>. Restituisce l&#39;oggetto <code>MB_PseudoFormValue</code> con indice <em>i</em></td>
</tr>
<tr>
<td><code>push(obj)</code></td>
<td><code>number</code></td>
<td><strong>Parametro</strong>: <em>obj</em> <code>MB_PseudoFormValue</code>. Aggiunge un oggetto <code>MB_PseudoFormValue</code> alla lista. Se esiste già un&#39;oggetto che lo stesso <code>Name</code>, l&#39;oggetto presente viene sostituito da quello inserito. Restituisce la nuova lunghezza della lista</td>
</tr>
<tr>
<td><code>remove(name)</code></td>
<td><code>boolean</code></td>
<td><strong>Parametro</strong>: <em>name</em> <code>string</code>. Rimuove dalla lista l&#39;oggetto con <code>Name</code> = <em>name</em>. Restituisce <code>true</code> se l&#39;oggetto è stato rimosso <code>false</code> se non è stato trovato nella lista</td>
</tr>
<tr>
<td><code>indexOf(name)</code></td>
<td><code>number</code></td>
<td><strong>Parametro</strong>: <em>name</em> <code>string</code>. Cerca dalla lista l&#39;oggetto con <code>Name</code> = <em>name</em>. Ne restituisce l&#39;indice se l&#39;oggetto è stato trovato altrimenti <code>-1</code>.</td>
</tr>
<tr>
<td><code>getValue(name)</code></td>
<td><code>any</code></td>
<td><strong>Parametro</strong>: <em>name</em> <code>string</code>. Cerca dalla lista l&#39;oggetto con <code>Name</code> = <em>name</em> e restituisce il suo <code>Value</code>.</td>
</tr>
<tr>
<td><code>clear()</code></td>
<td>nessuno</td>
<td>Svuota la lista</td>
</tr>
</tbody></table>
<h3 id="mb_pseudoform-1">MB_PseudoForm</h3>
<p>In generale non dovrebbe essere necessario accedere direttamente alle proprietà e ai metodi di MB_PseudoForm. L&#39;interfaccia con lo pseudo form è garantita dagli eventi (<code>change.mb.pseudoform</code>, <code>validate.mb.pseudoform</code> e <code>submitted.mb.pseudoform</code>) che vengono emessi nei momenti chiave del processo.  </p>
<h4 id="proprietà"><strong>Proprietà</strong></h4>
<table>
<thead>
<tr>
<th>Proprietà</th>
<th>Tipo</th>
<th>Descrizione</th>
</tr>
</thead>
<tbody><tr>
<td><code>pseudoForm</code></td>
<td><code>HTML element</code></td>
<td>Proprietà a sola lettura. Restituisce l&#39;elemento HTML su cui è stato costruito lo pseudo form</td>
</tr>
<tr>
<td><code>submit</code></td>
<td><code>HTML element</code></td>
<td>Proprietà a sola lettura. Restituisce l&#39;elemento HTML che viene usato come <em>submit button</em></td>
</tr>
<tr>
<td><code>inputs</code></td>
<td><code>static NodeList</code></td>
<td>Proprietà a sola lettura. Restituisce la lista degli elementi (<code>input</code>, <code>select</code> e <code>textarea</code>) che fanno parte dello pseudo form in formato <a href="https://developer.mozilla.org/en-US/docs/Web/API/NodeList">static NodeList</a></td>
</tr>
<tr>
<td><code>pendingChanges</code></td>
<td><code>boolean</code></td>
<td>Restituisce <code>true</code> se almeno un elemento di input è stato modificato. Viene automaticamente resettata quando i dati vengono inviati. Può essere resettata (impostata a <code>false</code>) anche programmaticamente.</td>
</tr>
</tbody></table>
<h4 id="metodi"><strong>Metodi</strong></h4>
<table>
<thead>
<tr>
<th>Metodo</th>
<th>Tipo restituito</th>
<th>Descrizione</th>
</tr>
</thead>
<tbody><tr>
<td><code>collectData</code></td>
<td><code>Promise</code></td>
<td>Metodo asincrono. La Promise restituita si risolve con l&#39;elenco dei valori immessi dall&#39;utente sotto forma di <code>ValueList</code>.</td>
</tr>
<tr>
<td><code>submitData</code></td>
<td>nessuno</td>
<td>Consente di inviare programmaticamente lo pseudo form al server. Emette un evento <code>validate.mb.pseudoform</code> (cancellabile) subito prima dell&#39;invio e un evento <code>submitted.mb.pseudoform</code> subito dopo aver ricevuto la risposta dal server.</td>
</tr>
</tbody></table>
<h4 id="eventi"><strong>Eventi</strong></h4>
<p>Tutti gli eventi sono inviati all&#39;elemento HTML su cui viene costruito lo pseudo form. Per gestirli, quindi, basta aggiungere un gestore di eventi  all&#39;elemento stesso:</p>
<pre><code>&lt;div id=&quot;sample1-en&quot; data-mb-action=&quot;api/PseudoForm&quot; data-mb-ride=&quot;pseudo-form&quot;&gt;
  &lt;!-- Campi di input --&gt;
  &lt;button type=&quot;button&quot; data-mb-toggle=&quot;submit&quot;&gt;Invia dati&lt;/button&gt;
&lt;/div&gt;
....
&lt;script&gt;
  const myForm = document.getElementById(&quot;sample1-en&quot;);
  myForm.addEventListener(&#39;validate.mb.pseudoform&#39;, event =&gt; {
    const values = event.detail;
    // .......
  })
&lt;/script&gt;
</code></pre>
<table>
<thead>
<tr>
<th>Evento</th>
<th>Descrizione</th>
</tr>
</thead>
<tbody><tr>
<td><code>change.mb.pseudoform</code></td>
<td>Viene emesso ogni volta che un campo dello pseudo form viene modificato. La proprietà <code>detail</code> dell&#39;evento contiene l&#39;elemento HTML il cui valore è stato modificato.</td>
</tr>
<tr>
<td><code>validate.mb.pseudoform</code></td>
<td>Viene emesso subito prima che i dati vengano mandati al server. La proprietà <code>detail</code> dell&#39;evento contiene la <code>ValueList</code> che sta per essere inviata. Consente di validare i dati prima dell&#39;invio. Per estrarre informazione su campi specifici si possono applicare alla lista i metodi della classe <code>ValueList</code>. Se si applica il metodo <code>preventDefault</code> all&#39;evento, l&#39;invio viene cancellato.</td>
</tr>
<tr>
<td><code>submitted.mb.pseudoform</code></td>
<td>Viene emesso dopo che i dati vengano inviati e o si riceve la risposta dal server, o si verifica un errore. Nel caso di risposta dal server, la proprietà dell&#39;evento detail contiene la risposta, in caso di errore contiene un oggetto con quattro proprietà <code>Success</code> (<code>boolean</code>, impostata su <code>false</code>), <code>Message</code> (<code>string</code>, contiene il messaggio di errore), <code>Exitcode</code> e <code>Data</code> attualmente non usate. (vedi demo).</td>
</tr>
</tbody></table>
<h2 id="demo">Demo</h2>
<p>Nella cartella demo del progetto troverete una semplice applicazione web ASP.NET che dimostra come utilizzare MB_PseudoForm congiuntamente a un API Controller per generare, partendo da un MB_PseudoForm, una mail formattata con le informazione inserite dall&#39;utente e inviata allo staff del sito, e una mail di ringraziamento inviata all&#39;utente stesso.</p>
<h3 id="utilizzare-il-demo">Utilizzare il demo</h3>
<p>Clona il repository git sul tuo computer</p>
<pre><code>git clone https://github.com/magicbruno/MB_PseudoForm.git
</code></pre>
<p>oppure <a href="https://github.com/magicbruno/MB_pseudo_form/archive/refs/heads/main.zip">scaricalo</a>.</p>
<p>Apri <code>/demo/demo.sln</code> in Visual Studio.</p>
<p>Prima di eseguire l&#39;applicazione devi configurare il server smtp che il controller utilizzerà per inviare i messaggi email generati.</p>
<p>Apri nell&#39;editor di <strong>Visual Studio</strong> <code>Web.config</code> e nella sezione <code>appSettings</code> inserisci i dati:</p>
<pre><code>    &lt;appSettings&gt;
    &lt;!-- Inserisci url del server --&gt;
        &lt;add key=&quot;SmtpServer&quot; value=&quot;...&quot;/&gt;
    &lt;!-- Inserisci credenziali di accesso --&gt;
        &lt;add key=&quot;SmtpUsername&quot; value=&quot;...&quot;/&gt;
        &lt;add key=&quot;SmtpPassword&quot; value=&quot;...&quot;/&gt;
    &lt;!-- Modifica le impostazioni ssl se necessario --&gt;
        &lt;add key=&quot;SmtpPort&quot; value=&quot;25&quot;/&gt;
        &lt;add key=&quot;SmtpUseSSL&quot; value=&quot;false&quot;/&gt;
    &lt;!-- Mittente dei messaggi inviati dal server --&gt;
        &lt;add key=&quot;DefaultSmtpFromMail&quot; value=&quot;...&quot;/&gt;
    &lt;!-- Casella di posta dello staff --&gt;
        &lt;add key=&quot;MailTo&quot; value=&quot;...&quot;/&gt;
    &lt;/appSettings&gt;
</code></pre>
<p>Quindi lancia l&#39;applicazione in Iis Express premendo <kbd>f5</kbd> o <kbd>ctrl</kbd> + <kbd>f5</kbd>.</p>
<blockquote>
<h2 id="nota">Nota</h2>
<p>Per usare l&#39;api controller <code>/ApiControllers/PseudoFormController.cs</code> in un tuo progetto devi installare il pacchetto <a href="https://www.nuget.org/packages/Microsoft.AspNet.WebApi">Microsoft.AspNet.WebApi</a> e aggiungere al progetto anche le classi <code>/ApiControllers/ApiControllerResponse.cs</code> e<code> /ApiControllers/PseudoFormModel.cs</code>. Maggiori informazioni su ASP.NET Web API <a href="https://docs.microsoft.com/it-it/aspnet/web-api/">qui</a>.</p>
</blockquote>
