==== Progettazione ==== * [[grid_albero#Struttura|Struttura]] * [[proggridalbero#Guida|Guida]] * [[grid_albero#Model| Codice nel Model]] * [[grid_albero#menLib|Codici in menLib]] * [[proggridalbero#Funzione GetMenu|Funzione GetMenu]] * [[proggridalbero#Funzione caricaTreeLegami|Funzine caricaTreeLegami]] \\ ---- \\ === Struttura === Come abbiamo già visto il treeGridModel utilizzato è quello Adjacency.\\ E' importante definire, nella parte di programmazione, che comportamento dovranno assumere i vari campi.\\ Le possibili configurazioni sono: * **Level :** Che assume valori integer, e indica il livello di profondità * **Parent :** Indica ,nell'array, l'indice del padre. Quale livello è padre. (Assume anche esso valori integer) * **isLeaf :** * **true:** Indica se è o meno una foglia. Nota. La foglia è l'ultimo elemento dell'albero, quindi non è chiaramente espandibile. * **false:** Se impostato indica che l'elemento non è una foglia. * **loaded :** * **true:** Se impostato appena viene caricata la grid, vengono anche visualizzate le foglie. * **false:** Se impostato appena viene caricata la grid, non verranno visualizzate le varie foglie del parent, quindi sarà necessario un click per visualizzare le varie foglie. * **expanded :** * **true:** Se impostato si avrà l'effetto grid ad albero. * **false:** Se impostato false , la tabella non visualizzerà nulla, perchè ,come definito da programma utilizzando l'Adjacency Model, il programma si aspetta un effetto ad "albero". **Nota.**\\ Se si vuole ottenere un effetto ad albero, dove vengono visualizzate automaticamente i nodi e le loro foglie, è necessario impostare sia **Expanded** che **Loaded** in "True". Se almeno uno dei 2 risulterà falso l'effetto sarà lo stesso: verrà visualizzato solo il nodo principale. \\ \\ ===== Guida ===== ===Model=== **Esempio:**\\ Nel Programma andremo a chiamare la funzione **getMenu** dalla libreria **menLib**.\\ Il risultato chiaramente poi finirà nell'array per costruire la Grid.\\ ..... $this->tree = $this->menLib->getMenu($voceMenu, $only_menu = false, $gruppo, $return_model = 'adjacency', $filtro = false); $arr = array('arrayTable' => $this->tree, 'rowIndex' => 'idx'); $griglia = new TableView($this->tableId, $arr); $griglia->setPageNum(1); $griglia->setPageRows('1000'); .... \\ ------ \\ === Libreria: menLib === Nella libreria menLib troveremo chiaramente molte funzioni, ma ce ne interessano 2 in particolare: * [[proggridalbero#Funzione getMenu|Funzione getMenu]] * [[proggridalbero#Funzione caricaTreeLegami|Funzione caricaTreeLegami]] \\ == Funzione getMenu == public function getMenu($root = 'TI_MEN', $only_menu = false, $gruppo = '', $return_model = 'adjacency', $filtro = true) { $inc = 0; $albero = array(); $albero[$inc]['INDICE'] = $inc; \\ Nella funzione getMenu possiamo notare che:\\ **$inc** viene settato a **0**\\ Viene dichiarato l'array **$albero** e gli viene attribuito il valore **$inc** nel campo **'INDICE'** di **$inc.**\\ In questo caso avremo nell'array:\\ * [0] * ↳ INDICE = 0 \\ \\ Successivamente dovremo impostare alcuni campi obbligatori: **'level','parent','isLeaf','expanded','loaded'** \\ \\ ..... $albero[$inc]['INDICE'] = $inc; $albero[$inc]['level'] = 0; //Imposta il livello 0 $albero[$inc]['parent'] = NULL; // Imposta il parent nullo perchè è il primo nodo $albero[$inc]['isLeaf'] = 'false'; // Non è una foglia, essendo il primo nodo che avremo $albero[$inc]['expanded'] = 'true'; //Rende l'albero espandibile $albero[$inc]['loaded'] = 'true'; // Carica le foglie insieme all'albero Dopo di che possono essere impostatati anche gli altri campi all'interno dell'array : \\ ...... $albero[$inc]['loaded'] = 'true'; // Carica le foglie insieme all'albero $albero[$inc]['pm_voce'] = $root; $albero[$inc]['me_id'] = $chiave; $albero[$inc]['pm_id'] = $pm_id; $albero[$inc]['pm_descrizione'] = $pm_descrizione; $albero[$inc]['pm_sequenza'] = 0; $save_count = count($albero); Alla fine dell'impostazione dei campi, possiamo notare **"$save_count = count($albero);"**.\\ La variabile **$save_count** viene quindi settata con il conteggio totale delle righe in **$albero**, che servirà più avanti come controllo.\\ \\ A questo punto ci servirà richiamare un'altra funzione, per definire i vari legami tra i livelli:, la funzione **creaTreeLegami** contenuta sempre nella libreria menLib. $albero = $this->caricaTreeLegami($chiave, $albero, 1, $inc, $only_menu, $filtro); if ($save_count == count($albero)) { $albero[$inc]['isLeaf'] = 'true'; } return $albero; } In questo esempio possiamo notare che nell'assegnazione dei valori della funzione caricaTreeLegami: * al campo **$level** assegna il valore 1 (1 perchè in questo esempio è il livello successivo al primo parent (0), ma è possibile inserire anche un autoincrementazione ) * al campo **$parent** assegna il valore **$inc,** ($inc perchè vi è contenuto il valore del parent iniziale, che in questo caso è 0) \\ La condizione ci serve per capire se abbiamo un risultato dalla funzione. Infatti potrebbe essere che non ci sia nessun sottolivello e che quindi il primo livelo (0 in questo caso) sia solo una foglia, viene quindi impostato in isLeaf = True.\\ \\ \\ ==Funzione caricaTreeLegami== La funzione caricaTreeLegami è una funzione ricorsiva che: - ispeziona un gruppo di dati, - scorre la tabella estratta, - si ripete se trova altri sottolivelli. In breve stabilisce quali record nell'array sono dei "Rami" e quali le "foglie". public function caricaTreeLegami($chiave, $albero, $level, $indice, $only_menu = false, $filtro = true) { if ($level == 10) { // Impostato a 10 perchè è praticamente impossibile che si arrivi ad avere più di 10 livelli. return $albero; } $sql = "SELECT * FROM ita_puntimenu WHERE me_id = '" . $chiave . "' ORDER BY pm_sequenza"; $Ita_puntimenu_tab = ItaDB::DBSQLSelect($this->ITALSOFT_DB, $sql, true); if ($Ita_puntimenu_tab) { foreach ($Ita_puntimenu_tab as $i => $Ita_puntimenu_rec) { if ($only_menu && $Ita_puntimenu_rec['pm_categoria'] != 'ME') { continue; } In questa prima parte di codice, possiamo notare un primo controllo: **if ($level == 10)**, per evitare che la ricorrenza avvenga all'infinito.\\ \\ In questo esempio si vedono chiaramente anche una **SELECT** e un foreach.\\ All'interno di quest'ultimo è possibile notare una if, dove viene controllato se il campo **$only_menu** e il campo **'pm_categoria'** nel record **ita_puntimenu_rec** non sono di tipo **ME** (Menu).\\ Nell'esempio questo controllo è utilizzato per capire se il record che sta passando è o meno una Foglia. \\ All'interno del **foreach** continueremo con l'impostazione dei campi obligatori, per quanto riguarda l'impostazione delle foglie:\\ \\ \\ ..... continue; } $inc = count($albero); $albero[$inc] = $Ita_puntimenu_rec; $albero[$inc]['INDICE'] = $inc; $albero[$inc]['level'] = $level; $albero[$inc]['parent'] = $indice; $albero[$inc]['expanded'] = 'false'; $albero[$inc]['loaded'] = 'false'; $albero[$inc]['isLeaf'] = 'true'; Possiamo notare che la variabile **$inc** viene settata con il conteggio totale dei record in **$albero**.\\ \\ Successivamente, sempre all'interno del **foreach**, verrà controllato se il rercord che sta passando è o meno un menu :\\ ..... $albero[$inc]['isLeaf'] = 'true'; if ($Ita_puntimenu_rec['pm_categoria'] == 'ME') { $albero[$inc]['isLeaf'] = 'false'; $sql = "SELECT * FROM ita_menu WHERE me_menu = '" . $Ita_puntimenu_rec['pm_voce'] . "'"; $Ita_menu_giu_rec = ItaDB::DBSQLSelect($this->ITALSOFT_DB, $sql, false); $me_id = $Ita_menu_giu_rec['me_id']; Nel caso in cui si tratti di un **Menu**, possiamo subito notare l'impostazione del campo obbligatorio **'isLeaf'**definita **false**, in quanto si tratta di un Nodo e non una foglia.\\ E' inoltre presente una **Select**, che assegnerà alla variabile $me_id il valore **'me_id'** risultante dalla query. \\ Dopo di che verrà salvato il conteggio totale in **$save_count** dei record contenuti in **$albero** e la funzione avrà un "autorichiamo": .... $me_id = $Ita_menu_giu_rec['me_id']; $save_count = count($albero); $albero = $this->caricaTreeLegami($me_id, $albero, $level + 1, $inc, $only_menu, $filtro); if ($save_count == count($albero)) { $albero[$inc]['isLeaf'] = 'true'; } } } } return $albero; } Possiamo notare che nell'assegnazione della funzione ricorsiva i valori **$chiave,$level** e **$parent** subiscono delle variazioni: \\ * alla variabile **$chiave** viene assegnato il valore **$me_id** * la variabile **$level** viene incrementata di **1** * e alla variabile **$parent** viene assegnato il valore contenuto in **$inc** Viene inoltre riutilizzata la condizione **if ($save_count == count($albero))** che come prima ha il compito di controllare se il risultato è differente( quindi nuovo livello) o non è variato (quindi foglia). Infine vi è il ritorno di $albero : **return $albero;** Per concludere: ..... $this->tree = $this->menLib->getMenu($voceMenu, $only_menu = false, $gruppo, $return_model = 'adjacency', $filtro = false); $arr = array('arrayTable' => $this->tree, 'rowIndex' => 'idx'); $griglia = new TableView($this->tableId, $arr); $griglia->setPageNum(1); $griglia->setPageRows('1000'); .... **tree** a questo punto contiene tutto il nostro albero.\\ Come è già stato detto in precedenza nel Generetor il nostro elemento è stato definito treeGrid, e attraverso la selezione del 'arrayTable' e la funzione TableView , il nostro albero verrà inserito nella grid.