La nuova versione 6.2 di Liferay ha portato molte modifiche, una queste riguarda alcuni moduli di Alloy che sono cambiati o semplicemente deprecati.
Vediamo quindi come gestire l'autocomplete con Liferay 6.2, recuperando i dati via Ajax.
Per questo esempio, utilizzeremo i dati contenuti all'interno della tabella classname, semplicemente perchè contiene un numero sufficiente di dati di test.
La prima, e più importante, cosa da preparare è la JSP che conterrà il widget e lo script; iniziamo quindi con la definizione di 2 campi di input: il primo per visualizzare il widget ed il secondo per memorizzare il valore da utilizzare nella portlet per l'eventuale salvataggio:
<aui:input name="className" /> <aui:input name="valueToBeSaved" type="hidden" />
Dopodichè andremo a definire la URL ed il datasource che serviranno per il recupero via Ajax dei valori da mostrare nel widget; trattandosi di una chiamata Ajax che restituisce un frammeto JSON, la URL sarà ovviamente di tipo resource:
<liferay-portlet:resourceURL id="autocomplete" var="autocompleteURL" />
<aui:script use="autocomplete-list,datasource-io">
var datasource = new A.DataSource.IO({
source: '<%=autocompleteURL%>'
});
...
L'ultima parte di script è quella più importante che si occupa di istanziare il widget e renderlo funzionante:
var autoComplete = new A.AutoCompleteList({
allowBrowserAutocomplete: false,
activateFirstItem: true,
inputNode: '#<portlet:namespace />className',
maxResults: 10,
on: {
select: function(event) {
var result = event.result.raw;
A.one('#<portlet:namespace/>valueToBeSaved').val(result.classNameId);
}
},
render: true,
source: datasource,
requestTemplate: '&<portlet:namespace />keywords={query}',
resultListLocator: function (response) {
var responseData = A.JSON.parse(response[0].responseText);
return responseData.response;
},
resultTextLocator: function (result) {
return result.value;
},
width: 400
});
</aui:script>
Per maggiori dettagli sui vari parametri disponibili si consulti la documentazione ufficiale di AlloyUI; vediamo tuttavia quelli principali:
allowBrowserAutocomplete- Disabilita l'autocomplete del browser
inputNode- Rappresenta il campo di input in cui scrivere
on.select- Rappresenta il codice da eseguire alla selezione di un valore;
event.result.rawrappresenta l'oggetto JSON selezionato source- Rappresenta il datasource della chiamava Ajax che recupera i dati da visualizzare
requestTemplate- Rappresenta i parametri inviati al server per la ricerca, tra cui il placeholder
{query}che contiene il testo digitato dall'utente resultListLocator- Rappresenta il codice che estrae la lista di valori dalla risposta JSON del server
resultTextLocator- Rappresenta il codice per estrarre il valore ma mostrare nella lista
L'ultima parte consiste nel codice Java che deve gestire la chiamata Ajax per la ricerca e la restituzione dei valori, nulla è cambiato rispetto alla vecchia versione di Liferay:
public void serveResource(ResourceRequest resourceRequest,
ResourceResponse resourceResponse) throws IOException,
PortletException {
String resourceID = resourceRequest.getResourceID();
if ("autocomplete".equals(resourceID)) {
String keywords = ParamUtil.getString(resourceRequest, "keywords");
JSONObject json = JSONFactoryUtil.createJSONObject();
JSONArray results = JSONFactoryUtil.createJSONArray();
json.put("response", results);
try {
DynamicQuery query = DynamicQueryFactoryUtil
.forClass(ClassName.class);
query.add(PropertyFactoryUtil.forName("value").like(
StringPool.PERCENT + keywords + StringPool.PERCENT));
List<ClassName> classNames = ClassNameLocalServiceUtil
.dynamicQuery(query);
for (ClassName className : classNames) {
JSONObject object = JSONFactoryUtil.createJSONObject();
object.put("classNameId", className.getClassNameId());
object.put("value", className.getValue());
results.put(object);
}
} catch (SystemException e) {
e.printStackTrace();
}
writeJSON(resourceRequest, resourceResponse, json);
} else {
super.serveResource(resourceRequest, resourceResponse);
}
}