Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Ext.js: il componente Panel

Usare il componente Panel di questo potente framework Javascript
Usare il componente Panel di questo potente framework Javascript
Link copiato negli appunti

Abbiamo conosciuto  Ext e abbiamo intravisto le sue  potenzialità; abbiamo steso le basi per superare i primi due grandi ostacoli: impaginazione e personalizzazioni; ora possiamo cominciare a sviluppare tutto ciò che ci viene in mente o ci viene richiesto. Per far questo abbiamo bisogno di conoscere uno ad uno gli elementi che compongono la nostra libreria e metterli nella classica cassetta degli attrezzi per poi poter essere capaci di scegliere lo strumento giusto a seconda dell'applicazione che stiamo sviluppando.

Lo scopo di questo articolo in due parti è quello di introdurre l'utilizzo degli oggetti Ext.Panel ed Ext.Window. Alla fine di questi due articoli, il lettore sarà in grado di stabilire quale dei due oggetti è più consono ai propri scopi, disegnare interfacce che contengono più Panel e Window, personalizzare esempi che assomigliano a complesse formattazioni di pagine di giornale o creare semplici motori che generano Window simili a post-it.

Object Oriented ed Ereditarietà

Le componenti Ext, come abbiamo già detto nei precedenti articoli, sono molte e tutte disegnate con un orientamento gerarchico ad oggetti. L'oggetto più utile alla base della catena di ereditarietà Ext è il Panel.

Per chi è pratico di programmazione orientate agli oggetti (Java, .NET ad esempio), è facile intravedere le analogie con oggetti tipici della programmazione desktop (Swing / SWT). 

Per chi non conoscesse la programmazione OO (Object Oriented) consigliamo innanzitutto la lettura di qualche pagina di questo articolo su HTML.it:  Pensare Object Oriented; inoltre possiamo semplificare molto i concetti che compongono questa utile tecnica di programmazione rapportando il nostro codice al mondo reale. Tutto cio' che ci circonda (il foglio o il monitor su cui stiamo leggendo queste righe) sono particolari istanze di una generica classe Oggetto. Quando diciamo quindi che Oggetto è un'entità astratta, intendiamo appunto questo: un oggetto può essere esteso ed istanziato in qualsiasi cosa. I concetti di ereditarietà tra oggetti si inseriscono in questo esempio se si pensa che il foglio su cui stiamo leggendo è un particolare foglio, figlio dell'oggetto Carta che a sua volta è figlio dell'oggetto Materiali e così via. Diversi fogli (un A4, una carta da regalo, un post-it) sono specializzazioni di Carta. Per chiudere questa breve carrellata esemplificativa, il foglio che abbiamo in mano è un'istanza che identifica esattamente il foglio che stiamo reggendo, con i suoi attributi che lo diversificano e lo rendono unico rispetto a un altro foglio.

Gli oggetti in Ext

Tornando ad Ext, quindi, leggiamo insieme l'albero genealogico dell'oggetto che ci interessa per comprendere a pieno le sue proprietà. Ogni oggetto deriva da una componente astratta generica chiamata Observable. Questa equivale all'oggetto più astratto che possiamo immaginare e che viene utilizzato come base per costruire altri oggetti. Per agganciarci al nostro esempio, pensiamo al seguente codice:

Foglio = function(name){
   this.name = name;
   this.addEvents({
       "stampa" : true, 
       "archivia" : true,
       "straccia" : true
   });
}
Ext.extend(Foglio, Ext.util.Observable);

Continuando la lettura genealogica del nostro oggetto, incontriamo quella che è la base per tutte le interfacce grafiche Ext: l'oggetto Component.

Ogni Component possiede un attributo xtype, che è il suo Ext-specific type name, e i relativi metodi per identifcarlo: getXType e isXType

Di seguito una lista degli xtypes validi:

xtype            Class
box              Ext.BoxComponent
button           Ext.Button
colorpalette     Ext.ColorPalette
component        Ext.Component
container        Ext.Container
cycle            Ext.CycleButton
dataview         Ext.DataView
datepicker       Ext.DatePicker
editor           Ext.Editor
editorgrid       Ext.grid.EditorGridPanel
grid             Ext.grid.GridPanel
paging           Ext.PagingToolbar
panel            Ext.Panel
progress         Ext.ProgressBar
propertygrid     Ext.grid.PropertyGrid
slider           Ext.Slider
splitbutton      Ext.SplitButton
statusbar        Ext.StatusBar
tabpanel         Ext.TabPanel
treepanel        Ext.tree.TreePanel
viewport         Ext.Viewport
window           Ext.Window

Toolbar components
toolbar          Ext.Toolbar
tbbutton         Ext.Toolbar.Button
tbfill           Ext.Toolbar.Fill
tbitem           Ext.Toolbar.Item
tbseparator      Ext.Toolbar.Separator
tbspacer         Ext.Toolbar.Spacer
tbsplit          Ext.Toolbar.SplitButton
tbtext           Ext.Toolbar.TextItem

Form components
form             Ext.FormPanel
checkbox         Ext.form.Checkbox
combo            Ext.form.ComboBox
datefield        Ext.form.DateField
field            Ext.form.Field
fieldset         Ext.form.FieldSet
hidden           Ext.form.Hidden
htmleditor       Ext.form.HtmlEditor
label            Ext.form.Label
numberfield      Ext.form.NumberField
radio            Ext.form.Radio
textarea         Ext.form.TextArea
textfield        Ext.form.TextField
timefield        Ext.form.TimeField
Trigger          Ext.form.TriggerField

Risaliamo ancora la catena che ci porterà al nostro oggetto e incontriamo BoxComponent, una specializzazione di Component. è la classe base per ogni tipo di Ext.Component che usa contenitori che prendono il nome di box, ovvero forme che contengono HTML. 

BoxComponent fornisce automatismi per la modellazione dei box come il dimensionamento o la posizione. Tutti gli oggetti che contengono HTML devono essere figli (sottoclassi) di BoxComponent in modo che le loro proprietà siano congrue e convivano con gli altri box nel momento in cui andremo a nidificarli uno dentro l'altro per poter ottenere i layout più disparati, utili ai nostri scopi.

Dal nonno, arriviamo finalmente al padre del nostro tanto atteso oggetto, ovvero: Container.  Di default, i Containers usano gli schemi di layout che abbiamo introdotto nei precedenti articoli e che prendono il nome di ContainerLayout. In questo modo le componenti che vanno a nidificarsi l'una nell'altra sfruttano i meccanismi di collocazione nella pagina e possiamo appenderli uno dopo l'altro all'interno del Container, senza preoccuparci delle dimensioni o della convivenza cross-browser degli elementi. 

Arriviamo così, attraverso gli avi, alla componente che da oggi useremo ed estenderemo fino a farla diventare il punto di partenza di ogni nostro disegno di interfaccia: il Panel.

La componente più semplice: il Panel

La classe Ext.Panel, estende Ext.Container ed è alla base di ogni altro tipo di interfaccia. I suoi attributi e le sue peculiarità ci aiutano a identificare il Panel con un ipotetico div/layer in cui suddividere le pagine dei nostri siti e delle nostre applicazioni.

Le potenzialità del Panel si intravedono dalla lista delle sue sottoclassi, ovvero: TabPanel, Tip, Window, FieldSet, FormPanel, GridPanel, TreePanel. Questi sono tutti oggetti che esamineremo, uno per uno, nei prossimi articoli e che ci consentono di strutturare i nostri dati nella forma più utile per ogni tipologia di interazione con l'utente.

Gli attributi di un Panel

Gli attributi che può assumere un panel sono veramente numerosi. Non possiamo elencare all'interno di questo articolo, per motivi di spazio, tutte le caratteristiche del nostro Panel ma provvederemo ad analizzare quelli che riusciremo ad incontrare attraverso il nostro classico esempio.

Immaginiamo che ci venga commissionata una pagina di un ipotetico giornale come quello in figura.

Figura 1 - Screenshot dell'esempio da realizzare
screenshot

Impaginarla in questa maniera, magari rendendo dinamici i contenuti, rimanendo cross-browser e costruendo l'architettura in modo che sia scalabile, ovvero facilmente estendibile avrebbe richiesto esperti CSS e di sviluppo, oltre che un duro lavoro di analisi di compatibilità tra i vari browser.

Grazie ad Ext, una volta disegnata l'architettura della nostra pagina, possiamo identificare il layout più appropriato al nostro scopo e suddividere la nostra pagina nelle sue componenti elementari. Il layout che scegliamo in questo caso è il TableLayout e le componenti elementari sono gli Ext.Panel.

Identificheremo un oggetto generale che conterrà l'intera pagina e lo chiameremo "journal".

var journal = new Ext.Panel({
	id:'journal-panel',
	title: 'La gazzetta del 2.0',
    layout:'table',
	width:800,
	height:700,
	layoutConfig: {
		columns: 4
	},
	frame:true,
    items: [new Ext.Panel({
        title: 'The best test in all site',
		frame:true,
		html: '<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p><br><p>It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.</p>',
		rowspan: 2,
		colspan: 3
    }),new Ext.Panel({
		html: '<center><img src="img/1.png"></center>',
		frame:true
	}),{
			html: '<center><img src="img/2.png"></center>',
		frame:true
	}, ….

Le scatole cinesi

Abbiamo un Panel, che contiene un Panel che ne contiene altri e così via. Gli attributi che possiamo identificare sono pertanto un set che tende a ripetersi. In questo caso, ad esempio, vediamo:

id: identificatore univoco del layer, va a coincidere con l'id del div associato all'HTML generato da Ext per renderizzare il nostro Ext.Panel – di default è un identificativo autogenerato dalla libreria -.

title: il testo del titolo che verrà visualizzato nell'intestazione del pannello (una stringa vuota è il valore di default). Quando un titolo è specificato l'intestazione dell'elemento verrà automaticamente creata e visualizzata a meno che non si dichiari esplicitamente l'attributo header:false.

layout: la disposizione da utilizzare in questo Container. Se non si specifica un Ext.layout.ContainerLayout, verrà visualizzata un'impostazione predefinita. I valori validi sono: absolute, accordion, anchor, border, card, column, fit, form and table. 

width: la larghezza di questa componente in pixel (il default è auto).

height: l'altezza di questa componente in pixel (il default è auto).

layoutConfig: si tratta di un oggetto di configurazione contenente le proprietà specifiche per la scelta del layout. Per maggiori dettagli per quanto riguarda le opzioni di configurazione validi per ogni tipo di layout, consiglio di visualizzare le API di Ext in merito a:

Ext.layout.Absolute

Ext.layout.Accordion

Ext.layout.AnchorLayout

Ext.layout.BorderLayout

Ext.layout.CardLayout

Ext.layout.ColumnLayout

Ext.layout.FitLayout

Ext.layout.FormLayout

Ext.layout.TableLayout

frame: è impostato a true per renderizzare il pannello con uno stile personalizzato con bordi arrotondati e integrato nella grafica generale del pannello; false per renderizzare un pannello generico con il bordo quadrato di 1px (il valore di default è false).

items: un unico elemento o un insieme di componenti figlie che verranno aggiunte al Container principale. Ogni elemento può essere qualsiasi tipo di oggetto che estende Ext.Component. Gli item vengono specificati ognuno dentro a parentesi graffe e tutti racchiusi da due parentesi quadre, cosi': [{…},{…},{…}]. 

Ogni elemento tra parentesi graffe, nel nostro esempio, è a sua volta un Ext.Panel. Si potrebbero definire esternamente alla variabile journal i diversi Ext.Panel che conterranno i vari riquadri della nostra pagina e in seguito inserirli nell'attributo items di journal, separandoli solo da virgole, senza necessità delle parentesi graffe. In pratica items è un Array di oggetti contenuti nell'Ext.Panel. A sua volta ogni oggetto figlio conterrà elementi in items oppure un attributo HTML di seguito descritto.

html: un frammento di HTML, o un DomHelper di Ext (vedremo nei prossimi articoli come si utilizzano queste utility per creare codice HTML direttamente dal Javascript).

Il risultato del nostro lavoro è visibile qui. Disponibile anche il pacchetto zip con il materiale completo.

Attenzione a IE

Colgo l'occasione di questo articolo per presentare il primo di tanti errori curiosi che un programmatore newbie non riuscirebbe a identificare molto semplicemente, data la natura poco chiara del codice di errore che incontriamo nel visualizzare il nostro oggetto Ext in cui è presente il seguente baco di programmazione. 

Figura 2 - Errore
screenshot

Questo errore lo troviamo in Internet Explorer. La dicitura "Impossibile completare l'operazione a causa di un errore 80020101" non è molto esplicativa, né in italiano né in inglese. Credo di risparmiare qualche ora di lavoro ai futuri programmatori Ext facendo loro notare che si tratta di una virgola in più nella nostra lista di attributi o di items. Pare che in questo caso IE pretenda una certa pulizia del codice, infatti, e che, mentre Firefox o Safari o Opera ignorano il fatto che alla fine della nostra lista si presenti una virgola a cui non seguono elementi, il browser di Microsoft si blocca e non renderizza per niente la nostra pagina.

Conclusioni e anticipazioni

Abbiamo diviso il nostro articolo in due parti in modo che i lettori possano metabolizzare i concetti introdotti e il primo esempio di oggetti nidificati uno nell'altro. Nel prossimo articolo esporremo un esempio di oggetti Window che produrranno un effetto di bacheca di post-it.

Ti consigliamo anche