Un tipico esempio di utilizzo di un multicheckbox o di una multiselect si ha quando
è necessario creare una maschera per una tabella di relazione N:N. Nel framework P4A è possibile implementare entrambi i tipi di oggetto.
Il problema è che, come detto in precedenti post, la documentazione non è completa, si rende necessario quindi fare una una ricerca nel forum. In questo thread e in quest'altro, viene spiegato il funzionamento. Sperando di fare cosa gradita, ho cercato di riassumere la procedura in questo esempio pratico.
Dunque, ammettiamo di avere tre tabelle relazionate come nella figura a fianco. L'obiettivo è di poter associare ad ogni fascia uno o più colori. Nella tabella di relazione possono essere presenti N fasce e per ogni fascia N colori.
Per prima cosa creaiamo le tre tabelle:
CREATE TABLE `colori` ( `idcolori` bigint(20) NOT NULL auto_increment, `nome` varchar(255) NOT NULL, `note` varchar(255) default NULL, PRIMARY KEY (`idcolori`), UNIQUE KEY `colori_index_nome` (`nome`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- ----------------------------------------------- CREATE TABLE `fasce` ( `idfasce` bigint(20) NOT NULL auto_increment, `descrizione` varchar(255) default NULL, PRIMARY KEY (`idfasce`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- ----------------------------------------------- CREATE TABLE `fasce_colori` ( `colori_idcolori` bigint(20) NOT NULL, `fasce_idfasce` bigint(20) NOT NULL, PRIMARY KEY (`colori_idcolori`,`fasce_idfasce`), KEY `fasce_colori_FKIndex1` (`colori_idcolori`), KEY `fasce_colori_FKIndex2` (`fasce_idfasce`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
A questo punto è necessario creare le due classi e le maschere per la gestione delle tabelle fasce e colori nel modo standard, che non illustro ma sono presenti nel pacchetto scaricabile.
Possiamo finalmente creare la maschera per la tabella di relazione: fasce_colori nel seguente modo:
class P4A_Fasce_colori extends P4A_Mask
{
function P4A_Fasce_colori()
{
$this->P4A_Mask();
$p4a =& P4A::singleton();
// DB Source
$this->build("p4a_db_source","fasce");
$this->fasce->setTable("fasce");
$this->fasce->setPk("idfasce");
//Filtro il record con idfasce=0 che indica
//tutti i colori e non deve essere modificato
$this->fasce->setWhere("idfasce > 0");
$this->fasce->setPageLimit(15);
$this->fasce->addMultivalueField("fld_fasce_colori",
"fasce_colori","fasce_idfasce", "colori_idcolori");
$this->fasce->load();
$this->setSource($this->fasce);
$this->setTitle('Gestione fasce colore');
$this->fasce->firstRow();
$this->build("p4a_db_source","colori");
$this->colori->setTable("colori");
$this->colori->setPk("idcolori");
$this->colori->load();
$this->fields->fld_fasce_colori->setType("multicheckbox");
// Oppure se si preferisce la multiselect
//$this->fields->fld_fasce_colori->setType("multiselect");
$this->fields->fld_fasce_colori->setSource($this->colori);
$this->fields->fld_fasce_colori->label->setVisible(false);
//Fieldset con l'elenco dei campi
$this->build("p4a_fieldset", "fset");
$this->fset->setWidth(590);
$this->fset->setTitle("Selezione colori");
$this->fset->anchor($this->fields->fld_fasce_colori);
// Toolbar
$this->build("p4a_simple_toolbar", "toolbar");
$this->toolbar->setMask($this);
$this->toolbar->buttons->new->disable();
// Table
$table =& $this->build("p4a_table", "table");
$table->setWidth(600);
$table->setSource($this->fasce);
$table->setVisibleCols(array("descrizione"));
$table->showNavigationBar();
// Message
$message =& $this->build("p4a_message", "message");
$message->setWidth("300");
// Frame
$frm=& $this->build("p4a_frame", "frm");
$frm->setWidth(600);
$frm->anchorCenter($message);
$frm->anchorCenter($table);
$frm->anchorCenter($this->fset);
// Display
$this->display("main", $frm);
$this->display("menu", $p4a->menu);
$this->display("top", $this->toolbar);
}
}
Notate che la sorgente dati principale è quella della tabella dove agisce il selettore dei record,
nel nostro caso: fasce. L'azione chiave di tutta la procedura è la costruzione
di un campo attraverso il metodo addMultivalueField(),
i quattro parametri passati nell'ordine a questo metodo sono:
- Il nome del nuovo campo
- Il nome della tabella di relazione
- Il nome della chiave esterna che lega la tabella dove agisce il selettore record
- Il nome della chiave esterna che lega la tabella che funge da sorgente dati per il nuovo campo
Richiamando il metodo saveRow() le query di aggiornamento e inserimento verranno automaticamente eseguite dal P4A framework engine senza dover scrivere ulteriori righe di codice!
Download:
Il pacchetto completo è scaricabile qui
Conclusioni:
Il setup del codice necessario all'utilizzo di multicheckbox e multiselect è semplice ma poco documentato, il suo utilizzo è potente e fa risparmiare parecchio tempo.
Riferimenti ed approfondimenti:

Hi,
I had try the source code and i have this error: Method p4a not found
test_mckbox.php line 43.
Have you some idea?
Thanks for your contributions to P4A.
--
Jesus
@ Jesus: check your P4A version, this code only works on P4A 2.x. Since P4A version 2.9.x (R.C.) all the engine has been changed, loosing back compatibility.