Implmentando la configuration-action-class di un portlet custom è nata l'esigenza di avere una lista di campi dello stesso tipo con lunghezza arbitraria.
Inizialmente abbiamo utilizzato un unico campo di testo dove l'utente potesse inserire i valori separati da virgola.
Questa implementazione funzionava, ma non era soddisfacente dal punto di vista della pulizia del codice e dell'usabilità da parte dell'utente.
Facendo un po' di scouting sul portale abbiamo scoperto che la soluzione esiste già!
Questo è il risultato.
Questo è il codice della jsp che lo renderizza.
<%
String[] emails = preferences.getValues(MyFilterPreferences.INDIRIZZI_MAIL, new String[0]);
%>
La variabile emails contiene i valori precedentementi inseriti, oppure è vuota.
<portlet:namespace />addEmail = function(table) {
table.insertRow(table.rows.length);
var row = table.rows[table.rows.length - 1];
row.insertCell(0);
row.insertCell(1);
row.cells[0].innerHTML = "<input name=\"<portlet:namespace />email\" />";
row.cells[1].innerHTML = "<a href=\"javascript: ;\" onclick=\"jQuery(this.parentNode.parentNode).remove();\">
<img alt=\"<liferay-ui:message key="unsubscribe" />\" src=\"<%= themeDisplay.getPathThemeImages() %>/common/remove.png\" /></a>";
table.appendChild(row);
}
Questo è il javascript che aggiunge una riga nella lista in cui inserire il valore quando clicchiamo sull'icona +
1. <tr>
2. <td><liferay-ui:message key="add-email" /></td>
3. <td>
4. <a href="javascript:;" onclick="<portlet:namespace />addEmail(this.parentNode.parentNode.parentNode);">
5. <img alt="<liferay-ui:message key="add-location" />" src="<%= themeDisplay.getPathThemeImages() %>/common/add.png" /></a>
6. </td>
7. </tr>
8. <%
9. for (int i = 0; i < emails.length; i++) {
10.%>
11. <tr>
12. <td>
13. <input class="lfr-input-text" name="<portlet:namespace />email" type="text" value="<%= emails[i] %>" />
14. </td>
15. <td>
16. <a href="javascript: ;" onclick="jQuery(this.parentNode.parentNode).remove();">
17. <img alt="<liferay-ui:message key="unsubscribe" />"
18. src="<%= themeDisplay.getPathThemeImages() %>/common/remove.png" /></a>
19. </td>
20. </tr>
21.<%
22.}
23.%>
Nelle righe 1-7 viene visualizzata la label e il pulsante per aggiungere una riga, la cui pressione richiama il javascript di sopra.
Nelle righe 9-22 viene fatto un ciclo sulla variabile emails per stampare gli eventuali valori già inseriti.
Nella classe che salva le preference basterà invocare il metodo setValues(MyFilterPreferences.INDIRIZZI_MAIL,emails) per salvare in maniera persistente i valori che abbiamo inserito.