Agilizando Seleções com Popup JSF

 

Introdução

Este artigo apresenta uma forma fácil e rápida de obter um resultado de pesquisa, acionando uma janela popup e retornando o ítem selecionado através de uma listagem à janela principal, utilizando a estrutura padrão da navegação de Java Server Faces para a navegação em um ambiente de múltiplas janelas.

 

Arquivos de Configuração

Esses arquivos juntos definem a configuração e a navegação utilizada para o correto funcionamento da aplicação de acordo com os padrões JSF.

 

Abaixo o arquivo web.xml na integra:

 

<?xml version="1.0"?>

<!DOCTYPE web-app PUBLIC

  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

  "http://java.sun.com/dtd/web-app_2_3.dtd">

 

<web-app>

 

    <context-param>

        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>

        <param-value>server</param-value>

    </context-param>

 

    <context-param>

        <param-name>javax.faces.application.CONFIG_FILES</param-name>

        <param-value>/WEB-INF/faces-config.xml</param-value>

    </context-param>

 

    <!-- Faces Servlet -->

    <servlet>

        <servlet-name>Faces Servlet</servlet-name>

        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>

        <load-on-startup> 1 </load-on-startup>

    </servlet>

 

 

    <!-- Faces Servlet Mapping -->

    <servlet-mapping>

        <servlet-name>Faces Servlet</servlet-name>

        <url-pattern>*.jsf</url-pattern>

    </servlet-mapping>

 

    <welcome-file-list>

        <welcome-file>index.jsp</welcome-file>

    </welcome-file-list>

    

</web-app>

 

Abaixo o arquivo faces-config.xml na integra:

 

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN" "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">

<faces-config>

 <managed-bean>

  <description>Ir para</description>

  <managed-bean-name>GetPlaceBean</managed-bean-name>

  <managed-bean-class>demo.GetPlaceBean</managed-bean-class>

  <managed-bean-scope>session</managed-bean-scope>

  <managed-property>

   <property-name>country</property-name>

   <property-class>java.lang.String</property-class>

   <value>Usa</value>

  </managed-property>

  <managed-property>

   <property-name>place</property-name>

   <property-class>java.lang.String</property-class>

   <value>Pegar da lista --></value>

  </managed-property>

 </managed-bean>

 <managed-bean>

  <description>Ir para</description>

  <managed-bean-name>ListHolderBean</managed-bean-name>

  <managed-bean-class>demo.ListHolderBean</managed-bean-class>

  <managed-bean-scope>session</managed-bean-scope>

 </managed-bean>

 <navigation-rule>

  <navigation-case>

   <from-outcome>showPlace</from-outcome>

   <to-view-id>/pages/place.jsp</to-view-id>

  </navigation-case>

 </navigation-rule>

 <navigation-rule>

  <from-view-id>/pages/inputdata.jsp</from-view-id>

  <navigation-case>

   <from-outcome>visit</from-outcome>

   <to-view-id>/pages/destination.jsp</to-view-id>

  </navigation-case>

 </navigation-rule>

 <navigation-rule>

  <from-view-id>/pages/destination.jsp</from-view-id>

  <navigation-case>

   <from-outcome>back</from-outcome>

   <to-view-id>/pages/inputdata.jsp</to-view-id>

  </navigation-case>

 </navigation-rule>

 <lifecycle/>

 <application>

  <locale-config/>

 </application>

 <factory/>

</faces-config>

 

Classes JAVA

A classe GetPlaceBean.java é a representação do objeto que será transportado e utilizado:

 

package demo;

 

/**

 * @author Setembrino Lusa.

 *

 */

 

public class GetPlaceBean {

     

      private String place;

      private String country;

 

      public String getPlace() {

            return place;

      }

 

      public void setPlace(String p) {

            place = p;

      }

 

      public String getCountry() {

            return country;

      }

 

      public void setCountry(String c) {

            country = c;

      }

 

}

 

A classe ListHolderBean.java representa os dados para listagem e o carregamento destes, caso este exemplo seja utilizado em um sistema com acesso a banco de dados, teria algo mais elegante para o carregamento dos dados, porém como este não é o intuito deste artigo, faremos seu carregamento estático:

 

package demo;

 

 

/**

 * @author Setembrino Lusa.

 *

 */

 

public class ListHolderBean {

     

      private String[] usaPlaces = {

            "Alabama", "Alaska", "Arizona",

"Arkansas", "California", "Colorado",

            "Connecticut", "Delaware", "Florida",

"Georgia", "Hawaii", "Idaho",

            "Illinois", "Indiana", "Iowa",

"Kansas", "Kentucky", "Louisiana",

            "Maine", "Maryland", "Massachusetts",

"Michigan", "Minnesota", "Mississippi",

"Missouri", "Montana", "Nebraska",

"Nevada", "New Hampshire", "New Jersey",

"New Mexico", "New York", "North Carolina",

            "North Dakota", "Ohio", "Oklahoma",

"Oregon", "Pennsylvania", "Puerto Rico",

"Rhode Island", "South Carolina", "South Dakota",

"Tennessee", "Texas", "Utah",

"Vermont", "Virginia", "Washington",

"Washington D.C.", "West Virginia", "Wisconsin",

"Wyoming" };

     

     

      private String[] canadaPlaces= {

                  "Alberta", "British Columbia",

"Manitoba", "Newfoundland",

"New Brunswick", "Northwest Territories",

"Nova Scotia", "Ontario",

"Prince Edward Island", "Quebec",

"Saskatchewan", "Yukon" };

     

      private String country;

 

      public String[] getItems() {

            return "Canada".equals(country) ? canadaPlaces : usaPlaces;

      }

 

      public String getCountry() {

            return country;

      }

 

      public void setCountry(String c) {

            country = c;

      }

 

}

 

Arquivos JSP

O arquivo index.jsp serve aqui apenas para o redirecionamento da aplicação, visto que o utilizamos como welcome page na definição do arquivo web.xml.

 

    ...

 

    <welcome-file-list>

        <welcome-file>index.jsp</welcome-file>

    </welcome-file-list>

   

</web-app>

 

Abaixo o arquivo index.jsp:

 

<html>

<head>

</head>

<body>

            <jsp:forward page="/pages/inputdata.jsf" />

</body>

</html>

 

Abaixo o arquivo place.jsp, responsável por mostrar uma listagem selecionável. Uma vez que o usuário seleciona um dos itens clicando sobre ele na listagem, o campo de texto correspondente no formulário da janela principal é atualizado com o valor selecionado.

 

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

 

<html>

   <head>

<title>Listagem</title>

         <script type="text/javascript">

            function update(place) {

                  window.opener.updatePlace(place);

            }    

         </script>

   </head>

   <body>

      <f:view>

         <h:dataTable  value="#{ListHolderBean.items}"  var="place">

            <h:column>

               <h:outputLink title="#{place}"

onmousedown="update(this.title);"

value="#{place}" onclick="return false">

                     <h:outputText value="#{place}" />

               </h:outputLink>

            </h:column>

         </h:dataTable>

</f:view>

   </body>

</html>

 

Abaixo o arquivo inputdata.jsp, responsável pela seleção de um item na combo box que servirá como parâmetro na montagem da lista na chamada da janela popup.

 

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<f:loadBundle basename="demo.bundle.Messages" var="Message"/>

 

<HTML>

  <HEAD>

<title>Página de entrada de dados</title>

      <style>

            .header {

                  font-size:30px;

                  color:black;

                  padding-bottom: 20px;

            }

            p.note {

                  border:1 solid black;

                  font-size:12px;

            }

      </style>

      <script language="javascript">

 

            var formId; // referência ao formulário principal

            var winId;  // referência à janela popup

 

 

            // Esta função faz a chamada da janela popup.

            //

            function showPlaceList(action, form, target) {

                  formId=action.form.id;

                  features="height=300,width=250,

status=yes,toolbar=no,menubar=no,

location=no,scrollbars=yes";            

                 

winId=window.open('','list',features);

 

// Formulário escondido

                  hform=document.forms[form];               

                 

//Esta é uma simulação de um link quando clicado.

                  hform[form+':'+target].value=form+':'+target;

 

                  // Copia o item selecionado para o campo

// correpondente no formulário escondido.

                  hform[form+":country"].value =

getCountry(action.form);

 

                  // Submit do formulário escondido.

                  hform.submit();

            }

           

           

            // Esta função é chamada pela janela popup

            // quando um usuário clica em um item na listagem.

            // O item selecionado é copiado para um campo de texto

            // no formulário principal.

             

            function updatePlace(place) {

                             form=document.forms[formId];

                             form[formId+":place"].value=place;

                             winId.close();

            }

           

           

            // Esta função apenas retorna o valor selecionado

            // na combo box.

            //

            function getCountry (form) {

                  field = form[form.id+":country"];

                  return field.value;

            }

     

            // Esta função apenas limpa o campo de texto.

            // 

            function resetTextField(form, field) {

                  fieldName=form.id+":"+field;

                  form[fieldName].value="";

            }

 

      </script>

 </HEAD>

 

 <body bgcolor="white">

   <f:view>

<h:form id="whereForm">

         <h:panelGrid columns="2" headerClass="header">

            <f:facet name="header">

               <h:outputText value="#{Message.inputdata_header}"/>

                  </f:facet>

                     <h:outputText value="#{Message.promptName}"/>

                     <h:selectOneMenu id="country"

  value="#{GetPlaceBean.country}"

  onchange="resetTextField(this.form,'place')">

 

                        <f:selectItem itemValue="USA"

itemLabel="Unated States"/>

                        <f:selectItem itemValue="Canada"

itemLabel="Canada"/>

                     </h:selectOneMenu>

                  <h:outputText value="#{Message.promptPlace}"/>

                  <h:panelGroup>

            <h:inputText id="place" value="#{GetPlaceBean.place}" />

            <h:commandButton id="find" action="showPlace" value="..."

immediate="true"

onmousedown="showPlaceList(this,'placeList','find')"

                  onclick="return false"/>

            </h:panelGroup>

 

            <f:facet name="footer">

                  <h:panelGrid width="410" columns="1">

                     <f:facet name="header">

                        <h:commandButton id="visit" action="visit"

value="Vamos..."/>

                                   </f:facet>

                              </h:panelGrid>

                        </f:facet>

                  </h:panelGrid>         

    </h:form>

    <%-- Este formulário escondido é usado para a

   requisição da janela de popup. --%>

    <h:form id="placeList" target="list">

      <h:inputHidden id="country" value="#{ListHolderBean.country}">

      </h:inputHidden>

            <%--

            Esta linha de comando abaixo é usada para navegar até a

Página que contem a listagem.

            --%>

            <h:commandLink id="find" action="showPlace" value="">

                  <f:verbatim></f:verbatim>

            </h:commandLink>

    </h:form>   

  </f:view>

 </body>

</HTML> 

 

Abaixo o arquivo destination.jsp, responsável por mostrar as informações selecionadas pelo usuário.

 

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<f:loadBundle basename="demo.bundle.Messages" var="Message"/>

 

<HTML>

    <HEAD> <title>Valores Selecionados</title> </HEAD>

     

    <body bgcolor="white">

      <f:view>

                        <h3>

                  <h:outputText value="#{Message.greeting_text}" />

                  <h:outputText value="#{GetPlaceBean.place}" />,

                  <h:outputText value="#{GetPlaceBean.country}" />!

            </h3>

                        <h:form>

                             <h:commandLink action="back">

                                   <f:verbatim>Ver outros valores</f:verbatim>

                             </h:commandLink>

                        </h:form>              

      </f:view>

      </body>    

</HTML> 

 

Conclusão

Espero que tenham gostado da solução, é algo rápido e muito util para seleções de informações, certamente algumas das implementações mais conhecidas e suportadas têm algo muito mais elegante para a resolução deste problema, porém a facilidade e não dependência deste exemplo o torna extremamente fácil de se implementar.