Elementos Js f

87
1 parte D: parte D: Elementos JSF Elementos JSF para construir pantallas para construir pantallas CincoSOFT Ltda. CincoSOFT Ltda. [email protected] [email protected] http://www.cincosoft.com http://www.cincosoft.com Curso: Curso: Desarrollo de aplicaciones Desarrollo de aplicaciones en Java EE 5 (antes J2EE) en Java EE 5 (antes J2EE)

Transcript of Elementos Js f

Page 1: Elementos Js f

1

parte D:parte D:

Elementos JSF Elementos JSFpara construir pantallaspara construir pantallas

CincoSOFT Ltda.CincoSOFT [email protected]@cincosoft.com

http://www.cincosoft.comhttp://www.cincosoft.com

Curso:Curso: Desarrollo de aplicaciones Desarrollo de aplicacionesen Java EE 5 (antes J2EE)en Java EE 5 (antes J2EE)

Page 2: Elementos Js f

2

Pantalla JSF simplePantalla JSF simple

Page 3: Elementos Js f

3

Pantalla “editHotel”Pantalla “editHotel”de edición de una entidad Hotelde edición de una entidad Hotel

Page 4: Elementos Js f

4

✹ Expone directamente los atributos de la entidad Hot el ... <div class="label">Name:</div> <div class="input"> <h:inputText id="name" value=" #{hotel.name} " required="true" /> <br/> <span class="errors"> <h:message for="name" /> </span> </div>

✹ Hay una zona para los mensajes FacesMessages <div class="entry errors"> <h:messages globalOnly="true" /> </div>

✹ Los botones invocan servicios <div class="input">

<t:commandButton id="proceed" value="Proceed" action=" #{hotelInscription.verifyNewHotel} " styleClass="button" /> &#160; <s:button value="Cancel" id="cancel" action=" #{hotelInscription.cancel} " styleClass="button" /> </div>

Page 5: Elementos Js f

5

Pantalla no editable que muestraPantalla no editable que muestrauna entidad Hoteluna entidad Hotel

Page 6: Elementos Js f

6

✹ pantalla para ver datos de hotel sin editar: confirmHotel◆ muestra cada campo de la entidad hotel, por ej name : <div class="entry">

<div class="label">Name:</div> <div class="output"> #{hotel.name} </div> </div>

◆ botones finales para invocar confirm(), cancel() o regresar a lapantalla anterior<div class="input">

<t:commandButton id="confirm" value="Confirm" action=" #{hotelInscription.confirm} " styleClass="button" /> &#160; <t:commandButton id="revise" value="Revise" action=" backEditHotel " styleClass="button"/>&#160; <t:commandButton id="cancel" value="Cancel" action=" #{hotelInscription.cancel} " styleClass="button" /> </div>

◆ observar el alias " backEditHotel " definido en navigation.xmlcomo /pages/hotels/hotelInscription/editHotel.xhtml o como acción enpages.xml

Page 7: Elementos Js f

7

Estructuración de Estructuración de pantallas “pantallas “ faceletsfacelets””mediante mediante templatestemplates y <div> y <div>

Page 8: Elementos Js f

8

Concepto de Concepto de templatetemplate

✹ Concepto de template:◆ pantalla base que define estructura común de las pantallas reales◆ contiene partes fijas y partes que deben ser redefinidas por cada pantalla◆ ejemplo de estructura de pantalla:

banner

contentsidebar

footer

Page 9: Elementos Js f

9

✹ Ejemplo de template: template.xhtml

<!-- librerias de etiquetas --><html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:t="http://myfaces.apache.org/tomahawk">

<!-- referencia al archivo que define estilos de los div --><head> <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" /> <title>Hotels reservation system</title> <link href="../css/ screen.css " rel="stylesheet" type="text/css"/></head>

Page 10: Elementos Js f

10

<body><!-- div que define estructura global de toda pantalla --><div id="document" >

<!-- toda pantalla tiene un banner fijo --> <div id="headerMenu"> <div id="titleMenu"><h4>CincoSOFT framework</h4></div> <div id="statusMenu"> <t:jscookMenu layout="hbr" theme="ThemeIE"> <t:navigationMenuItems value="#{login.menu}" /> </t:jscookMenu> </div> </div> <!-- toda pantalla tiene un contenido variable: partes sidebar y content deben ser definidos por c/pantalla

--> <div id="container"> <div id="sidebar" style=" width : 150px;"> <ui:insert name=" sidebar " /> </div>

<div id="content" style="width : 500px;"> <ui:insert name=" content " /> <ui:include src=" footer.xhtml " /> </div> </div></div></body></html>

Page 11: Elementos Js f

11

◆ etiqueta más externa <ui:composition> indica que se usa un template◆ la etiqueta <ui:define> redefine partes variables del template◆ se diseña con <div> que tienen estilos asociados◆ ejemplo: password.xhtml :

<!-- librerias de etiquetas; template utilizado --><ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:t="http://myfaces.apache.org/tomahawk" xmlns:s="http://jboss.com/products/seam/taglib" template="../common/template.xhtml" >

<!-- definicion de la parte content --> <ui:define name=" content " > <div class="section"> <h1>Change Your Password</h1> </div> <div class="section"> ... </div> </ui:define>

<!-- definicion de la parte content --> <ui:define name=" sidebar " > <h1>changePassword use case</h1> </ui:define></ui:composition>

faceletfacelet: Pantalla real: Pantalla realque se basa en el templateque se basa en el template

Page 12: Elementos Js f

12

◆ se definen en el archivo screen.css◆ algunos estilos:

/* para el div mas externo de una pantalla */#document { padding: 0 1px; background: #fff url(../img/bg.gif) 0 0 repeat-y; float: left; border-bottom: 1px solid #C3BBB6;}

/* para el banner con el menu */#headerMenu { float: left; width: 758px; height: 40px; background: url(../img/hdr.bg.gif) 0 0 repeat-x;}

/* para el contenido variable */#container { float: left; width: 758px; background: url(../img/hdr.bar.jpg) 0 0 repeat-x;}

Estilos asociados a los <div>Estilos asociados a los <div>

Page 13: Elementos Js f

13

/* para la parte content dentro del contenido variable */#content { float: left; width: 548px; margin-top: 75px; padding-top: 5px; background: #fff url(../img/cnt.bg.gif) 0 0 repeat-x;}

/* para un div section dentro de content */#content .section { float: left; width: 518px; padding: 15px 15px 0 15px;}

/* redefine h1 dentro de div section dentro de content */#content .section h1 { font-family: "Trebuchet MS", Arial, sans-serif; line-height: normal; font-weight: normal; font-size: large;}...

Page 14: Elementos Js f

14

✹ Ejemplo: pantalla home

◆ encierra sus elementos en:

<f:view>

...

</f:view>

◆ dentro de <f:view> utilizar:• botones <h:commandButton action="main" value="Go Login" styleClass="button" />

• enlaces <s:link id="register" action="register" value="Register new user" />

La pantalla inicial antes de autenticaciónLa pantalla inicial antes de autenticaciónno usa templateno usa template

Page 15: Elementos Js f

15

Librerías de elementos JSFLibrerías de elementos JSF

Page 16: Elementos Js f

16

Múltiples librerías que pueden combinarseMúltiples librerías que pueden combinarse

✹ elementos estándares h: y f:◆ xmlns:h="http://java.sun.com/jsf/html”◆ xmlns:f="http://java.sun.com/jsf/core"

✹ elementos ui: para soportar facelets◆ xmlns:ui="http://java.sun.com/jsf/facelets”

✹ elementos s: ofrecidos por Seam◆ xmlns:s="http://jboss.com/products/seam/taglib"

✹ elementos t: ofrecidos por Apache Myfaces (Tomahawk)

◆ xmlns:t="http://myfaces.apache.org/tomahawk"

✹ elementos ajax (a: y rich: ) ofrecidos por JBoss -RedHat◆ xmlns:a="https://ajax4jsf.dev.java.net/ajax"◆ RichFaces (Exadel): xmlns:rich ="http://richfaces.ajax4jsf.org/rich"

✹ otras librerías: Oracle ADF, IceFaces, ...

Page 17: Elementos Js f

17

Validación, enlaces y botonesValidación, enlaces y botones

Page 18: Elementos Js f

18

✹ Validación JSF antes de invocar servicios:

Page 19: Elementos Js f

19

Validación de datos en el nivel web Validación de datos en el nivel web mediantemediantelos elementos los elementos <s:validate><s:validate> y y <s:validateAll><s:validateAll>

◆ <s:validate> y <s:validateAll> son elementos Seam y se utilizanen la pantalla de edición de datos de una entidad

◆ se engloban los elementos a validar con:<s:validateAll> ... </s:validateAll>

o se aplica a un elemento particular con <s:validate/> ej:<h:inputSecret id="password"

value=" #{user.password} " required="true" ><s:validate/>

</h:inputSecret>

◆ la validacion se realiza a nivel Web como prerequisito previo ainvocar cualquier acción (servicio) de los EJB

◆ las validaciones realizadas son las correspondientes a la entidad(indicadas por anotaciones)

◆ los elementos que se validan deben usar el atributo:required="true"

Page 20: Elementos Js f

20

✹ Invocar una acción enviando en una forma los datossuministrados por el usuario, previa validación

◆ usar botón <t:commandButton>

<h:form> ... <t:commandButton value="Proceed" action=" #{hotelInscription.verifyNewHotel} " styleClass="button” /> </h:form>

Invocar acciones con o sin validación previa:Invocar acciones con o sin validación previa:elementos elementos <t:commandButton><t:commandButton>, , <s:button><s:button> y y <s:link><s:link>

Page 21: Elementos Js f

21

✹ Invocar una acción sin requerir validar ni enviar l osdatos suministrados por el usuario

◆ usar <s:button> que no requiere campos validados antes deinvocar la acción, por ej:

<s:button value="Cancel" action=" #{hotelBooking.cancel} " styleClass="button" />

◆ <s:link> para invocar una acción (no envía datos) :

• en forma de botón: <s:link value="delete" action=" #{userGestion.deleteUser} " linkStyle="button" buttonClass="buttonSmall" />

• en forma de imagen: <s:link action=" #{userGestion.addProfile} " > <img src="../../public/img/rightArrow.gif" /> </s:link>

Page 22: Elementos Js f

22

✹ Validar un campo a medida que el usuario teclea◆ ej: pantalla book.xhtml para registrarse en un hotel : mensajes AJAX de validación ANTES de invocar la acción:

Validación con facilidades AjaxValidación con facilidades Ajax

Page 23: Elementos Js f

23

◆ mensajes JSF de validación DESPUES de invocar la acción:

Page 24: Elementos Js f

24

✹ elementos <s:decorate>, <a:support>, <a:outputPanel><s:validateAll> <!-- imagen para mostrar junto a campo invalido --> <f:facet name=" beforeInvalidField " > <h:graphicImage value="../../public/img/error.gif" /> </f:facet> <!-- estilo para resaltar campo invalido --> <f:facet name=" aroundInvalidField " > <s:span styleClass="errors"/> </f:facet> ... <div class="entry"> <div class="label"> <h:outputLabel for="creditCard">Credit Card #: </h:outputLabel> </div> <div class="input"> <s:decorate> <h:inputText id="creditCard" value="#{ booking.creditCard }" required="true"> <a:support event="onblur" reRender="creditCardErrors" /> </h:inputText> <br/> <a:outputPanel id="creditCardErrors" > <s:message/> </a:outputPanel> </s:decorate> </div> </div> ...</s:validateAll>

Page 25: Elementos Js f

25

Fechas, horas y calendariosFechas, horas y calendarios

Page 26: Elementos Js f

26

Mostrar una fecha-hora con elementosMostrar una fecha-hora con elementos<t:outputText><t:outputText> y y <f:convertDateTime><f:convertDateTime>

◆ Se muestra un elemento de texto de salida convirtiéndolo a unafecha

◆ Ejemplo: pantalla confirm.xhtml, mostrar campo checkoutDate : ...

<div class="entry">

<div class="label">Check Out Date:</div>

<div class="output">

<t:outputText

value=" #{booking.checkoutDate} " >

<f:convertDateTime type="date" />

</t:outputText>

</div>

</div> …

Page 27: Elementos Js f

27

Edición de una fecha-hora con elementosEdición de una fecha-hora con elementos<t:inputText><t:inputText> y y <f:convertDateTime><f:convertDateTime>

◆ Se muestra elemento de texto de entrada con convertidor de fecha◆ Ejemplo: pantalla book.xhtml, edición del campo checkoutDate con

validación y campo de error:

<s:validateAll> <f:subview>

...<div class="entry">

<div class="label">Check Out Date:</div> <div class="input"> <t:inputText id="checkoutDate" value=" #{booking.checkoutDate} " required="true" > <f:convertDateTime timeZone=" #{timeZone} " type="date" /> </t:inputText> <br/> <span class="errors"> <h:message for="checkoutDate" /> </span> </div> </div> ...

Page 28: Elementos Js f

28

◆ Importante indicar atributo timeZone para fecha-hora:• Ejs valores para zona horaria: timeZone="Antarctica/South_Pole”

timeZone="UTC”timeZone="GMT”timeZone="PST”

• también usando una variable de contexto (String o TimeZone): timeZone=" #{timeZone} "

◆ Valores posibles para el atributo type :• type="date"• type="time"• type="both” (date + time)

◆ Atributo de formato pattern :• pattern="dd.MM.yyyy" pattern="yyyy-MM-dd"• pattern="hh:mm" pattern="hh:mm a"• pattern="yyyy-MM-dd HH:mm:ss z"

◆ Atributo de estilo para date dateStyle :• dateStyle="short"• dateStyle="medium"• dateStyle="full”

◆ Atributo de estilo para time timeStyle , ej: timeStyle="short"

Page 29: Elementos Js f

29

◆ Para establecer en un EJB la zona horaria correspondiente alservidor

• se le da valor a variable de contexto de sesion, por ej "timeZone”• ej: EJB Login:

private java.util.TimeZone timeZone ;

...

timeZone = TimeZone.getDefault();

Contexts.getSessionContext().set("timeZone", timeZone );

Page 30: Elementos Js f

30

Calendario con el elemento Calendario con el elemento <<t:inputCalendar>t:inputCalendar>

Page 31: Elementos Js f

31

◆ Ejemplo: pantalla book.xhtml, edición del campo checkinDate convalidación y campo de error:

... <s:validateAll> <f:subview>

... <div class="entry">

<div class="label">Check In Date:</div> <div class="input"> <t:inputCalendar id="checkinDate" renderAsPopup="true" value=" #{booking.checkinDate} ” popupDateFormat="dd-MM-yyyy" renderPopupButtonAsImage="true" popupWeekString="Semana" popupTodayString="Hoy es" /> <br/> <span class="errors"> <h:message for="checkinDate" /> </span> </div> </div> ...

Page 32: Elementos Js f

32

◆ Pueden indicarse los estilos de los elementos del calendario:

<t:inputCalendar id="checkinDate"

monthYearRowClass="yearMonthHeader"

weekRowClass="weekHeader"

dayCellClass="dayCell"

currentDayCellClass="currentDayCell”

renderAsPopup="true”

value=" #{booking.checkinDate} "

popupDateFormat="dd/MM/yyyy"

/>

Page 33: Elementos Js f

33

Listas de SelecciónListas de Selección

Page 34: Elementos Js f

34

Lista de selección estática con elementosLista de selección estática con elementos<h:selectOneMenu><h:selectOneMenu> y y <f:selectItem><f:selectItem>

✹ Varios tipos de listas de selección◆ <h:selectOneListbox>◆ <h:selectOneMenu>, …

✹ Lista de selección con items estáticos◆ el item seleccionado da valor a un atributo de una entidad o de

EJB

<h:selectOneMenu id="beds" value=" #{booking.beds} " >

<f:selectItem itemLabel="One king-size bed” itemValue="1" />

<f:selectItem itemLabel="Two double beds" itemValue="2" />

<f:selectItem itemLabel="Three beds" itemValue="3" />

</h:selectOneMenu>

Page 35: Elementos Js f

35

<h:form>...

<h:selectOneListbox id="systemProfiles" value=" #{userGestion.systemProfile} " size="10" styleClass="selectOneListbox"> <f:selectItems value=" #{userGestion.systemProfiles} " /> </h:selectOneListbox></h:form>

Lista de selección dinámica con elementosLista de selección dinámica con elementos<f:selectItems><f:selectItems>

✹ Los valores de los items son calculados por un EJB◆ además de los items dinámicos se pueden agregar item estáticos

mediante <f:selectItem>◆ ejemplo users.xhtml, lista “systemProfiles”

Page 36: Elementos Js f

36

public List<SelectItem> getSystemProfiles () { List<SelectItem> selectItems = new ArrayList<SelectItem>();

for (Profile p : systemProfiles){ . . . // value, display selectItems .add(new SelectItem(p.getId(), p.getName())); } return selectItems ;}

✹ EJB de sesión que soporta la lista de seleccióndinámica

◆ Método getSystemProfiles() que calcula los items, invocado en <f:selectItems value=" #{userGestion.systemProfiles} " />

Page 37: Elementos Js f

37

public void setSystemProfile (Long s) { // s is the value of selected item profileToAdd = s;}

✹ Método que reacciona a la selección de un itemcuando hay submit de la forma:◆ invocado en value=" #{userGestion.systemProfile} "

✹ Método que establece el item inicialmenteseleccionado en la lista:

◆ invocado en value=" #{userGestion.systemProfile} "

public Long getSystemProfile () { // return item value return ((Profile)systemProfiles.get(0)).getId();}

Page 38: Elementos Js f

38

Tabla básica asociada aTabla básica asociada auna lista de entidadesuna lista de entidades

Page 39: Elementos Js f

39

Pantalla que muestra un elementoPantalla que muestra un elemento<t:dataTable><t:dataTable> asociado a una variable lista asociado a una variable lista

✹ Ej. lista de atracciones de un hotel

Page 40: Elementos Js f

40

✹ Ej. pantalla hotel.xhtml : muestra detalles de un hotel◆ Observar expresiones #{...} en lenguaje EL (Expression Language)

<div class="entry"> <div class="label">Atractions:</div> <div class="output"> <h:form> <t:outputText value="No atractions Found" rendered=" #{atractions.rowCount==0} " />

<t:dataTable value=" #{atractions} " var=" atract " rendered=" #{atractions.rowCount>0} " > <h:column> <f:facet name="header">Name of atraction </f:facet> #{atract.description} </h:column> </t:dataTable> </h:form> </div></div>

Page 41: Elementos Js f

41

@In(required=false) @Out private Hotel hotel;

@DataModel private List<Atraction> atractions ;

public void selectHotel (Hotel selectedHotel) {

hotel = em. merge (selectedHotel);

atractions = hotel.getAtractions();

}

EJB de sesión que soporta el EJB de sesión que soporta el dataTabledataTable

Page 42: Elementos Js f

42

Expresiones Expresiones ELEL (Expression Language) (Expression Language)

Page 43: Elementos Js f

43

✹ Operadores de comparación: > < >= <= == !=

gt lt ge le eq ne

✹ Operadores lógicos: and or not

&& || !

✹ Operadores aritméticos: + - * / div % mod ?

Operadores usados en lasOperadores usados en lasexpresiones EL (Expression Language)expresiones EL (Expression Language)

Page 44: Elementos Js f

44

✹ Expresiones EL con valor booleano:"#{someBooleanVariable}""#{!someBooleanVariable}""#{someVariable.someAttribute}""#{varA.num1 > varB.num2}""#{empty someList}""#{not empty someList}""#{someList.rowCount==0}""#{someVariable!=null and someList.rowcount==0}""#{someList['value1'] or someList['value2']]}”"#{rule != null && rule.id != '{empty}'}"

✹ Expresión EL con valor String (ej: valor de una propiedad):"#{msgs.serviceManagement}"

"#{userprofile.user.username}""#{var.attrib1==null ? var.attrib2 : var.attrib1}"

✹ Expresión EL para invocar acción :"#{someBean.someMethod}"

Ejemplos de Expresiones ELEjemplos de Expresiones EL

Page 45: Elementos Js f

45

Tabla con scroll y ordenable por columnasTabla con scroll y ordenable por columnas

Page 46: Elementos Js f

46

✹ elemento <t:dataTable>

Pantalla que muestra una tabla ordenablePantalla que muestra una tabla ordenabley con y con scrollscroll

Page 47: Elementos Js f

47

✹ Pantalla main.xhtml: elemento <t:dataTable> <f:subview rendered=" #{hotels.rowCount>0} " > <div id="scroll"> <h:form> <t:dataTable value=" #{hotels} " var="hot" sortColumn=" #{hotelSearching.column} " sortAscending=" #{hotelSearching.ascending} " preserveSort="false" preserveDataModel="false" renderedIfEmpty="false" >

<h:column> <f:facet name="header"> <t:commandSortHeader columnName="name" arrow="true"> <h:outputText value="Name" /> </t:commandSortHeader> </f:facet> <h:outputText value=" #{hot.name} " /> </h:column> ... </t:dataTable> </h:form> </div> </f:subview>

Page 48: Elementos Js f

48

✹ Observar en la pantalla:◆ el scroll es posible gracias al div que encierra el datatable: <div id="scroll"> : está asociado al siguiente estilo en screen.css:

#scroll { height: 400px; overflow: auto; }

◆ para no ver el espacio en blanco del datatable cuando no hay datos:• debe ponerse dentro de un <f:subview> que se mostrará solo cuando sí

hay datos

◆ en el encabezado de <t:datatable> se indican acciones asociadas aordenar una columna y cambiar el modo de ordenamiento(ascendente o descendente)

• se invocan métodos setColumn() y setAscending() del EJBhotelSearching

◆ para cada columna ordenable, se indica con elemento<t:commandSortHeader> el nombre de la columna

• se tendrá para esa columna un criterio de ordenamiento en el EJBhotelSearching

Page 49: Elementos Js f

49

EJB que soporta la tabla ordenableEJB que soporta la tabla ordenable

✹ Nuevos atributos del EJB HotelSearchingprivate String column = "name";

private boolean ascending = true;

✹ Métodos set invocados como acciones de la pantalla:

public void setAscending (boolean ascending) { this. ascending = ascending; sort(hotels); }

public void setColumn (String column) { this. column = column; sort(hotels); }

◆ invocan el método privado sort

Page 50: Elementos Js f

50

✹ Metodo privado sort : define criterio de ordenamientode cada columna ordenable :

private void sort (List data) {

Collections.sort(data, new Comparator<Hotel>() {

public int compare(Hotel o1, Hotel o2) {

if (!ascending){ Hotel temp = o2; o2 = o1; o1 = temp; } if ("name".equals(column)){ return o1.getName().compareTo(o2.getName()); } else if ("address".equals(column)){ return o1.getAddress().compareTo(o2.getAddress()); } ...

return 0; } });}

Page 51: Elementos Js f

51

Facilidades Ajax de búsqueda con una tablaFacilidades Ajax de búsqueda con una tablacomo resultadocomo resultado

Page 52: Elementos Js f

52

✹ Reacción a cada carácter tecleado

Entrega de resultados a medida que elEntrega de resultados a medida que elusuario teclea el patrón de búsquedausuario teclea el patrón de búsqueda

Page 53: Elementos Js f

53

✹ Pantalla main.xhtml: elementos <a:support>, <a:status>, <a:outputPanel>

◆ El campo patrón de búsqueda se habilita con ajax para que labúsqueda se active con cualquier carácter tecleado por elusuario:

<h:inputText id="searchString" value=" #{hotelSearch.searchString} "

style="width: 165px;" > <a:support event="onkeyup" actionListener=" #{hotelSearch.find} " reRender=" searchResults " />

</h:inputText>

◆ Se puede agregar una imagen "status" que se mueve mientrasse completa una búsqueda:

<a:status> <f:facet name="start" > <h:graphicImage value="../../public/img/spinner.gif" /> </f:facet> </a:status>

Page 54: Elementos Js f

54

◆ El panel de resultados "searchResults " debe englobar la tabla deresultados

<a:outputPanel id=" searchResults " >

<div class="section"> <h:outputText value="No Hotels Found" rendered="#{hotels != null and hotels.rowCount==0}" /> <t:dataTable id="hotels" value="#{hotels}" var="hot" rendered="#{hotels.rowCount>0}" > <h:column> <f:facet name="header">Name</f:facet> #{hot.name} </h:column> ... </t:dataTable> </div>

</a:outputPanel>

Page 55: Elementos Js f

55

Tabla de resultadosTabla de resultadosque se muestra por pantallazosque se muestra por pantallazos

Page 56: Elementos Js f

56

Un enlace o botón llevaUn enlace o botón llevaal siguiente pantallazoal siguiente pantallazo

✹ El enlace " More results" se muestra solo si hay más pantallazos

Page 57: Elementos Js f

57

EJB con query para obtenerEJB con query para obtenerlos datos por loteslos datos por lotes

✹ EJB HotelSearching◆ Servicio público find() invoca un query por lotes

public String find (){ page = 0; queryHotels(); return "main";}private void queryHotels (){ String searchPattern = searchString==null ? "%" : '%' + searchString.toLowerCase().replace('*', '%') + '%'; hotels = em.createQuery (" select h from Hotel h where (lower(h.name) like :search " + " or lower(h.city) like :search " + " or lower(h.zip) like :search " + " or lower(h.address) like :search) " + " and h.status = :status " + " order by h.name ") .setParameter("search", searchPattern) .setParameter("status", Status.ACTIVE) .setMaxResults(pageSize) .setFirstResult( page * pageSize ) .getResultList();}

Page 58: Elementos Js f

58

◆ Servicios para obtener el siguiente lote (pantallazo)

◆ El enlace que lleva a la siguiente pantalla utiliza los anterioresservicios:

<s:link value="More results"

action=" #{hotelSearching.nextPage} "

rendered=" #{hotelSearching.nextPageAvailable} " />

public boolean isNextPageAvailable (){ return hotels!=null && hotels.size()== pageSize;}

public void nextPage () { page++; queryHotels();}

Page 59: Elementos Js f

59

Tabla editable con validación por celdaTabla editable con validación por celda

Page 60: Elementos Js f

60

✹ elemento <t:dataTable>✹ mensaje de validación en la misma celda del error

Pantalla que muestra tabla editablePantalla que muestra tabla editablecon validación por celdacon validación por celda

Page 61: Elementos Js f

61

✹ Pantalla main.xhtml: elemento <t:dataTable>◆ Se escogieron algunas columnas que eran <h:outputText> y se

transformaron en <h:inputText> con validacion:

...<h:form> <t:dataTable value=" #{bookings} " var="book" rendered=" #{bookings.rowCount>0} " > ... <h:column> <f:facet name="header" >Check in date </f:facet> <h:inputText id="checkinDate" value=" #{book.checkinDate} " required="true" > <f:convertDateTime type="date" /> <s:validate/> </h:inputText> <br/><span class="errors"> <h:message for="checkinDate" /> </span> </h:column> ...

Page 62: Elementos Js f

62

◆ Se agregan 2 botones despues de las columnas de la tabla:Update y Cancel :

... <f:facet name="footer" > <h:panelGroup> <t:commandButton value="Update" action=" #{bookingList.update} " styleClass="button" /> &#160; <s:link value="Cancel" action=" #{bookingList.cancelUpdates} " linkStyle="button" buttonClass="button" /> </h:panelGroup> </f:facet> </t:dataTable></h:form>

Page 63: Elementos Js f

63

EJB que soporta EJB que soporta la tabla editable conla tabla editable convalidación por celdavalidación por celda

✹ EJB BookingList◆ Nuevos servicios

• update : para cada elemento “booking” de la lista que se muestraen la tabla, valida que la fecha checking sea anterior a checkout; sies correcto actualiza la BD con el nuevo valor del elemento:

public String update () { for (int i=0; i < bookings.size(); i++) { Booking b1 = (Booking)bookings.get(i); if (!b1.getCheckinDate().before( b1.getCheckoutDate() ) ) { FacesMessages.instance().add ("Check out date must be later than check in date for" + + " booking with number " + b1.getId()); return null; } Booking b2 = em. merge (b1); } getBookings (); return " main ";}

Page 64: Elementos Js f

64

◆ cancelUpdates: vuelve a obtener la lista de bookings de la BD:

public String cancelUpdates () { getBookings(); return " main ";}

@Factorypublic void getBookings () { bookings = em. createQuery ("select b from Booking b " + "where b.user.username = :username " + "order by b.checkinDate") .setParameter("username", user.getUsername()) .getResultList();}

Page 65: Elementos Js f

65

Tablas anidadasTablas anidadas

Page 66: Elementos Js f

66

Pantalla con 3 tablas anidadasPantalla con 3 tablas anidadas

✹ Ejemplo: mostrar módulos - casos de uso - servicios

Page 67: Elementos Js f

67

...<!-- tabla mas externa de modulos --><t:dataTable value=" #{modules} " var=" module " styleClass="standardTable" columnClasses="standardTable_Column,standardTable_C olumnCentered"> <h:column> <f:facet name="header">module </f:facet> <t:outputText value=" #{module.name} " style="color:green; font-size: large; font-weight:b old; " /> </h:column>

<h:column>

<f:facet name="header">use case </f:facet> <!-- tabla intermedia de usecases de cada modulo --> <t:dataTable value=" #{module.usecases} " var=" usecase " styleClass="standardTable_ColumnCentered" columnClasses="nestedColumn1,nestedColumn2" rowClasses="standardTable_Row1,standardTable_Row2" >

✹ Pantalla profiles.xhtml: elemento <t:dataTable>asociado a modules

Page 68: Elementos Js f

68

<h:column> <t:outputText value=" #{usecase.display} " style="font-size: small; font-weight:bold;" /> </h:column>

<h:column> <!-- tabla mas interna: servicios de c/usecase --> <t:dataTable value=" #{usecase.services} " var=" service " styleClass="nestedColumn2" columnClasses= "moreNestedColumn1,moreNestedColumn2" > <h:column> <t:outputText value=" #{service.display} " /> </h:column> <h:column> <h:selectBooleanCheckbox value=" #{service.activeInProfile} " /> </h:column> </t:dataTable> </h:column> </t:dataTable> </h:column>

<f:facet name="footer" > <h:panelGroup> <t:commandButton value="Update " . . . /> </h:panelGroup> </f:facet> </t:dataTable>

Page 69: Elementos Js f

69

Menú jerárquico dinámicoMenú jerárquico dinámico

[adaptación de CincoSOFT]

Page 70: Elementos Js f

70

Uso del menu Uso del menu jscookmenujscookmenu en una pantalla en una pantalla✹ elemento <t:jscookMenu>

Page 71: Elementos Js f

71

✹ Pantalla template.xhtml : elemento t:jscookMenu

<div id="headerMenu"> <div id="titleMenu">

<h4>CincoSOFT framework</h4></div><div id="statusMenu"> <t:jscookMenu layout="hbr" theme="ThemeIE" > <t:navigationMenuItems value=" #{login.menu} " /> </t:jscookMenu></div>

</div>

◆ elemento definido y soportado por tomahawk.jar (contiene clases,javascript y estilos requeridos)

◆ los elementos del menu son calculados por el servicio menu() delEJB de sesión login

Page 72: Elementos Js f

72

Entidad MenuEntidad Menu

✹ Menu.java : representa elementos de un menújerárquico@Entity@Name("menu")@Scope(SESSION)@Table(name="Menu")public class Menu implements Serializable {

private Long id ;private String action ;private String icon ;private String display ; // if submenuprivate Usecase usecase ; // if not submenuprivate Module module ;private Menu parent ;

private List<Menu> submenus = new ArrayList<Menu>();

private int numChilds ; // transient...

Page 73: Elementos Js f

73

✹ Inserción de elementos en la tabla Menu:

/* elemento submenu */insert into menu (id, display, icon, action, usecase_id, module_id, parent_id) values (nextval('hibernate_sequence'), 'Security actions', 'playBlue.jpg', NULL, NULL, (select id from module where name = 'security'),NULL);

/* elemento terminal correspondiente a un caso de uso */insert into menu (id, display, icon, action, usecase_id, module_id, parent_id) values ( nextval('hibernate_sequence'), NULL, 'playOrange.jpg', 'password', (select id from usecase where name = 'changePassword'), (select id from module where name = 'security'), (select id from menu where display = 'Security actions'));...

Page 74: Elementos Js f

74

Métodos de un EJB de sesiónMétodos de un EJB de sesiónpara construir el menúpara construir el menú

✹ EJB de sesión Login◆ método login() invocado solo 1 vez cuando el usuario inicia

sesión:• carga los menus de la base de datos:

mainMenus = em. createQuery ("select m from Menu m where m.parent is null " + "order by m.display") .getResultList();

systemMenus = em. createQuery ("select m from Menu m where m.parent is not null " + "order by m.parent.id, m.id") .getResultList();

• obtiene los submenus de cada elemento para calcularnúmero de hijos (numChilds)

• elimina cada elemento terminal correspondient a un caso deuso no permitido al usuario, actualizando numChilds de suelemento padre

• elimina elementos no terminales con 0 hijos (numChilds == 0)

Page 75: Elementos Js f

75

◆ método getMenu() invocado cada vez que una pantalla requiereel menú (elemento <t:jscookmenu>): construye recursivamente laestructura del menu

• contruye un objeto NavigationMenuItem para cada elementodel menú

• si un elemento tiene hijos, se le asocia un arregloNavigationMenuItem[] donde cada elemento corresponde aun hijo

Page 76: Elementos Js f

76

Internacionalización en JSFInternacionalización en JSF

Page 77: Elementos Js f

77

Características de una aplicación conCaracterísticas de una aplicación coninternacionalizacióninternacionalización

✹ Objetivos:◆ el usuario debe poder escoger el idioma de su preferencia◆ existe idioma por defecto según localización del usuario◆ los letreros de las pantallas deben salir en el idioma vigente◆ los mensajes de errores de validación también deben salir en el

idioma vigente

✹ Letreros de pantallas deben registrarse en archivosde propiedades para los diferentes idiomas◆ Archivo messages.properties : contiene el valor de los letreros

de las pantallas en el idioma por defecto (ubicado bajoWEB-INF/classes)

◆ Archivos messages_ xx.properties :• c/u contiene el valor de los letreros en un determinado idioma• valor de xx corresponde a un idioma más opcionalmente un país:

en, en_US, en_AU, de, fr, es, es_CO, ja, it, ca, pt , ru, zh , ...• cuando el usuario selecciona un idioma, se debe establecer cuál

es el archivo de propiedades vigente

Page 78: Elementos Js f

78

✹ Las pantallas no deben usar literales sino propieda des

◆ Ejemplo: el siguiente boton utiliza la propiedad “GoLogin” yaparecerá como “Go Login”, “Entrar”, etc. según el idioma vigente

<h:commandButton value=" #{messages.GoLogin} " action="main" styleClass="button" />

◆ #{messages.GoLogin} es equivalente a #{messages['GoLogin']}donde messages es un componente interno de seam

◆ en los diferentes archivos de propiedades de idiomas debe existirel valor de la propiedad “GoLogin”, por ejemplo en el archivomessages_es.properties :

GoLogin=Entrar

Page 79: Elementos Js f

79

Cómo JSF determina el idioma a utilizarCómo JSF determina el idioma a utilizaren la sesión del usuarioen la sesión del usuario

✹ JSF selecciona como idioma vigente (locale) el corr espondienteal browser

✹ Si no se puede deducir del browser: se usa el idiom a defaultindicado en faces-config.xml :

<application> ... <locale-config> <default-locale> en</default-locale> <supported-locale>fr</supported-locale> <supported-locale>es_CO</supported-locale> </locale-config> </application>

✹ Si faces-config-xml no indica idioma default: se usa el idiomaasociado al servidor

✹ Los letreros de las pantallas que usen propiedades messagesextraerán los valores del archivo messages_ xx.propertiesasociado al idioma vigente xx◆ si no existe el archivo messages_ xx.properties : se utiliza el archivo

messages.properties

Page 80: Elementos Js f

80

Cómo permitir al usuario seleccionar elCómo permitir al usuario seleccionar elidioma de su sesiónidioma de su sesión

✹ En la pantalla de entrada ( home ) agregar lista deselección con los idiomas ofrecidos

◆ la lista de selección se apoya componente interno de seam“localeSelector ” que captura el idioma seleccionado por el usuario ylo asigna como idioma de la sesión:

<h:outputText value=" #{messages.SelectLanguage} (select)" />

<h:selectOneMenu value=" #{localeSelector.localeString} "> <f:selectItems value=" #{localeSelector.supportedLocales} " /> </h:selectOneMenu>

<h:commandButton value=" #{messages.ChangeLanguage} (change)" action=" #{localeSelector.select} " styleClass="button" />

Page 81: Elementos Js f

81

✹ Idiomas que se ofrecen en la lista de selección

◆ si faces-config.xml no tiene indicaciones de idiomas entonces lalista de selección ofrece todos los idiomas soportados por JSF:

en, en_US, en_AU, de, fr, es_CO, ja, it, ca, pt, ru , zh

◆ faces-config.xml debería restringir los idiomas soportados asolamente los que tienen archivo messages_ xx .propertiesasociado, y solamente esos idiomas saldrán en la lista deselección

◆ cuando el usuario selecciona un idioma, este se vuelve el vigentepara la sesion

• si no existe el archivo messages_ xx .properties correspondiente,entonces se usará el archivo asociado al browser

• si tampoco existe éste, entonces se usara el archivo defaultmessages.properties

Page 82: Elementos Js f

82

✹ El atributo required="true" implica validacion JSFcon mensaje de error traducido al idioma vigente:

<h:inputText id="name" value=" #{hotel.name} ” required="true" > <s:validate /></h:inputText> <br/><span class="errors"> <h:message for="name" /> </span>

✹ Cuando el usuario no suministra ningún valor, salemensaje de error construido por JSF en el idiomavigente, ejemplo:

• "name": Value is required.• "name": Valor requerido.• "name": Une donnée est requise.• "name": Il valore è obbligatorio• "name": Um valor é requerido.• "name": Eingabe erforderlich.• …

✹ El atributo id debe usar una propiedad de idiomapara mostrarse en el idioma vigente:

• cambiar id="name" por id="#{messages.name}

Mensajes de errores de validaciónMensajes de errores de validaciónen el idioma vigenteen el idioma vigente

Page 83: Elementos Js f

83

✹ Validación de entidades asociada a anotaciones

◆ Notar que la anotacion @Length no indica ningún mensaje de error devalidación porque si lo hiciera lo tendría que expresar en un idiomaconcreto:

@Length(min = 1, max = 20, message="longitud debe estar entre {min] y {max}")

◆ Cuando el dato del usuario incumple la restricción de longitud, JSFmostrará como mensaje de error el valor de la propiedadvalidator.length :

• busca la propiedad en el archivo messages_ xx .propertiesasociado al idioma vigente

• si no la encuentra: buscará en messages.properties• si no la encuentra: sale excepcion

@Entity@Name("parameter")@Table(name = "Parameter")public class Parameter ..... @Length(min = 1, max = 20) public String getName() { return name; } ...}

Page 84: Elementos Js f

84

◆ Se recomienda dar valor en los archivos messages_ xx.properties alas propiedades asociadas a anotaciones de validacion de entidades:

• por ej: en messages_en.properties# para anotaciones @AssertFalse y @AssertTruevalidator.assertFalse=assertion failedvalidator.assertTrue=assertion failed# para anotaciones @Future y @Pastvalidator.future=must be a future datevalidator.past=must be a past date# anotaciones @Length(min=, max=)y @Range(min=, max=)validator.length=length must be between {min} and {max}validator.range=must be between {min} and {max}# para anotacion @Max(value=) y @Min(value=)validator.max=must less than or equal to {value}validator.min=must greater than or equal to {value}# para anotacion @NotNullvalidator.notNull=may not be null# para anotacion @Pattern(regex="…", flag=)validator.pattern=must match "{regex}"# para anotacion @Size(min=, max=)validator.size=size must be between {min} and {max}# para anotacion @Emailvalidator.email=not a well-formed email address

Page 85: Elementos Js f

85

✹ Expresiones para dar valor a las propiedades

◆ Expresiones según reglas de sintaxis de java.text.MessageFormat• ver http://java.sun.com/j2se/1.5.0/docs/api/java/text/MessageFormat.html• pueden usar parámetros de las siguientes formas:

{ArgumentIndex}{ArgumentIndex,FormatType}{ArgumentIndex,FormatType,FormatStyle}

• donde:– FormatType es uno de los siguientes: number date time choice- FormatStyle es uno de los siguientes: short medium long full integer currency percent

• ejemplo de valor de propiedad con parámetros: miPropiedad = At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.

• la clase que usa la propiedad le da valor a los parámetros, por ej: String EvaluarPropiedad (String valorPropiedad) { int planet = 7;

String event = "a disturbance in the Force"; String result = MessageFormat.format

(valorPropiedad, planet, new Date() , event); return result;

} queda en result: "At 12:30 PM on Jul 3, 2053, there was a disturbance

in the Force on planet 7. "

Page 86: Elementos Js f

86

◆ Propiedades usadas en la validación de elementos Myfaces -Tomahawk (como ej. de librería de elementos JSF):

• vienen en el jar correspondiente a la librería: myfaces-impl-1.1.4.jar• hay un archivo por cada idioma soportado• usan en general parámetros, ej en Messages_fr.properties del jar: org.apache.myfaces.Date.INVALID_detail = The given value ({0}) is not a correct date

• se pueden redefinir y es recomendable agregar las propiedadesfaltantes, por ej en messages_fr.properties de la aplicación:

org.apache.myfaces.calendar.CONVERSION_detail = "{0}"\: La donn\u00E9e "{1}" ne peut pas etre convertie a une date.

◆ Expresiones EL en el valor de propiedades:• por ej en messages_en.properties WelcomeUser =Welcome #{user.name}

Page 87: Elementos Js f

87

Consulta desde los EJBs a propiedades delConsulta desde los EJBs a propiedades delarchivo asociado al idioma vigentearchivo asociado al idioma vigente

✹ Acceso a todas las propiedades del idioma vigente

✹ Acceso a una propiedad especifica:

✹ Mensajes informativos o de validacion a través deFacesMessages:

@In(create=true)private Map<String,String> messages ;. . .// ejemplo: dar valor a atributo transiente de entidad// mostrado en pantalla como// <t:outputText value="#{service.displayBis}" />Service service = . . .service.setDisplayBis(messages.get(s.getDisplay()));

@In("#{messages.Hello}")

private String helloMessage ;

@In(create=true)FacesMessages facesMessages ;...facesMessages. addFromResourceBundle ("Hello");