# Finestre Modali e Finestre Flottanti — Framework _main.6.2

Questo documento spiega il sistema di finestre del backend basato su `_main.6.2`, con focus su:

- **Finestre modali overlay** (`openModalWindow`)
- **Finestre flottanti full** (`openWindowX` / `openWindow`)
- **Come creare un nuovo modulo woverlay**
- **Pattern di callback (ritorno dati al frame chiamante)**

---

## 1. Finestre Modali Overlay (`openModalWindow`)

Le finestre modali aprono un pannello sovrapposto alla UI corrente, senza aprire una vera finestra separata. Sono ideali per form di selezione, conferme, form brevi.

### Firma della funzione

```javascript
openModalWindow(title, _SEZ, strparams, idFinestraCaller, tipo = 0)
```

| Parametro         | Tipo     | Descrizione                                                                 |
|-------------------|----------|-----------------------------------------------------------------------------|
| `title`           | string   | Titolo mostrato nell'header del pannello overlay                            |
| `_SEZ`            | string   | Codice sezione, gestito in `woverlay.php` (es. `tracking.setCellsApCorr`)  |
| `strparams`       | string   | Parametri querystring aggiuntivi passati al contenuto (es. `id=5&mode=1`)  |
| `idFinestraCaller`| int/var  | ID della finestra corrente (`$id_finestra` in PHP, usato per il callback)  |
| `tipo`            | int      | Tipo overlay: `0` = standard con auto-close su cambio frame padre          |

### Implementazione interna (`jscode.js.php`)

```javascript
function openModalWindow(title, _SEZ, strparams, idFinestraC, tipo = 0) {
    top.showlayer('main_woverlay');
    top.setTextinDiv('cnt_woverlay_title', title);
    top.document.frmmenuw._SEZ.value = _SEZ;
    top.document.frmmenuw.strparam.value =
        'idFinestraCaller=' + idFinestraC + '&ModalW=' + tipo + '&' + strparams;
    top.document.frmmenuw.submit();
}
```

Il form `frmmenuw` viene sottomesso con la sezione e i parametri; il server carica il file `woverlay.php` che fa `switch ($_SEZ)` e restituisce il contenuto.

### Esempio di utilizzo in PHP/JS

```php
// In un file PHP che renderizza JS (il $id_finestra è quello della finestra corrente)
function openAPC(c) {
    openModalWindow(
        'Correlazioni cella/apparato',   // titolo
        'p.setCellsApCorr',              // _SEZ → case in woverlay.php
        'id_location=<?=$id_location?>&cell=' + c,  // parametri
        <?=$id_finestra?>,               // ID finestra chiamante
        0                                // tipo
    );
}
```

---

## 2. Finestre Flottanti (`openWindowX` / `openWindow`)

Le finestre flottanti sono finestre vere e proprie all'interno del desktop del backend, draggable e resizable, con un iframe interno.

### Firma

```javascript
openWindowX(title, cpTo, szTo, menuw, params, child = 0)
openWindow(title, cpTo, szTo, menuw)
```

| Parametro | Descrizione                                                       |
|-----------|-------------------------------------------------------------------|
| `cpTo`    | Control panel di destinazione (es. `'aiprojects'`)               |
| `szTo`    | Numero di sezione da aprire nella finestra (es. `200`)           |
| `menuw`   | `0` = nessun menu laterale, `1` = con menu laterale             |
| `params`  | Stringa di parametri aggiuntivi separati da `|` (es. `'id:5'`)  |

### Esempio

```javascript
openWindowX(
    'Modifica Progetto',
    'aiprojects',       // cp
    200,                // sezione
    0,                  // menuW
    '_WParent:' + <?=$id_finestra?> + '|id:' + projectId
);
```

Il sistema invoca `ajaxSrv('createWindow', ...)` → `openMyWindow(res)` che aggiunge dinamicamente la finestra al DOM e la gestisce con z-index, drag, resize.

---

## 3. File `woverlay.php`

Questo è il router del contenuto delle finestre modali.

**Percorso:** `_inc/woverlay.php`

### Struttura

```
woverlay.php
│
├── switch ($_SEZ)  ← cases incorporati direttamente
│   ├── case "note_pagamento": ...
│   └── ...
│
└── include per moduli opzionali:
    ├── if ($_modulo['crm']   == '1') include "modules/crm/crm.woverlay.php";
    ├── if ($_modulo['digital']=='1') include "modules/digital/digital.woverlay.php";
    ├── if ($_modulo['tracking']=='1') include "modules/tracking/tracking.woverlay.php";
    └── include($incpathgeneral . "modules/aiprojects/aiprojects.woverlay.php"); ← sempre incluso con file_exists
```

> **Nota path:** I moduli built-in usano path relativi (`"modules/..."`) perché `woverlay.php` è nella cartella `_inc/` della webapp. I moduli aggiunti successivamente devono usare la variabile `$incpathgeneral` per avere il path assoluto corretto.

---

## 4. Creare un Nuovo Modulo Woverlay

### Passo 1 — Creare il file woverlay del modulo

`_inc/modules/MIOMODULO/MIOMODULO.woverlay.php`

```php
<?php

switch ($_SEZ) {

    case "MIOMODULO.miaAzione":
    {
        // Logica PHP per preparare i dati
        // (usa $idFinestraCaller per il callback)

        if ($azione == 'save') {
            // ... salvataggio ...
        }
        ?>
        <div style="padding:12px;">
            <!-- HTML del contenuto del modal -->
            <p class="admtitolo">Titolo contenuto</p>
            <!-- form, bottoni, lista, ecc. -->
        </div>

        <form name="frm1" action="<?= $action ?>" method="POST">
            <input type="hidden" name="cp"              value="<?= $cp ?>">
            <input type="hidden" name="MSID"            value="<?= $MSID ?>">
            <input type="hidden" name="_SEZ"            value="<?= $_SEZ ?>">
            <input type="hidden" name="sezione"         value="<?= $sezione ?>">
            <input type="hidden" name="azione"          value="">
            <input type="hidden" name="idFinestraCaller" value="<?= $idFinestraCaller ?>">
        </form>

        <script>
        function salva() {
            document.frm1.azione.value = 'save';
            document.frm1.submit();
        }

        // Callback al frame chiamante e chiusura
        function seleziona(valore) {
            <?php if (isset($idFinestraCaller) && $idFinestraCaller > 0): ?>
            var i = findFrame('frameWindow_<?= (int)$idFinestraCaller ?>');
            if (i >= 0) {
                top.frames[i].onModalResult(valore);  // chiama funzione nel frame padre
            }
            top.wclose_();  // chiude il modal
            <?php endif; ?>
        }
        </script>
        <?php
    } break;

}
?>
```

### Passo 2 — Includere in `woverlay.php`

Aggiungere prima del blocco `if(isset($ModalW)...)`:

```php
// Moduli con path assoluto (incpathgeneral):
if (file_exists($incpathgeneral . "modules/MIOMODULO/MIOMODULO.woverlay.php"))
    include $incpathgeneral . "modules/MIOMODULO/MIOMODULO.woverlay.php";
```

### Passo 3 — Chiamare il modal

Nel file PHP del modulo (es. `edit_qualcosa.php`):

```php
// PHP: assicurarsi che $id_finestra sia disponibile nel contesto
```

```javascript
// JS: nel <script> del file
function apriMioModal(param) {
    openModalWindow(
        'Titolo del Modal',
        'MIOMODULO.miaAzione',
        'campo1=' + param,
        <?= $id_finestra ?>,
        0
    );
}

// Callback ricevuta dal modal
function onModalResult(valore) {
    // aggiorna il DOM, i campi form, ecc.
    document.frmins.miocampo.value = valore;
}
```

---

## 5. Pattern Callback (dal Modal al Frame Padre)

Il modal non può usare `window.opener` perché è caricato in un overlay nello stesso contesto `top`. Il sistema usa `findFrame` per raggiungere l'iframe del frame chiamante.

```javascript
// Nel woverlay — invia dati al frame padre e chiude
function restituisciValore(val) {
    var i = findFrame('frameWindow_<?= (int)$idFinestraCaller ?>');
    if (i >= 0) {
        top.frames[i].nomeCallbackNelPadre(val);
    }
    top.wclose_();
}
```

```javascript
// Nel frame padre — riceve i dati
function nomeCallbackNelPadre(val) {
    document.frmins.mioInput.value = val;
    // opzionale: savecfg() o altro submit automatico
}
```

> `findFrame(name)` scorre `top.frames` cercando il frame con il `name` corrispondente a `frameWindow_<id_finestra>`.

---

## 6. Chiudere il Modal

Per chiudere il modal dall'interno del woverlay:

```javascript
top.wclose_();
```

Il modal si chiuderà automaticamente anche se il frame chiamante viene rimosso (`tipo=0` attiva un `setInterval` che monitora la presenza del frame padre).

---

## 7. Variabili Disponibili nei Woverlay

Queste variabili sono automaticamente disponibili all'interno di tutti i case in `woverlay.php` (estratte dalla request via `extract($_REQUEST)`):

| Variabile          | Descrizione                                        |
|--------------------|----------------------------------------------------|
| `$_SEZ`            | Codice sezione corrente                            |
| `$idFinestraCaller`| ID della finestra che ha aperto il modal           |
| `$MSID`            | Session ID                                         |
| `$cp`              | Control panel corrente                             |
| `$sezione`         | Numero sezione del frame chiamante                 |
| `$azione`          | Azione form (es. `save`)                           |
| `$ModalW`          | Tipo modal (`0` = con auto-close watch)            |
| `$action`          | URL di submit del form                             |
| `$incpathgeneral`  | Path assoluto della cartella `_inc/`               |

E tutti i parametri passati in `strparams` alla `openModalWindow`.
