Ejemplo basico search-container en Liferay

De ChuWiki
Saltar a: navegación, buscar


Para dibujar tablas en un portlet de liferay tenemos los tags de search-container. La estructura básica es la siguiente

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
...
<portlet:defineObjects />
<liferay-theme:defineObjects />
...
<%
   List<UserGroup> tempResults = UserGroupLocalServiceUtil
         .getUserGroups(themeDisplay.getCompanyId());
%>
<liferay-ui:search-container
   emptyResultsMessage="there-are-no-user-groups"
   delta="<%= tempResults.size() %>">
   <liferay-ui:search-container-results>
      <%
         results = ListUtil.subList(tempResults,
                     searchContainer.getStart(), searchContainer.getEnd());
               total = tempResults.size();
               pageContext.setAttribute("results", results);
               pageContext.setAttribute("total", total);
      %>
   </liferay-ui:search-container-results>
   <liferay-ui:search-container-row
      className="com.liferay.portal.model.UserGroup"
      keyProperty="userGroupId" modelVar="userGroup">
      <liferay-ui:search-container-column-text name="Id"
         property="userGroupId" />
      <liferay-ui:search-container-column-text name="Name"
         property="name" />
      <liferay-ui:search-container-column-text name="Description"
         property="description" />
      <liferay-ui:search-container-column-jsp
         path="/admin_actions.jsp" align="right" />
   </liferay-ui:search-container-row>
   <liferay-ui:search-iterator />
</liferay-ui:search-container>

Vamos a ir viendo poco a poco qué es todo esto. En el primer trozo de código

<%
   List<UserGroup> tempResults = UserGroupLocalServiceUtil
         .getUserGroups(themeDisplay.getCompanyId());
%>

lo que hacemos es obtener los datos que queremos presentar en la tabla. Puede ser cualquier lista de datos que queramos, obtenida de nuestra base de datos o de donde sea, lo importante es meterlo en un List<TipoDatoDeseado>. En este ejemplo usamos la clase UserGroupLocalServiceUtil de Liferay que nos permite obtener los grupos de usuarios (UserGroup) que existe en una compañía themeDisplay.getCompanyId(). themeDisplay es una variable que pone liferay a nuestra disposición para consultar este tipo de cosas (ver http://www.liferay.com/web/raymond.auge/blog/-/blogs/809893 ). En cualquier caso, todo esto no es importante, ya que en tu tabla posiblemente quieras otros datos y no sea este el código que necesitas.

Ahora empezamos la tabla (search-container)

<liferay-ui:search-container
   emptyResultsMessage="there-are-no-user-groups"
   delta="<%= tempResults.size() %>">
   ...
</liferay-ui:search-container>

La etiqueta es <liferay-ui:search-container>. El prefijo liferay-ui, por supuesto, es poque lo hemos elegido previamente en nuestros taglib

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

El parámetro emptyResultMessage es una propiedad que tengamos definida en nuestro fichero de recursos (idiomas) con el texto que queramos que se muestre cuando no hay resultados en la tabla. Si la propiedad no existe, se motrará el texto tal cual. El atributo delta indica cuántas filas queremos que tenga nuestra tabla. Si hay más datos que filas, search-container mostrará botones de paginación (viendo 10 elementos de 57, página siguiente, anterior, etc). Aquí hemos puesto tempResults.size() para que muestre todos los elementos y no hay paginación.

Ahora debemos indicarle al search-container cuales son los datos que debe mostrar. Para ello debemos rellenar una variables que define el search-container y que usará a la hora de mostrar resultados

   <liferay-ui:search-container-results>
      <%
         results = ListUtil.subList(tempResults,
                     searchContainer.getStart(), searchContainer.getEnd());
               total = tempResults.size();
               pageContext.setAttribute("results", results);
               pageContext.setAttribute("total", total);
      %>
   </liferay-ui:search-container-results>

En results metemos una sublista con los datos a mostrar. La sublista se puede usar con la clase ListUtil proporcionada por Lieray, usando su método subList(), al que pasamos como parámetros la lista total de datos tempResults, el índice de inicio searchContainer.getStart() y el de fin searchContainer.getEnd(). En nuestro ejemplo que no queremos paginación, podiamos poner directamente

results = tempResults;

ya que siempre vamos a ver todos. Pero si tuvieramos paginación, habría que preguntarle a searchContainer cuales son los elementos que el usuario desea mostrar y dárselos. Por ello eso hemos puesto así el trozo de código.

En total metemos el número total de elementos en la lista, de forma que search-container pueda indicar al usuario cuantos elementos hay en total. Almacenamos ambas variables total y results en pageContext, también un objeto ofrecido por Liferay.

Ya solo nos queda definir qué columnas tiene cada fila,

   <liferay-ui:search-container-row
      className="com.liferay.portal.model.UserGroup"
      keyProperty="userGroupId" modelVar="userGroup">
   ...
   </lieray-ui:search-container-row>

Con <liferay-ui:search-container-row> indicamos el nombre de la clase que va a ir en cada fila (UserGroup) en nuestro caso e indicamos cual de sus propiedades (método getXXX()) queremos usar como clave de dicha clase, de forma que se pueda identificar la clase que hay en cada fila para posibles operaciones sobre ella. En nuestro caso, será UserGroup.getUserGroupId() y almacenaremos esa clave en una variable userGroup.

Vamos con las columnas. Cada columna será una etiqueta <search-container-column-xxxx> donde xxxx puede ser text, button o jsp. La primera se usa para mostrar texto, la segunda para poner botones y la tercera para incluir una página jsp completa en esa columna. Los de texto son sencillos, nuestras tres primeras columnas son texto

      <liferay-ui:search-container-column-text name="Id"
         property="userGroupId" />
      <liferay-ui:search-container-column-text name="Name"
         property="name" />
      <liferay-ui:search-container-column-text name="Description"
         property="description" />

El "name" aparecerá en la cabecera de la tabla como etiqueta de la columna. Los property son las propiedades de la clase UserGroup que se van a mostrar, es decir UserGroup.getId(), UserGroup.getName() y UserGroup.getDescription() en nuestro ejemplo.

Las columnas button, no hay ninguna en nuestro ejemplo, llevaría un atributo href="url" con la url a la que se llamará cuando se pulse el botón. <liferay-ui:search-container-column-text href="..." ....

Finalmente, las columnas jsp como la del ejemplo

      <liferay-ui:search-container-column-jsp
         path="/admin_actions.jsp" align="right" />

lleva un atributo path en el que se pone la página jsp que se va a mostrar en la celda. Habitualmente esta página jsp puede contener un menú de opciones como "editar", "borrar", "permisos" etc que afectarán al item en la fila correspondiente. En ese fichero admin_actions.jsp podríamos obtener el elemento de la fila con el siguiente código

<%
   ResultRow row = (ResultRow) request
         .getAttribute(WebKeys.SEARCH_CONTAINER_RESULT_ROW);
   UserGroup userGroup = (UserGroup) row.getObject();
%>

A partir de ahi podemos construir un menú o lo que queramos en la celda de la tabla sabiendo a qué elemento estamos haciendo referencia. Por ejemplo, el siguiente trozo mostraría un menú con dos opciones, editar y borrar.

<liferay-ui:icon-menu>
    <portlet:actionURL name="editProduct" var="editURL">
      <portlet:param name="resourcePrimKey" value="<%= myProduct.getPrimaryKey() %>" />
    </portlet:actionURL>
    <liferay-ui:icon image="edit" message="Edit" url="<%= editURL.toString() %>" />

    <portlet:actionURL name="deleteProduct" var="deleteURL">
      <portlet:param name="resourcePrimKey" value="<%= myProduct.getPrimaryKey() %>" />
    </portlet:actionURL>
    <liferay-ui:icon-delete url="<%= deleteURL.toString() %>" /> 
</liferay-ui:icon-menu>

Usamos <liferay-ui:icon-menu> para poner un menú con icono en la celda de la tabla. Dentro definimos las acciones.

Para cada acción, definimos con portlet:actionURL las distintas acciones liferay para cada una de las acciones, editar y borrar. En esa url ponemos como parámetros lo que queramos, en el ejemplo la clave primaria de UserGroup. Hay, por supuesto, que hacer el código de esas acciones en el servidor, pero eso está fuera de este tutorial, aquí solo estamos viendo como dibujar la tabla. Con <liferay-ui:icon> ponemos la opción del menú indicando un icono para ella, el texto de la opción y la url donde se ejecutará dicha acción.