bloggers bloggers

Marco Napolitano
Messaggi: 79
Stelle: 0
Data: 17/02/22
Jader Jed Francia
Messaggi: 63
Stelle: 0
Data: 18/02/21
Paolo Gambetti
Messaggi: 2
Stelle: 0
Data: 11/11/19
Katia Pazzi
Messaggi: 1
Stelle: 0
Data: 27/06/19
Ezio Lombardi
Messaggi: 11
Stelle: 0
Data: 10/04/18
Chiara Mambretti
Messaggi: 25
Stelle: 0
Data: 27/02/17
Serena Traversi
Messaggi: 3
Stelle: 0
Data: 21/07/16
Francesco Falanga
Messaggi: 8
Stelle: 0
Data: 14/06/16
Antonio Musarra
Messaggi: 2
Stelle: 0
Data: 18/11/13
Simone Celli Marchi
Messaggi: 6
Stelle: 0
Data: 09/07/13
Indietro

Il form navigator di Liferay

Spesso mi capita di sviluppare funzionalità in Liferay, specialmente riguardanti l'interfaccia utente, di perdere tantissimo tempo nel perfezionare una routine javascript che faccia sparire un DIV, che ne evidenzi un'altro o che ne posizioni un'altro ancora.

Poi, dopo giorni di lavoro, mi accorgo che c'e' un oggetto in Liferay che fa esattamente quello che voglio, con 2 righe di codice.

E' questo il caso della taglib liferay-ui:form-navigator: è quel box azzurro che si trova alla destra di molte form del pannello di controllo, come ad esempio la gestione utente o la gestione di un site.

Ovviamente l'aspetto grafico è governato dai CSS per cui è utilizzabile anche al di fuori del control panel e personalizzabile come tutto in Liferay.

Per utilizzare il form navigator occorre importare le seguenti taglib:

<%@ taglib uri="http://alloy.liferay.com/tld/aui" prefix="aui" %>

<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>

<%@ taglib uri="http://liferay.com/tld/util" prefix="liferay-util" %>

Il form navigator si usa così nella home.jsp (o comunque si chiami):

<portlet:actionURL name="saveAll" var="saveAll"/>

<aui:form action="<%=saveAll%>" name="form">

<liferay-ui:form-navigator

    backURL="<%=backURL %>"
    categoryNames="<%= categoryNames %>"
    categorySections="<%= categorySections %>"
    formName="form"
    htmlTop="<%=htmlTop %>"
    htmlBottom="<%=htmlBottom %>"
    jspPath="/sections/" 
    showButtons="<%=true %>"
/>
</aui:form>

dove:

backUrl: (opzionale) è la URL associata al pulsante Cancel

categoryNames: è uno String array con le label delle sezioni (nell'esempio, dopo la localizzazione delle label: User Information, Identification, Miscellaneous)

categorySections: è uno String[ ][ ] che contiene le voci di ogni sezione; all'i-esimo categoryName corrisponde l'i-esimo categorySection[ ]. Nell'esempio, categorySections[0]={"details","password","organizations","sites","usergroups","roles","personal_site","categorization"}

formName: (opzionale) il nome della form che racchiude il form-navigator

htmlTop: (opzionale) è il pezzo di codice html che andrà al top del form navigator

htmlBottom: come sopra, ma sotto :-)

jspPath: è il path che contiene i files jsp corrispondenti alle categorySections: nell'esempio, esiste una pagina password.jsp, una pagina organizations.jsp etc; il file si deve chiamare come la stringa contenuta nell'array e non come la sua versione localizzata a schermo.

showButtons:(opzionale) di default a true, serve per visualizzare o nascondere la button bar con Save e Cancel.

In sostanza la taglibcrea un div nascosto per ogni pagina jsp che trova nel jspPath e che corrisponde a una voce di categorySections; poi crea il codice per gestire i click sui link del menù, per evidenziare il link cliccato, visualizzare il div corrispondente e nascondere quello attualmente visualizzato.

Il pulsante Save esegue l'action della form che racchiude il form-navigator (nel mio caso"saveAll"); la form conterrà la somma di tutti gli elementi html inseriti in tutte le categorySections.

Le pagine jsp delle varie sections possono essere complicate a piacere, tanto da poter includere altre form con altre actions, o risultati di ricerca con il search-container, anche paginati etc.

Piccolo problema: se la pagina jsp contiene una form che fa POST su un'action, al ritorno dall'elaborazione il browser atterrerà sulla pagina principale, visualizzando la prima section (questo perchè devo sempre scrivere actionRequest.setRenderParameter("jspPage","home.jsp") e non posso impostare una sottopagina nel renderparameter. Di conseguenza se sto editando, ad esempio, i ruoli dell'utente ad ogni "add" LR ritorna sui dettagli. Il trucco c'e', ma non si vede: con un po' di javascript viene reimpostata la pagina corretta subito dopo, per questo tutto sembra filare liscio.

Purtroppo questa cosa non è automatica, cioè non è inclusa nel taglib del form-navigator, per cui occorre industrarsi un pò.

Studiando, come al solito, il funzionamento del codice html con google chrome, ho visto cheper ogni categorySection il div che contiene la pagina corrispondente ha id<portlet:namespace/>nomeCategorySection

Il link che lo fa apparire ha id<portlet:namespace/>nomeCategorySectionLink

la classe css che fa sparire il div è aui-helper-hidden-accessible,

mentre quella che fa apparire un div o visualizzare il link come selezionato è selected

La mia soluzione prevede che ad ogni action delle varie categorySections venga impostato un request attribute che contiene il nome della pagina da visualizzare.

Ad esempio, nel mio casoesiste una categorySection "video" e una pagina "video.jsp" che contiene a form che invoca l'action saveVideo, la cui ultima istruzione è

actionRequest.setAttribute("page2show","video");

Alla fine della jsp home.jsp che contiene il form navigator ho inserito queste istruzioni jquery:

<script type="text/javascript">
$('#<portlet:namespace/><%=page2show%>').addClass("selected");
$('#<portlet:namespace/><%=page2show%>').removeClass("aui-helper-hidden-accessible");
$('#<portlet:namespace/>primaSection').addClass("aui-helper-hidden-accessible");
$('#<portlet:namespace/>primaSection').removeClass("selected");
$('#<portlet:namespace/>primaSectionLink').parent().removeClass("selected");
$('#<portlet:namespace/><%=page2show%>Link').parent().addClass("selected"); </script>

Nel mio caso "primaSection" è la prima categorySection.

Le ultime 2 istruzioni impostano i link. La struttura del menù html che si vede nell'HTML della paginaè simile alla seguente:

<ul>
<li class="selected">
<a id="<portlet:namespace/>primaSectionLink">
</li>
<li class>
<a id="<portlet:namespace/>videoLink">
</li>
</ul>

La selezione del menù viene implementata con una classe dell'elemento LI (che non ha id)che racchiude il link; a questo sono dovute le due modifiche alle classi css del parent().

In sostanza, al ritorno da ogni action nascondo il primo DIV, deseleziono il link corrispondente, visualizzo il DIV deciso nell'action e seleziono il link corrispondente.

Probabilmente esiste una soluzione più liferay-istica, ma questa funziona bene ed è molto semplice.

Spero possa esser d'aiuto.

Buon lavoro!

Marcello

Precedente
Commenti
Aggiungi Commento
Ivano Masiero
Ciao, grazie per i tuoi post, sempre interessanti e molto utili!
Ho la necessità di utilizzare il form navigator che però includa delle jsp in cui ho inserito delle form così come ipotizzato nel tuo post.
Supponi ad esempio che ci sia un form navigator per la creazione di una nuova entity Persona che abbia, a livello di progettazione della base di dati, una relazione uno a molti con un'entity tipo Area. Vorrei quindi creare una section in cui includere la possibilità di aggiungere le aree creandole direttamente dalla section stessa. La mia idea è poi quella che il salva "globale" del navigator crei la nuova Persona e, inoltre, leghi le aree create nella section con questa Persona.

Il problema che sto riscontrando ora è che il submit della form della section (a cui ho legato una actionURL) chiama sempre la action globale (anch'essa definita da una actionURL) e non riesco quindi a renderle indipendenti.
Grazie in anticipo se mi puoi dare qualche suggerimento.
Inviato il 09/07/15 14.02.
marcello marangio
Ciao ivan, grazie per i complimenti, sempre apprezzati.
Mi sono reso conto che nel post sono stato un pò impreciso: le jsp interne non possono contenere una form, perchè sarebbero form innestate nella form esterna, il chè è vietato dallo standard HTML. E questo è l'origine del tuo problema. Dovresti, quindi, mettere nella pagina che contiene il navigator (subito sotto) tante form hidden per quante sono le jsp con form (area, ad esempio); poi, con un pò di semplice js, fai in modo che il pulsante SALVA della jsp AREA copi i campi nel form hidden corrispondente e faccia submit. A quel punto nelle form hidden ci puoi mettere l'action che vuoi.
spero di esserti stato utile.
ciao
Marcello
Inviato il 09/07/15 14.02 in risposta a Ivano Masiero.
Marco Napolitano
Per risolvere il problema del posizionamento della sezione, date un'occhiata a questo post: http://blog.d-vel.com/web/blog/home/-/blogs/posizionarsi-correttamente-in-un-form-navigator-di-liferay.
Inviato il 09/07/15 14.02.