> For the complete documentation index, see [llms.txt](https://docs.opencityitalia.it/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.opencityitalia.it/guida-alla-creazione-dei-servizi-digitali/creare-un-servizio/le-funzioni/configurare-logiche-avanzate-nel-modulo-del-servizio.md).

# Configurare logiche avanzate nel modulo del servizio

I controlli avanzati in Form.io permettono di gestire comportamenti dinamici e logiche personalizzate nei servizi digitali. Servono quando le configurazioni standard del form non bastano.

Apri l’esempio che ti serve:

* precompilare i dati del beneficiario;
* controllare residenza o domicilio;
* impostare controlli sull'età;
* popolare una select da un Datagrid.

<details>

<summary>Precompilazione dei dati del beneficiario</summary>

Usa questo controllo per copiare i dati del richiedente nel beneficiario.

È utile quando richiedente e beneficiario coincidono.

{% hint style="info" %}
Nell’esempio seguente viene descritto il caso in cui i campi del beneficiario vengono precompilati automaticamente con quelli del richiedente, qualora il campo “In qualità di” abbia come valore “beneficiario”.
{% endhint %}

### Come configurarlo

Configurare un componente:

* <mark style="color:$success;">`Select`</mark> con label "In qualità di" e property\_name "for\_whom".
* <mark style="color:$success;">`Nested Form`</mark> per i dati del beneficiario, selezionando il form OC- Beneficiario.

Il valore salvato nella select deve essere lo stesso controllato nel codice JavaScript. In questo esempio la precompilazione si attiva quando l’utente indica che il richiedente coincide con il beneficiario.\
La select deve quindi prevedere un’opzione con questo valore:

* label: `Beneficiario del servizio`
* data/value: `beneficiario`

{% hint style="info" %}
Se vuoi un ripasso su come inserire label e value nelle opzioni del componente, consulta la sezione [La select](/guida-alla-creazione-dei-servizi-digitali/creare-un-servizio/i-componenti/la-select.md).
{% endhint %}

<figure><img src="/files/fZEtlYLOrIo8ocXsZ3xv" alt=""><figcaption></figcaption></figure>

### Dove inserire il codice

Inserisci il seguente codice nel Nested Form del beneficiario, nella sezione **Data** → **Calculated Value**.

{% code expandable="true" %}

```javascript
let applicantRequester = ["beneficiario"].includes(data.for_whom)
window.FormioHelper.syncApplicantToBeneficiary(
 data,
 instance,
 applicantRequester
)
```

{% endcode %}

<figure><img src="/files/42BMsSmzfkuQJtgZvnx4" alt=""><figcaption></figcaption></figure>

### Risultato

Quando l’utente seleziona “Beneficiario del servizio”:

* i dati anagrafici del richiedente vengono copiati automaticamente nel beneficiario;
* eventuali modifiche successive vengono sincronizzate automaticamente.

Se viene selezionato un altro valore la sincronizzazione non viene eseguita.

<div><figure><img src="/files/hKX2KW6VESViBVJFOVw9" alt=""><figcaption></figcaption></figure> <figure><img src="/files/EY1BFnO2pV11JmIlWjZr" alt=""><figcaption></figcaption></figure></div>

</details>

<details>

<summary>Controllo della residenza o del domicilio</summary>

Usa questo controllo per verificare la residenza o il domicilio del beneficiario.

Se la condizione non è rispettata, il form viene bloccato.

{% hint style="info" %}
Nell'esempio seguente il controllo verifica se il beneficiario è residente nel Comune. Se la condizione non è rispettata viene mostrato un messaggio di alert e il form non può essere inviato.
{% endhint %}

### Come configurarlo

Segui questi passaggi per mostrare un messaggio di errore e bloccare l’invio quando il beneficiario non risulta residente nel Comune.

#### Passaggio 1 — Recupera il Comune corrente

Aggiungi un componente <mark style="color:$success;">`Hidden`</mark> con property\_name `residence_tenant`.

Nel campo **Data** → **Calculated Value** inserisci questo codice:

```javascript
if (!value) { 
  window.FormioHelper.getTenantInfo().then((info) => {
    instance.setValue(info.name.toLowerCase());
  });
}
```

Questo campo recupera automaticamente il Comune corrente e lo salva in minuscolo. Il valore viene poi usato dal controllo per confrontare il Comune del beneficiario con quello del servizio.

<div><figure><img src="/files/FIhjP22W2YGwCUEvTr6l" alt=""><figcaption></figcaption></figure> <figure><img src="/files/XUCTbwo6gB4BWk1NQwGt" alt=""><figcaption></figcaption></figure></div>

#### Passaggio 2 — Aggiungi il componente Columns

Inserisci un componente <mark style="color:$success;">`Columns`</mark>.

Questo componente serve da contenitore per il messaggio di errore e per la checkbox che blocca l’invio del form.

#### Passaggio 3 — Configura il messaggio di avviso

All’interno del componente <mark style="color:$success;">`Columns`</mark>, aggiungi un componente <mark style="color:$success;">`HTML Element`</mark>.

Nel contenuto del componente inserisci il messaggio da mostrare quando il beneficiario non rispetta il controllo. Ad esempio: *“Attenzione! Non puoi inviare questa pratica, il beneficiario deve essere residente nel Comune.”*

<figure><img src="/files/cVFVsvlcQvYU3oicP32L" alt=""><figcaption></figcaption></figure>

#### Passaggio 4 — Configura la checkbox che blocca l’invio

Sempre all’interno del componente <mark style="color:$success;">`Columns`</mark>, aggiungi una <mark style="color:$success;">`Checkbox`</mark>.

Nel componente imposta come property\_name `fail_applicant` , attiva i check **disabled** e **required** e come Custom CSS Classe inserisci "**d-none**"**.**

La checkbox non deve poter essere selezionata dall’utente. In questo modo, quando il blocco viene mostrato, il form non può essere inviato.

<figure><img src="/files/zTCIGSIsgY654imzAGIV" alt=""><figcaption></figcaption></figure>

#### Passaggio 5 — Applica il controllo al componente Columns

Dopo aver configurato il messaggio e la checkbox, apri il componente <mark style="color:$success;">`Columns`</mark> e vai nella sezione **Conditional** → **Advanced Conditions** → **JavaScript**

Qui devi incollare il codice di controllo riportato sotto. In questo modo l’intero blocco compare solo quando il Comune di residenza del beneficiario non supera il controllo.

{% code expandable="true" %}

```javascript
const residenceFields = [
 "beneficiary.data.address.data.address_locality"
]

show = window.FormioHelper.checkResidences(
 data, residenceFields
)
```

{% endcode %}

Il codice verifica il comune di residenza inserito che corrisponde al campo `beneficiary.data.address.data.address_locality`.

<figure><img src="/files/dgRUk3Xxp2yPIzxsgp1P" alt=""><figcaption></figcaption></figure>

### Come estendere il controllo al domicilio

Se vuoi considerare anche il domicilio, aggiorna la configurazione con questi passaggi.

#### Passaggio 1 — Aggiungi una domanda sul domicilio

Inserisci una domanda, per esempio **“Il domicilio è diverso dalla residenza?”**.

Puoi usare un componente che permetta una scelta chiara, come un radio button.

<figure><img src="/files/cjuq6oOmJctxa8OVi6h5" alt=""><figcaption></figcaption></figure>

#### Passaggio 2 — Mostra il Nested Form del domicilio

Se la risposta è “sì”, mostra un HTML con un messaggio informativo che richieda l’inserimento del domicilio e il Nested Form dedicato, per esempio **OC-Residenza**.

{% hint style="info" %}
Per far comparire questi componenti solo nel caso la risposta sia "sì", imposta un **conditional simple** sia sul messaggio informativo sia sul Nested Form. Per rivedere come configurare questo tipo di condizione, consulta [Relazione tra i dati: i conditional](/guida-alla-creazione-dei-servizi-digitali/creare-un-servizio/le-funzioni/relazione-tra-i-dati-i-conditional.md#condizionale-semplice).
{% endhint %}

Nel Nested Form imposta come property name `domicile`.

<figure><img src="/files/UA9fvDzgxaG5XU74BJoC" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/eBRYqh4erd0vd14rhGS4" alt=""><figcaption></figcaption></figure>

#### Passaggio 3 — Aggiorna il controllo JavaScript

Nel codice del componente **Columns** che contiene il messaggio di errore e la checkbox che blocca l’invio del form, aggiungi anche il campo del domicilio all’elenco dei campi da verificare.

{% code expandable="true" %}

```javascript
const residenceFields = [
 "beneficiary.data.address.data.address_locality",
 "domicile.data.address_locality"
]

show = window.FormioHelper.checkResidences(
 data, residenceFields
)
```

{% endcode %}

Se la domanda “Il domicilio è diverso dalla residenza?” è valorizzata “si”, il campo `domicile` viene incluso nella verifica.

### Esito del controllo

Se il beneficiario è residente nel Comune, oppure è domiciliato nel Comune quando hai esteso anche questo controllo:

* il messaggio di avviso resta nascosto;
* il form può essere compilato e inviato.

<div><figure><img src="/files/2OjG1XIEKc4eRh9k4NVA" alt=""><figcaption></figcaption></figure> <figure><img src="/files/34aN8zQmL0Bv1Cp2Q7Uv" alt=""><figcaption></figcaption></figure></div>

Se il beneficiario non è residente nel Comune (e non è nemmeno domiciliato nel Comune se hai esteso anche questo controllo):

* viene mostrato il messaggio di errore;
* il form non può essere inviato.

<figure><img src="/files/wr3iHXGzThEBUt1TcuFR" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary>Controllo dell’età</summary>

Usa questo controllo per verificare un requisito anagrafico. Se il limite non è rispettato, viene mostrato un errore e il form si blocca. Può essere utilizzato, ad esempio, per:

* limitare l'accesso a un servizio in base all'età;
* mostrare messaggi informativi o di avviso;
* validare i requisiti anagrafici previsti da una procedura o da un bando.

***

### Età del beneficiario

Ad esempio, se un servizio è riservato a beneficiari con meno di 65 anni, puoi configurare un controllo automatico sull'età del beneficiario.

{% hint style="info" %}
Nell'esempio seguente, se il beneficiario supera i 65 anni viene mostrato un messaggio di errore e il form non può essere inviato.
{% endhint %}

### Come configurarlo

Segui questi passaggi per mostrare un messaggio di errore e bloccare l’invio quando il beneficiario supera il limite di età previsto.

#### Passaggio 1 — Aggiungi il componente Columns

Inserisci un componente [<mark style="color:$success;">`Columns`</mark>](/guida-alla-creazione-dei-servizi-digitali/creare-un-servizio/i-componenti/i-columns.md).

Questo componente serve da contenitore per il messaggio di errore e per la checkbox che blocca l’invio del form.

#### Passaggio 2 — Configura il messaggio di avviso

All’interno del componente <mark style="color:$success;">`Columns`</mark>, aggiungi un componente <mark style="color:$success;">`HTML Element`</mark>.

Nel contenuto del componente inserisci il messaggio da mostrare quando il beneficiario non rispetta il requisito anagrafico. Ad esempio: *“Attenzione! Non puoi inviare questa pratica, l’età del beneficiario supera il limite d’età richiesto”*.

<figure><img src="/files/8elNBmhwjDiwWof2ySfa" alt=""><figcaption></figcaption></figure>

#### Passaggio 3 — Configura la checkbox che blocca l’invio

Sempre all’interno del componente <mark style="color:$success;">`Columns`</mark>, aggiungi una <mark style="color:$success;">`Checkbox`</mark>.

Nel componente imposta come property\_name `fail_applicant` , attiva i check **disabled** e **required** e come Custom CSS Classe inserisci "**d-none**"**.**

La checkbox non deve poter essere selezionata dall’utente. In questo modo, quando il blocco viene mostrato, il form non può essere inviato.

<figure><img src="/files/t3jaFZ5KjJLm6BAwnt1v" alt=""><figcaption></figcaption></figure>

#### Passaggio 4 — Applica il controllo al componente Columns

Dopo aver configurato il messaggio e la checkbox, apri il componente <mark style="color:$success;">`Columns`</mark> e vai nella sezione **Conditional** → **Advanced Conditions** → **JavaScript**.

Qui devi incollare il codice di controllo riportato sotto. In questo modo l’intero blocco compare solo quando l’età del beneficiario supera il limite che hai definito.

{% code expandable="true" %}

```javascript
const dateOfBirth = data.beneficiary?.data?.birth_date || ""
const dob = moment(dateOfBirth, 'DD/MM/YYYY')
const age = moment().diff(dob, 'years')
show = (age > 65)
```

{% endcode %}

Il codice legge la data di nascita del beneficiario, calcola l’età e mostra il blocco solo se il valore supera la soglia impostata.

<figure><img src="/files/DJfR2zyZtoIQvIyN4XGm" alt=""><figcaption></figcaption></figure>

### Risultato

Se il beneficiario ha più di 65 anni:

* viene visualizzato il blocco informativo;
* la checkbox diventa obbligatoria ma, non essendo selezionabile, impedisce la prosecuzione del form.

<div><figure><img src="/files/wFgXO3jAuL2aVwOTeH6R" alt=""><figcaption></figcaption></figure> <figure><img src="/files/HYekutdrKgLvnj7gwpBx" alt=""><figcaption></figcaption></figure></div>

In caso contrario, il blocco informativo rimane nascosto.

<div><figure><img src="/files/PZIDQCvws4BwDTEKluBw" alt=""><figcaption></figcaption></figure> <figure><img src="/files/3ytmSLhCkP1oE4CeSqlM" alt=""><figcaption></figcaption></figure></div>

***

### Età del figlio selezionato in OC - Figli

Se il servizio riguarda un figlio selezionato dall'utente tramite una [select](/guida-alla-creazione-dei-servizi-digitali/creare-un-servizio/i-componenti/la-select.md), il controllo sull'età va applicato al figlio e non al beneficiario principale.

In questo caso i figli sono inseriti tramite il nested form **OC - Figli** e l'utente ne seleziona uno tramite una select (`select_child`). Il codice per recuperare la data di nascita legge i dati direttamente dal figlio selezionato, non dal beneficiario.

{% hint style="info" %}
Per capire come impostare la select che recupera i figli vedi la sezione "[Popolare una select da un Datagrid](#popolare-una-select-da-un-datagrid)"
{% endhint %}

### **Come configurarlo**

Segui gli stessi passaggi descritti per il controllo sull'età del beneficiario. Al **Passaggio 4**, sostituisci il codice con quello riportato di seguito.

```javascript
const child = data?.select_child || {}
const dob = moment(child.birth_date, 'DD/MM/YYYY')
const age_years = moment().diff(dob, 'years')
show = dob.isValid() ? !(age_years >= 1 && age_years <= 3) : false
```

Il codice recupera la data di nascita del figlio selezionato nella select, verifica che la data sia valida e mostra il blocco solo se l'età non rientra nell'intervallo previsto (nell'esempio: da 1 a 3 anni).

{% hint style="info" %}
&#x20;Adatta i valori dell'età in base ai requisiti del tuo servizio.&#x20;
{% endhint %}

***

### Età inserita manualmente (fuori da un nested form)

Se il servizio prevede l'inserimento diretto di una data di nascita tramite un componente [Data](/guida-alla-creazione-dei-servizi-digitali/creare-un-servizio/i-componenti/le-date.md#configurare-le-date), puoi validare il valore direttamente nel componente, senza usare le logiche.

Nella sezione **Validation** del componente Data, compila la voce **Custom validation** con il codice JavaScript di verifica.

Nell'esempio seguente, il controllo verifica che la data inserita appartenga a un minorenne:

```javascript
date = moment(input, 'DD/MM/YYYY')
if (date.isAfter(moment())) {
  valid = "La data non può essere nel futuro"
} else {
  if (moment().diff(date, 'years') > 18) {
    valid = "L'età inserita non è quella di un minorenne"
  }
}
```

{% hint style="info" %}
A differenza dei controlli precedenti, questo approccio va configurato direttamente nella sezione **Validation** del componente Data, non tramite le logiche condizionali.&#x20;
{% endhint %}

</details>

<details>

<summary>Popolare una select da un Datagrid</summary>

Usa questo controllo per popolare automaticamente una select con i dati di un Datagrid inseriti all'interno di un Nested Form.

{% hint style="info" %}
Questa funzione può essere usata nei casi in cui devi far scegliere all’utente un elemento già inserito in un [Nested Form](/guida-alla-creazione-dei-servizi-digitali/creare-un-servizio/i-componenti/i-nested-form.md), per esempio un figlio, un veicolo o un immobile.
{% endhint %}

#### Use case — Selezionare un figlio

Nell’esempio seguente il componente `Select` mostra l’elenco dei figli inseriti nel Datagrid del Nested Form OC - Figli e l’utente può selezionare uno dei soggetti già compilati.

### Come configurarlo

Configurare un componente:

* <mark style="color:$success;">`Nested Form`</mark> per i dati dei figli, selezionando il Nested form OC - Figli
* <mark style="color:$success;">`Select`</mark> con label "Seleziona il figlio che vuoi iscrivere" con property\_name `select_child`

<figure><img src="/files/r5cGU4YQ5Y29I0p6HgIu" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/k7zUHGVEdhRfpTgHFZ85" alt=""><figcaption></figcaption></figure>

### Dove inserire il codice

Apri il componente <mark style="color:$success;">`Select`</mark> e vai nella sezione **Data**.

#### Passaggio 1 — Imposta la sorgente dati

Nel campo **Data Source Type** seleziona `Custom`.

#### Passaggio 2 — Inserisci i valori della select

Nel campo **Custom Values** incolla questo codice:

```javascript
values = data.children?.data?.children || []
```

In questo modo la select recupera i dati presenti nel Datagrid del Nested Form.

#### Passaggio 3 — Definisci come mostrare ogni voce

Nel campo **Item Template** incolla questo codice:

```javascript
<span>{{ item.given_name }} {{ item.family_name }}</span>
```

In questo esempio, ogni opzione della select mostra nome e cognome del figlio.

#### Passaggio 4 — Aggiorna la lista quando cambiano i dati

Nel campo **Refresh Options On** seleziona **I tuoi figli**.

In questo modo la select aggiorna automaticamente le opzioni ogni volta che il contenuto del Nested Form cambia.

<figure><img src="/files/3R2kheuuuo8aG7oMaW13" alt=""><figcaption></figcaption></figure>

#### Use case — Selezionare un veicolo

Puoi usare la stessa configurazione anche per far scegliere un veicolo già inserito nel Nested Form **OC - Veicoli.**

Configura questi componenti:

* <mark style="color:$success;">`Nested Form`</mark> per i dati dei veicoli, selezionando il Nested Form **OC - Veicoli**
* <mark style="color:$success;">`Select`</mark> con label "Seleziona il veicolo per cui richiedi il permesso"

In questo caso in **Costum Values** inserisci il codice:

{% code expandable="true" %}

```javascript
values = data.vehicles?.data?.vehicles || []
```

{% endcode %}

Nel campo **Item Template** mostra la targa:

{% code expandable="true" %}

```javascript
<span>{{ item.license_plate_number }}</span>
```

{% endcode %}

#### Use case — Selezionare un immobile

Puoi usare la stessa logica anche per far scegliere un immobile già inserito nel Nested Form **OC - Immobili.**

Configura questi componenti:

* <mark style="color:$success;">`Nested Form`</mark> per i dati degli immobili, selezionando il Nested Form **OC - Immobili**
* <mark style="color:$success;">`Select`</mark> con label "Seleziona l'immobile per cui fai la richiesta"

In questo caso in **Costum Values** inserisci il codice:

{% code expandable="true" %}

```javascript
values = data.real_estate?.data?.real_estate || []
```

{% endcode %}

Nel campo **Item Template** mostra la targa:

{% code expandable="true" %}

```javascript
<span>{{ item.description }}</span>
```

{% endcode %}

### Risultato

La Select viene popolata automaticamente con i dati presenti nel Datagrid del Nested Form.

In particolare:

* vengono mostrati nome e cognome dei figli o le targhe dei veicoli o la denominazione degli immobili;
* la lista si aggiorna automaticamente ad ogni modifica del Datagrid;
* l’utente può selezionare un elemento già inserito senza reinserire i dati.

<figure><img src="/files/fBDZAqlvdTehGRdf5t6R" alt=""><figcaption></figcaption></figure>

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.opencityitalia.it/guida-alla-creazione-dei-servizi-digitali/creare-un-servizio/le-funzioni/configurare-logiche-avanzate-nel-modulo-del-servizio.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
