Service Builder para desarrollar un portlet con gestión de base de datos Parte 3/3

Ya estamos terminando nuestro portlet para Liferay que nos ayudará a aprender y gestionar tareas Por si no recordáis o acabáis de llegar a este post aquí os dejo un par de links a la parte 1 y a la parte 2 respectivamente.

https://jesuslc.com/2013/05/07/utilizando-spring-para-desarrollar-un-portlet-para-liferay-con-base-de-datos-service-builde

https://jesuslc.com/2013/05/14/service-builder-para-desarrollar-un-portlet-con-gestion-de-base-de-datos-parte-23

Vamos a poner de nuevo como quedará el portlet porque hoy viene una de las partes más importantes, la vista:

Llegados aquí ya tenemos el Service Builder montado, si recordáis con solo definir un par de entidades con sus columnas correspondientes en el archivo services.xml y pulsar sobre la tarea (ant) “build Services” creamos un montón de código que nos sirve para mapear la base de datos. En el anterior post vimos cómo crear los controladores, en este ya tenemos el final. Vamos a definir 5 archivos JSP donde programaremos todos los elementos gráficos.

Creando el init

Así que lo primero para tener bien organizado el código será crear una carpeta llamada “JSP” (imaginación al poder) en docroot.

En Este nuevo directorio “/docroot/jsp” creamos el primer archivo llamado init.jsp Este primer archivo no tiene nada de vista, solo todas las importaciones de taglib, lo hacemos así para no repetir el mismo código de importaciones en todas las clases. También hemos definido 3 variables que nos ayudaran a no repetir código.

Brown-tsk-portlet/docroot/jsp/init.jsp

<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %> 
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x" %>

<%@ page import="com.liferay.portal.kernel.util.StringUtil" %>
<%@ page import="com.liferay.portal.security.permission.PermissionChecker" %>

<portlet:defineObjects /> 
<liferay-theme:defineObjects />

<%
         long groupId = themeDisplay.getPortletGroupId();
         String name = themeDisplay.getPortletDisplay().getRootPortletId();
         String primKey = themeDisplay.getPortletDisplay().getResourcePK();
%>

Vamos a por el archivo principal, llamado view.jsp

La vista general

Si nos fijamos en la figura de arriba tenemos  botones (addlist y additem), justo debajo la barra de pestañas (tabs) con cada una de las listas con una señalada por defecto SIEMPRE y debajo las tareas de esa lista. Pues todo ello puede resumirse en este archivo:

<%@ include file="init.jsp" %>

<portlet:renderURL var='urlAddList'><portlet:param name='action' value='addList'/><portlet:param name='order' value='${order}'/><portlet:param name='list' value='${list}'/></portlet:renderURL>
<portlet:renderURL var='urlEditList'><portlet:param name='action' value='addList'/><portlet:param name='order' value='${order}'/><portlet:param name='list' value='${list}'/><portlet:param name='id' value='${list}'/></portlet:renderURL>
<portlet:renderURL var='urlAddItem'><portlet:param name='action' value='addItem'/><portlet:param name='order' value='${order}'/><portlet:param name='list' value='${list}'/></portlet:renderURL>
<portlet:renderURL var='def'><portlet:param name='action' value='view'/></portlet:renderURL>

<p>

       <aui:button name='addList' value='add-list' onclick='<%=renderResponse.getNamespace()+"toAddList()" %>' />
       <c:if test="${list!=null}">
             <aui:button name='addItem' value='add-item' onclick='<%=renderResponse.getNamespace()+"toAddItem()" %>' />
       </c:if>

</p>

<liferay-ui:tabs
       names="${formNames}"
       value="${formTab}"
       url='<%=def %>'
       refresh="<%= true %>"
       />

<p style='text-align: right;'>
             <c:if test="${list!=null}">
                    <liferay-ui:icon
                           cssClass="top-link"
                           image="edit"
                           label="<%= true %>"
                           message="editlist"
                           url='${urlEditList}'
                           />
             </c:if>
</p>

<aui:script>
       function <%=renderResponse.getNamespace() %>toAddList() {
             window.location.href='<%=urlAddList %>';
             }

       function <%=renderResponse.getNamespace() %>toAddItem() {
             window.location.href='<%=urlAddItem %>';
             }
</aui:script>

<table style='width: 100%;'>
       <tr class="portlet-section-header results-header">
             <td>
                    <b>
                           <a style='text-decoration: none;' href='<portlet:renderURL>
                                        <portlet:param name='action' value='view'/>
                                        <portlet:param name='list' value='${list}'/>
                                        <portlet:param name='order' value='label'/>
                                        </portlet:renderURL>'>

                                  <liferay-ui:message key="label" />

                                  <c:if test="${order=='label'}">
                                        &or;
                                  </c:if>
                           </a>
                    </b>
             </td>
             <td>
                    <b>
                           <a style='text-decoration: none;' href='<portlet:renderURL>
                                        <portlet:param name='action' value='view'/>
                                        <portlet:param name='list' value='${list}'/>
                                        <portlet:param name='order' value='weight'/>
                                        </portlet:renderURL>'>

                                  <liferay-ui:message key="weight" />

                                  <c:if test="${order=='weight'}">
                                        &or;
                                  </c:if>
                           </a>
                    </b>
             </td>
             <td>
                    <b>
                           <a style='text-decoration: none;' href='<portlet:renderURL>
                                        <portlet:param name='action' value='view'/>
                                        <portlet:param name='list' value='${list}'/>
                                        <portlet:param name='order' value='status'/>
                                        </portlet:renderURL>'>

                                  <liferay-ui:message key="status" />

                                  <c:if test="${order=='status'}">
                                        &or;
                                  </c:if>
                           </a>
                    </b>
             </td>
       </tr>

       <c:forEach var="item" items="${itemList}">
             <portlet:renderURL var='urlViewItem'>
                    <portlet:param name='list' value='${list}'/>
                    <portlet:param name='itemid' value='${item.id}'/>
                    <portlet:param name='order' value='${order}'/>
             </portlet:renderURL>

             <tr>
                    <td>        
                           <aui:a href='${urlViewItem}'>
                                  ${item.label}
                           </aui:a>
                    </td>
                    <td>
                           <c:choose>
                                  <c:when test="${item.weight>=16}">
                                        <spanclass='weight_highest'>
                                  </c:when>
                                  <c:when test="${item.weight>=4}">
                                        <spanclass='weight_high'>
                                  </c:when>
                                  <c:when test="${item.weight>=-4}">
                                        <spanclass='weight_normal'>
                                  </c:when>
                                  <c:when test="${item.weight>=-14}">
                                        <spanclass='weight_low'>
                                  </c:when>
                                  <c:otherwise>
                                        <spanclass='weight_lowest'>
                                  </c:otherwise>
                           </c:choose>
                           ${item.weight}</span>
                    </td>
                    <td>
                                  <c:choose>
                                        <c:when test="${item.status==0}">
                                               <span class='status_normal'><liferay-ui:message key="normal" /></span>
                                        </c:when>
                                        <c:when test="${item.status==1}">
                                               <span class='status_waiting'><liferay-ui:message key="waiting" /></span>
                                        </c:when>
                                        <c:when test="${item.status==2}">
                                               <span class='status_cancelled'><liferay-ui:message key="cancelled" /></span>
                                        </c:when>
                                        <c:when test="${item.status==3}">
                                               <span class='status_finished'><liferay-ui:message key="finished" /></span>
                                        </c:when>
                                        <c:otherwise>
                                               ${item.status}
                                        </c:otherwise>
                                  </c:choose>
                    </td>
             </tr>
       </c:forEach>
</table>

Si veis al principio del archivo tenemos un include para evitar realizar allí todas las importaciones que realizamos en init.jsp

Viendo solo un ítem

SI hacemos clic encima de una tarea podemos ver con más detalle dicha tarea, más o menos veremos algo así:

El código que genera esta vista es algo así:

<%@ include file="init.jsp" %>

<portlet:renderURL var='urlCancel'><portlet:param name='action' value='view'/><portlet:param name='order' value='${order}'/><portlet:param name='list' value='${list}'/></portlet:renderURL>

       <liferay-ui:header title="${listObj.description} - ${item.label}" backURL="${urlCancel}" />

             
4px;" >                            'urlEditItem'>                                   'action' value='addItem'/>                                   'list' value='${list}'/>                                   'itemid' value='${item.id}'/>                                   'order' value='${order}'/>                                                       "top-link"                                   image="edit"                                   label=""                                   message="edit"                                   url='${urlEditItem}'                                   />             
       <aui:field-wrapper label="description">              <% pageContext.setAttribute("newLineChar", "\n"); %>              ${fn:replace(item.description,newLineChar,"<br/>")}        </aui:field-wrapper>       
left; margin-right: 4px;" >              "label">                     '${item.label}' />                    
      
left; margin-right: 4px;" >              "status">        "${statuses[ item.status ]=='Normal'}">                     'status_normal'>"normal" />               "${statuses[ item.status ]=='Waiting for'}">                     'status_waiting'>"waiting" />               "${statuses[ item.status ]=='Cancelled'}">                     'status_cancelled'>"cancelled" />               "${statuses[ item.status ]=='Finished'}">                     'status_finished'>"finished" />                           
      
both; overflow: hidden; height: 1px;" > 

Añadiendo una lista de tareas

Cuando pulsamos desde la pantalla principal de nuestro portlet de gestión de tareas el botón de añadir una lista de tareas no aparece algo como esto:

Como veis tenemos una caja donde añadir el nombre de la lista de tarea y un peso que nos servirá para ordenar las listas en la barra de pestañas.

<%@ include file="init.jsp" %>

<portlet:actionURL var='actionAddList'><portlet:param name='action' value='addList'/><portlet:param name='order' value='${order}'/></portlet:actionURL>
<portlet:renderURL var='urlCancel'><portlet:param name='action' value='view'/><portlet:param name='order' value='${order}'/><portlet:param name='list' value='${list}'/></portlet:renderURL>

<portlet:actionURL var='actionDeleteList'>
       <portlet:param name='action' value='addList'/>
       <portlet:param name='delete' value='1'/>
       <portlet:param name='id' value='${item.id}'/>
       <portlet:param name='order' value='${order}'/>
</portlet:actionURL>

<liferay-ui:header title="list-title"   backURL="${urlCancel}" />

<form method="post" action="<%= actionAddList %>" onSubmit = "<%= "javascript: return "+renderResponse.getNamespace()+"validate(this);" %>" >

       
left; margin-right: 4px; height: 43px;" >              'text' name='description' label="list-name" value='${item.description}' />       
      
left; margin-right: 4px; height: 43px;" >              "weight" name="weight">                     "${item.weight}" var="sval"/>                     "${item.id==null}">                            "0" var="sval"/>                                                      "i" begin="0" end="10">                            "${i-5}" selected="${sval==i-5}">${i-5}                                        
      
both; overflow: hidden; height: 1px;" >                      
       <p>              &nbsp;        </p>        <p>              <c:if test="${item.id!=null}">                              <aui:input type='hidden' name='id' value='${item.id}' />                     <input type='submit' value='<liferay-ui:message key="save" />'/>                     <input type='button' onclick='<%=renderResponse.getNamespace()+"toDelete();" %>' value='<liferay-ui:message key="action.DELETE" />'/>              </c:if>                          <c:if test="${item.id==null}">                              <aui:input type='hidden' name='id' value='-1' />                     <input type='submit' value='<liferay-ui:message key="add" />'/>              </c:if>                   &nbsp;&nbsp;&nbsp;&nbsp;              <input type='button' onclick="javascript: window.location.href='${urlCancel}';" value='<liferay-ui:message key="cancel" />'/>        </p> </form> <aui:script use="aui-node">        <portlet:namespace />validate=function() {              if ( AUI().one("#<portlet:namespace />description").val().trim()=="" ) {                     alert( '<liferay-ui:message key="this-field-is-mandatory" />' );                     AUI().one("#<portlet:namespace />description").focus();                     return false;                     }              return true;              }        <portlet:namespace />toDelete=function() {              if ( confirm("<liferay-ui:message key="attention-delete" />") )                     window.location.href='${actionDeleteList}';              } </aui:script>

Añadiendo una nueva tarea

Cuando queremos añadir una nueva tarea tenemos algo como esto:

El código lo tenemos aquí:

<%@ include file="init.jsp" %>

<portlet:actionURL var='actionAddItem'>
       <portlet:param name='order' value='${order}'/>
       <portlet:param name='action' value='addItem'/>
</portlet:actionURL>

<portlet:actionURL var='actionDeleteItem'>
       <portlet:param name='action' value='addItem'/>
       <portlet:param name='delete' value='1'/>
       <portlet:param name='id' value='${item.id}'/>
       <portlet:param name='list' value='${list}'/>
       <portlet:param name='order' value='${order}'/>
</portlet:actionURL>

<portlet:renderURL var='urlCancel'>
       <portlet:param name='order' value='${order}'/>
       <portlet:param name='action' value='view'/>
       <portlet:param name='list' value='${list}'/>
</portlet:renderURL>

<liferay-ui:header title="item-title"   backURL="${urlCancel}" />

<form method="post" action="<%= actionAddItem %>" onSubmit = "<%= "javascript: return "+renderResponse.getNamespace()+"validate(this);" %>" >

       <aui:input type='hidden' name='list' value='${list}' />

       
left; margin-right: 4px;" >              'text' name='label' label="label" value='${item.label}' />       
      
left; margin-right: 4px;" >              "weight" name="weight" style="float: left;">                     "${item.weight}" var="sval"/>                     "${item.id==null}">                            "0" var="sval"/>                                                      "i" begin="0" end="10">                            "${i-5}" selected="${sval==i-5}">${i-5}                                        
      
left; margin-right: 4px;" >              "status" name="status" style="float: left;">                     "0" label="normal" selected="${item.status==0}" />                     "1" label="waiting" selected="${item.status==1}" />                     "2" label="cancelled" selected="${item.status==2}" />                     "3" label="finished" selected="${item.status==3}" />                    
      
both; overflow: hidden; height: 1px;" >                      
       <aui:input type='textarea' name='description' label="item-description" value='${item.description}' style="width: 100%;" />        <p>              &nbsp;        </p>        <p>              <c:if test="${item.id!=null}">                              <aui:input type='hidden' name='id' value='${item.id}' />                     <input type='submit' value="<liferay-ui:message key='save' />"/>                     <input type='button' onclick='<%=renderResponse.getNamespace()+"toDelete();" %>' value='<liferay-ui:message key="action.DELETE" />'/>              </c:if>                          <c:if test="${item.id==null}">                              <aui:input type='hidden' name='id' value='-1' />                     <input type='submit' value='<liferay-ui:message key="add" />'/>              </c:if>                          &nbsp;&nbsp;&nbsp;&nbsp;              <input type='button' onclick="javascript: window.location.href='${urlCancel}';" value='<liferay-ui:message key="cancel" />'/>        </p> </form> <aui:script>        <portlet:namespace />validate=function() {              if ( AUI().one("#<portlet:namespace />label").val().trim()=="" ) {                     alert( '<liferay-ui:message key="this-field-is-mandatory" />' );                     AUI().one("#<portlet:namespace />label").focus();                     return false;                     }              return true;              }        <portlet:namespace />toDelete=function() {              if ( confirm("<liferay-ui:message key="attention-delete" />") )                     window.location.href='<%=actionDeleteItem %>';              } </aui:script>

Ya hemos como crear la vista, para tener un portlet totalmente funcional deberemos poder probarlo y para ello es necesario configurarlo.

Configurando el portlet

Por ultimo solo nos queda configurar un poco los parámetros del portlet para que eche a andar.

Modificamos la categoría

Para que a la hora de añadir el portlet podamos encontrarlo fácilmente vamos a definirle una categoría propia de la siguiente manera.

Abrimos el archivo Liferay-display.xml y modificamos la categoría, yo le he puesto como categoría “Demos JesusLC SB”

Modificando el Controller

Para que el portlet de gestión de tareas funcione, debemos indicarle cual es nuestra clase controladora, la que implementa a MVCPortlet, si os acordáis del post anterior creamos una clase llamada BalancerController, pues en el archivo portlet.xml debemos poner la ruta de esa clase, además de indicar  que tenemos un archivo llamado Language.properties donde está definido el idioma del portlet.

Debe quedar todo como esta figura:

Finalmente ya hemos terminado con este Portet, solo tenemos pulsar sobre build.xml y correr la tarea ant para que se añada al servidor y empezar a utilizarlo.

Anuncios

14 comentarios sobre “Service Builder para desarrollar un portlet con gestión de base de datos Parte 3/3

  1. oye amigo tengo un problema nos has dicho a vosotros que la vista es lo mas importante y os hemos quedado esperando por los nombres de los archivos jsp que se deben utilizar te agradezco nos dichas con mas detalle como construir la vista thanks

    Me gusta

      1. Hola de nuevo jesuslc lo que sucede es que no se bien que nombre colocar a los jsp solo he visto que existe un ini.jsp con los taglib y un view.jsp que me crea el porlet pero los demas jsp donde van puestos y con que nombre gracias

        Me gusta

      1. Es un ejemplo muy ilustrativo para trabajar con los servicios y BD en liferay.

        Sólo una cosa, faltan los css en la aplicación brown-tasks.

        Un saludo.

        Me gusta

  2. Gracias jesuslc los voy a estudiar bien yo te quería pedir un consejo.. lo que sucede es que yo soy nuevo en liferay y en java sigo siendo novato llevo como dos años desarrollando pequeñas aplicaciones pero me gusta esto y me gustaría saber cual es la mejor manera de aprender a desarrollar en liferay ya que tengo un sin fin de manuales de administración y desarrollo de portales en liferay pero estos se encargan de explicarte lo que liferay puede hacer hacer pero hay muy poco ejemplos al respecto te agradezco la comprensión y esperare tu mejor consejo gracias.

    Me gusta

    1. Yo para empezar a desarrollar te recomendaría alguno de los libros que hay para desarrollar Liferay. Si entras en la sección libros recomiendo un par de ellos.
      Y lo importantes no desesperes, porque hay veces que un fallo tonto te hace perder toda una tarde, pero después cuando ves la aplicación terminada te alegras y se te olvidan esos inconvenientes.

      Me gusta

      1. Muchas gracias he empezado el libro portlets en acción esta re bien 🙂 quería hacerte una pregunta Jesus respecto a los jsp que usas, muchos tienen etiquetas un poco diferentes como:
        , , si no estoy mal estas etiquetas son las utilizadas en la especificación java server faces sin embargo tienen la extension .jsp me podrias explicar un poco esta modalidad muchas gracias

        Me gusta

  3. Hola jesus exelente tutorial he aprendido muchas cosas para crear service builder, al principio tuve muchos inconvenientes con algunas librerías pero ahora tengo mi portlet funcionando muchas gracias por compartir tu conocimiento…
    ahora voy a empezar a construir service builder personalizados con funcionalidades diferentes gracias

    Me gusta

      1. Mauro disculpa deje de trabajr cone sta tecnologia es por esto que deje de eprender liferay, las librerias que usen para crear este portlet son las misma que viene integradas con liferay

        Me gusta

  4. Hola Jesus, una pregunta estoy modificando un portlet pero deseo agregar unos atributos extras en una tabla desde el service.xml, pero no consigo como actualizar las clases del service builder sin generar todo el codigo nuevo con “Build Services”, al realizar esto pierdo varios metodos que hizo la persona que construyo el portlet

    Me gusta

Comenta la entrada

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s