In questo quarto tutorial continuiamo le personalizzazioni e modifichiamo la pagina dei commenti. 

Leggi i precedenti post della serie parte 1parte 2 e parte 3 .

L'obiettivo è unire la pagina che mostra i commenti con quella della creazione, per avere l'elenco e la possibilità di scrivere un commento nella stessa pagina.

Il risultato desiderato è il seguente.
 
 

Passo 1. Elenco e creazione dei commenti in una unica pagina

Modichiamo l'action "Groovy" perché reindirizzi ad una pagina jsp personalizzata per la ricerca. La pagina conterrà anche il form di creazione.
 
@SupportsPermissions([ CrudAction.PERMISSION_CREATE, 
   CrudAction.PERMISSION_EDIT, 
   CrudAction.PERMISSION_DELETE ])

@RequiresPermissions(level = AccessLevel.VIEW)

class MyCrudAction extends CrudAction {
  //*********************************************
  // List objects
  //*********************************************

  @DefaultHandler
  public Resolution execute() {
      if (object == null) {
          return doList();
      } else {
          return read();
      }
  }

  public Resolution doList(){
     loadObjects();
     String jsp = "/apps/default/web/listComments.jsp";
      return new ForwardResolution(jsp);
  }

La pagina jsp custom mostra la lista dei commenti e permette di inserirne di nuovi come si vede nel codice seguente.

<%@ page import="java.util.List" %>
<%@ page import="com.manydesigns.elements.xml.XhtmlBuffer" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="javax.xml.crypto.Data" %>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java"
         pageEncoding="UTF-8"%>
<%@ taglib prefix="c" 
         uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="stripes" 
         uri="http://stripes.sourceforge.net/stripes-dynattr.tld"%>
<%@taglib prefix="mde" uri="/manydesigns-elements"%>
<%@ taglib tagdir="/WEB-INF/tags" prefix="portofino" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<stripes:layout-render name="/skins/${skin}/portlet.jsp">
    
    <jsp:useBean id="actionBean" scope="request" 
         type="com.manydesigns.portofino.pageactions.crud.CrudAction"/>
    
    <stripes:layout-component name="portletTitle">
        <c:out value="${actionBean.crudConfiguration.searchTitle}"/>
    </stripes:layout-component>

    <stripes:layout-component name="portletBody">
       <%
           SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy");
           XhtmlBuffer buffer = new XhtmlBuffer();
           for (HashMap object : (List<HashMap>)actionBean.objects){
               buffer.openElement("strong");
               buffer.write((String) object.get("author"));
               buffer.writeBr();
               buffer.write(df.format((Date)object.get("date")));
               buffer.closeElement("strong");
               buffer.writeParagraph((String)object.get("comment"));
               buffer.writeBr();
               buffer.writeHr();
           }
           out.println(buffer.toString());
       %>

            <h1>Add a new comment</h1>
        <form enctype="multipart/form-data" 
           action="<%= ((HashMap)actionBean
            .getOgnlContext().get("post")).get("id")%>/comment"
             method="post">
            <fieldset class="mde-form-fieldset mde-no-legend">
                <table class="mde-form-table">
                    <tbody>
                    <tr>
                        <th>* Comment</th>
                        <td><textarea id="comment" type="text" 
                              name="comment" class="mde-text-field"
                              maxlength="2147483647" cols="45" rows=5>
                            </textarea>
                        </td>
                    </tr>
                    <tr>
                        <th><label for="author" class="mde-field-label">
                            <span class="required">*</span>
                            Author:</label>
                        </th>
                        <td>
                            <input id="author" type="text" name="author" 
                              class="mde-text-field" 
                              maxlength="100" size="45">
                        </td>
                    </tr>
                    </tbody>
                </table>
            </fieldset>

            <input type="hidden" name="cancelReturnUrl" 
    value="/post/<%= ((HashMap)actionBean.getOgnlContext()
             .get("post")).get("id")%>"/>
            <input type="hidden" name="post" 
    value="<%= ((HashMap)actionBean.getOgnlContext()
             .get("post")).get("id")%>"/>
            <input type="submit" value="Add comment" name="save" 
    class="ui-button ui-widget ui-state-default ui-corner-all 
           portletButton ui-button-text-only" 
    role="button" aria-disabled="false"/>
        </form>
    </stripes:layout-component>
</stripes:layout-render>

Notiamo la sezione riguardante l'aggiunta di un nuovo commento. La form costruisce il link definito nella action con l'id dell'oggetto post e la stringa "comment" per indirizzare alla crud dei commenti e non a quella dei post.
I campi hanno i nomi delle proprietà corrispondenti, e la submit ha "save" come valore di "name", il nome del metodo della action che chiamerà.
In questo modo abbiamo i commenti inseribili in fondo alla lista, ma quando salviamo siamo indirizzati al dettaglio del commento.

Per eliminare questo comportamento facciamo l'ovveride del metodo "save" perché reindirizzi al post a cui il commento è associato. Nel codice seguente utilizzo quindi il path del parent attraverso l'oggetto pageInstance.

//Save redirects to blog post
@Button(list = "crud-create", key = "commons.save", order = 1d)
@RequiresPermissions(permissions = AbstractCrudAction.PERMISSION_CREATE)
public Resolution save() {
  super.save();
  if(!form.validate()){
      SessionMessages
        .addErrorMessage("Please insert the Comment and the Author fields");
  }
  return new RedirectResolution(pageInstance.parent.path);
}

Notiamo anche che lanciamo la validazione in maniera manuale per stampare un messaggio di errore sulla pagina del post.
Con questo ultimo passo abbiamo raggiunto il risultato desiderato. E abbiamo un blog perfettamente funzionante con un aspetto grafico accattivante.

Nel prossimo tutorial concluderemo la serie andando a creare i feed rss per i nostri articoli.

 

comments powered by Disqus