Mostrando entradas con la etiqueta XHTML. Mostrar todas las entradas
Mostrando entradas con la etiqueta XHTML. Mostrar todas las entradas

viernes, 19 de junio de 2020

BootsFaces

Es un Framework de front-end para JSF que tiene como base a Bootstrap 3 y jQuery-UI que permite crear páginas con Bootstrap de manera simplificada al convertir el código ingresado en HTML con el estilo definido.


Emplear BootsFaces

Existen dos manera de utilizar este Framework, la primera es mediante descarga que genera un archivo *.jar y se debe agregar al proyecto.



La otra forma es emplear un repositorio como Maven o Gradle y agregar las siguientes líneas en los archivos de construcción.
Maven Gradle
<dependency>
    <groupId>net.bootsfaces</groupId>
    <artifactId>bootsfaces</artifactId>
    <version>1.4.2</version>
    <scope>compile</scope>
</dependency>
  
compile 'net.bootsfaces:bootsfaces:1.4.2'
 


Implementar en un XHTML

Se debe agregar el siguiente atributo-valor xmlns:b="http://bootsfaces.net/ui" que como se aprecia emplea el prefijo "b".

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
   xmlns:h="http://xmlns.jcp.org/jsf/html"
   xmlns:b="http://bootsfaces.net/ui">
<h:head>
   <title>Prueba 05 - BootsFaces</title>
</h:head>
<h:body>
   <!--Código de la página-->
</h:body>
</html>


Ejemplo de aplicación

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
 xmlns:h="http://xmlns.jcp.org/jsf/html"
 xmlns:b="http://bootsfaces.net/ui">
<h:head>
 <title>Prueba 05 - BootsFaces</title>
</h:head>
<h:body>
 <b:navBar brand="INICIO" brandHref="index.html" inverse="true"
  fixed="top">
  <b:navbarLinks>
   <b:navLink value="JSF" href="#"></b:navLink>
   <b:navLink value="Bootsfaces" href="#"></b:navLink>
   <b:dropMenu value="Pruebas">
    <b:navLink value="Prueba 1" href="#"></b:navLink>
    <b:navLink value="Prueba 2" href="#"></b:navLink>
    <b:navLink value="Prueba 3" href="#"></b:navLink>
    <b:navLink></b:navLink>
    <b:navLink header="Otros"></b:navLink>
    <b:navLink value="Resultados" href="#"></b:navLink>
   </b:dropMenu>
  </b:navbarLinks>
 </b:navBar>
 <b:jumbotron>
  <b:container>
   <h1>Encabezado</h1>
   <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
    do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
    enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
    ut aliquip ex ea commodo consequat. Duis aute irure dolor in
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum.</p>
   <p>
    <a href="https://javajhon.blogspot.com/" class="btn btn-lg btn-info">
     Blog sobre Java </a>
   </p>
  </b:container>
 </b:jumbotron>
 <b:container>
  <b:row styleClass="show-grid">
   <b:column span="4">
    <h2>Botones b:commandbutton</h2><br/>
    <h:form>
    <b:commandButton action="j" value="primary" look="primary"/><br/><br/>
    <b:commandButton action="j" value="success" look="success"/><br/><br/>
    <b:commandButton action="j" value="danger" look="danger"/><br/><br/>
    <b:commandButton action="j" value="info" look="info"/><br/><br/>
    <b:commandButton action="j" value="warning" look="warning"/><br/><br/>
    <b:commandButton action="j" value="default" look="default"/><br/><br/>
    </h:form>       
   </b:column>
   <b:column span="4">
    <h2>Botones class btn-*</h2><br/>
    <a class="btn btn-lg btn-primary">primary</a><br/><br/>
    <a class="btn btn-lg btn-success">success</a><br/><br/>
    <a class="btn btn-lg btn-danger">danger</a><br/><br/>
    <a class="btn btn-lg btn-info">info</a><br/><br/>
    <a class="btn btn-lg btn-warning">warning</a><br/><br/>
    <a class="btn btn-lg btn-default">default</a>    
   </b:column>
   <b:column span="4">    
    <h2>Etiquetas</h2>
    <b:dropButton value="DropButton" look="success">
     <b:navLink value="Prueba 1" href="#"></b:navLink>
     <b:navLink value="Prueba 2" href="#"></b:navLink>
     <b:navLink value="Prueba 3" href="#"></b:navLink>
     <b:navLink></b:navLink>
     <b:navLink header="Otros"></b:navLink>
     <b:navLink value="Resultados" href="#"></b:navLink>
    </b:dropButton>
    <b:panelGrid ></b:panelGrid>
    <b:panel></b:panel>
   </b:column>
  </b:row>
  <hr />
  <footer>
   <p>© JavaJhon 2020</p>
  </footer>
 </b:container>
</h:body>
</html>

Fuentes:

  • BootsFaces. (2018). BootsFaces Showcase. Recuperado de: https://showcase.bootsfaces.net/

Java Server Faces - DataTable

Las tablas de HTML en una aplicación web con Java Server Faces se construye mediante la etiqueta h:dataTable en los Facelets.

Los datos que se pueden mostrar mediante un h:dataTable son:
  • Arrays
  • Instancias del Java Colletion Framework
  • Instancias de java.sql.ResultSet
  • Instancias de javax.servlet.jsp.jstl.sql.Result
  • Instancias de javax.faces.model.DataModel

Supongamos el siguiente bean llamado "LibroBean":
package proyectoJSF.model;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class LibroBean {

 private Integer id = 105;
 private String nombre = "JSF EL";
 private AutorBean autor = new AutorBean();
 private String[] idiomas = { "Español", "Inglés", "italiano" };
 private List<String> paises;
 private Map<String, LocalDate> ediciones;

 public LibroBean() {
  cargarPaises();
  cargarEdiciones();
 }

 public String[] getIdiomas() {
  return idiomas;
 }

 public List<String> getPaises() {
  return paises;
 }

 public Map<String, LocalDate> getEdiciones() {
  return ediciones;
 }

 private void cargarPaises() {
  paises = new ArrayList<>();
  paises.add("Perú");
  paises.add("Canadá");
  paises.add("Japón");
 }

 private void cargarEdiciones() {
  ediciones = new TreeMap<>();
  ediciones.put("Primera", LocalDate.of(2012, 12, 30));
  ediciones.put("Segunda", LocalDate.of(2015, 2, 12));
  ediciones.put("Tercera", LocalDate.of(2020, 6, 7));
 }

 public Integer getId() {
  return id;
 }

 public void setId(Integer id) {
  this.id = id;
 }

 public String getNombre() {
  return nombre;
 }

 public void setNombre(String nombre) {
  this.nombre = nombre;
 }

 public AutorBean getAutor() {
  return autor;
 }

 public void setAutor(AutorBean autor) {
  this.autor = autor;
 }

}


Se aprecia que contiene diversas estructuras de datos, vamos a mostrar la estructura MAP mediante un h:dataTable de la siguiente manera:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
 xmlns:h="http://xmlns.jcp.org/jsf/html"
 xmlns:f="http://java.sun.com/jsf/core">
<h:head>
 <title>Prueba 04 - DataTable</title>
</h:head>
<h:body>
 <h1>Ediciones de los libros</h1>
 <h:dataTable value="#{libroBean.ediciones}" var="edicion" border="1">
  <h:column>
   <f:facet name="header">
    Edición
   </f:facet>
   <h:outputText value="#{edicion.key}" />
  </h:column>
  <h:column>
   <f:facet name="header">
    Fecha de publicación (aaaa/mm/dd)
   </f:facet>
   <h:outputText value="#{edicion.value}" />
  </h:column>
 </h:dataTable>
</h:body>
</html>


Tenemos las siguientes etiqeutas y sus atributos:
  • h:dataTable, se convierte posteriormente en una tabla HTML
    • value, es el atributo cuyo valor es el que se itera dentro de la tabla
    • var, es el nombre de la variable que usaremos dentro de la estructura
    • border, similar a la propiedad "border" de una tabla HTML
  • h:column, en contraste con HTML no es necesario definir las filas, se hacen directamente las columnas. Dentro tendremos:
    • f:facet name="header", dentro de esta etiqueta con este "name" se coloca el texto que irá en dicha columna.
    • h:outputText value="#{edicion.key}", tendremos una etiqueta de texto que mostrará la clave de cada elemento del MAP
    • h:outputText value="#{edicion.value}", tendremos una etiqueta de texto que mostrará el valor de cada elemento del MAP

El resultado visual sería:
Edición Fecha de publicación (aaaa/mm/dd)
Primera 2012-12-30
Segunda 2015-02-12
Tercera 2020-06-07


Java Server Faces Expression Language (JSF EL)

Los Facelets no soportan las secuencias de comandos de Java Server Pages. Por ello, se requiere de una forma de indirectamente invocar al código Java. Así JSP y Facelets son dos tecnologías diferentes.

JSF permite la utilización de ambas incluso conjuntamente. A ello se debe acotar que Facelets es más reciente y específica para JSF ofreciendo más posibilidades al desarrollador. Se recomenda el uso de los Facelets en JSF.

El lenguaje de expresión de JSF fue inspirado en la tecnología JSTL mediante el uso de prefijos en sus bibliotecas estándar. Este se encuentra entre las capas de modelo y vista mediante la aplicación de las propiedades Setter y Getter.

Formatos

Emplear minúsculas al hacer referencia a un Bean. 
Tipo de bean EL
Atributo de un Bean Simple
#{nombre.atributo}
Ejemplo: Supongamos un Bean llamado "Mascota" que tiene un atributo llamado "peso", para llamarlo usaríamos
#{mascota.peso}
Método de un Bean Simple con retorno
#{nombre.metodo()}
Ejemplo: Supongamos un Bean llamado "Mascota" que tiene un método llamado "ladrido" que devuelve un valor String, para llamarlo usaríamos
#{mascota.ladrido()}
Atributo o método de un atributo tipo objeto de un Bean Simple
#{nombre.atrib1.atrib2}
Ejemplo: Supongamos un Bean llamado "Mascota" que tiene un atributo que es del tipo "Propietario" llamado "propietario" que devuelve un objeto y este objeto en su declaración tiene "id" y "nombre", para llamar al nombre del propietario usaríamos
#{mascota.propietario.nombre}


Aplicación

Nota: Para este caso se usa la versión JSF 2.3 y Java EE 8 con un servidor Payara

Supongamos que tenemos el siguiente "bean" llamado "AutorBeans"
package proyectoJSF.model;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class AutorBean {

 private Integer idAutor = 1;
 private String nombre = "Jhon";

 public AutorBean() {
 }
 
 public Integer getIdAutor() {
  return idAutor;
 }

 public void setIdAutor(Integer idAutor) {
  this.idAutor = idAutor;
 }

 public String getNombre() {
  return nombre;
 }

 public void setNombre(String nombre) {
  this.nombre = nombre;
 }

}


A partir de la versión 2.0 de JSF se puede emplear las EL desde cualquier parte del Facelet, ya no es necesario hacerlo dentro de sus etiquetas JSF. Para invocar a sus métodos Getter y Setter desde un Facelet debemos colocar lo siguiente:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
 xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
 <title>Prueba 03</title>
</h:head>
<h:body>
  <h1>Autor - Método GET</h1>
  <ul>
    <li>Id del autor: #{autorBean.idAutor}</li>
    <li>Nombre: #{autorBean.nombre}</li>
  </ul>
  <hr/>
  <h1>Autor - Método SET</h1>
  <h:form>
    <h:outputLabel value="Ingrese ID: "/>
    <h:inputText value="#{autorBean.idAutor}"/>
    <br/><br/>
    <h:outputLabel value="Ingrese nombre: "/>
    <h:inputText value="#{autorBean.nombre}"/>
    <br/><br/>
    <h:commandButton type="submit" value="Cambiar"/> 
  </h:form>
</h:body>
</html>


Se observa los siguiente, en este caso se modifico las cajas de texto con "10001" y "Jhon Paul" que originalmente tenían los mismos valores "1" y "Jhon":

La expresión #{autorBean.idAutor} invoca automáticamente al método GET del atributo "idAutor" y lo mismo en el caso de "nombre". Si se hace clic en el botón "Cambiar" se obtendrá el siguiente resultado:

En este caso la expresión #{autorBean.idAutor} dentro de los "h:inputText" invoca automáticamente al método SET del atributo "idAutor" y lo mismo en el caso de "nombre", que luego se ve reflejado en la primera sección del Facelet. Esto permite mucha simplicidad para el manejo de los atributos.



Manejando estructuras de datos con EL

Podemos visualizar Array y colecciones. Supongamos la siguiente clase "LibroBean" que emplea la anterior
package proyectoJSF.model;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class LibroBean {

 private Integer id = 105;
 private String nombre = "JSF EL";
 private AutorBean autor = new AutorBean();
 private String[] idiomas = { "Español", "Inglés", "italiano" };
 private List<String> paises;
 private Map<String, LocalDate> ediciones;

 public LibroBean() {
  cargarPaises();
  cargarEdiciones();
 }

 public String[] getIdiomas() {
  return idiomas;
 }

 public List<String> getPaises() {
  return paises;
 }

 public Map<String, LocalDate> getEdiciones() {
  return ediciones;
 }

 private void cargarPaises() {
  paises = new ArrayList<>();
  paises.add("Perú");
  paises.add("Canadá");
  paises.add("Japón");
 }

 private void cargarEdiciones() {
  ediciones = new TreeMap<>();
  ediciones.put("Primera", LocalDate.of(2012, 12, 30));
  ediciones.put("Segunda", LocalDate.of(2015, 2, 12));
  ediciones.put("Tercera", LocalDate.of(2020, 6, 7));
 }

 public Integer getId() {
  return id;
 }

 public void setId(Integer id) {
  this.id = id;
 }

 public String getNombre() {
  return nombre;
 }

 public void setNombre(String nombre) {
  this.nombre = nombre;
 }

 public AutorBean getAutor() {
  return autor;
 }

 public void setAutor(AutorBean autor) {
  this.autor = autor;
 }

}

Si deseamos mostrar el Array "idiomas", usaremos el siguiente código:
<h1>Libro - Idiomas disponibles</h1>
<ul>
 <li>#{libroBean.idiomas[0]}</li>
 <li>#{libroBean.idiomas[1]}</li>
 <li>#{libroBean.idiomas[2]}</li>
</ul>

Si deseamos mostrar la colección List "paises", usaremos el siguiente código:

<h1>Libro - Países de venta disponibles</h1>
<ul>
 <li>#{libroBean.paises[0]}</li>
 <li>#{libroBean.paises[1]}</li>
 <li>#{libroBean.paises[2]}</li>
</ul>

Si deseamos mostrar la colección Map "ediciones", usaremos el siguiente código:

<h1>Libro - Ediciones y fechas</h1>
<ul>
 <li>#{libroBean.ediciones["Primera"]}</li>
 <li>#{libroBean.ediciones["Segunda"]}</li>
 <li>#{libroBean.ediciones["Tercera"]}</li>
</ul>


Obteniendo el siguiente resultado:


Operaciones con EL

Podemos emplear operaciones de comparación, aritméticas, lógicas y el operador "empty".

Operaciones aritméticas
Expresión Resultado
Suma (+) #{2+2} 4
Resta (-) #{2-12} -10
Producto (*) #{7*5} 35
División ("div" o "/") #{4/5} 0.8
Residuo ("mod" o "%") #{12 mod 5} 2
Operación combinada #{(5 % 3)*2-1} 3

Operaciones de comparación
Expresión Resultado
Igual ("==" o "eq") #{"hola" eq "hola"} true
Diferente ("!=" o "ne") #{20 ne 20} false
Mayor ("gt") #{30 gt 20} true
Menor ("lt") #{10 lt 20} true
Mayor o igual ("ge") #{11 ge 22} false
Menor o igual ("le") #{12 le 12} true

Nota evitar el uso de los símbolos < y > para las comparaciones por las reglas de XML

Operaciones lógicas
Expresión Resultado
Disyunción ("or") #{(1 ne 1) or (5 ne 6)} true
Conjunción ("and") #{(1 ne 1) and (5 ne 6)} false
Negación ("!") #{!(1 eq 2)} true

El operador "empty" verifica si un contenido es vacío o nulo y retornará verdadero o falso según sea el caso. Se puede ejemplificar mediante
  • #{empty ""}
  • #{empty null}
Ambos ejemplos devolverán "true", si tenemos un valor capturado que es nulo entonces la siguiente expresión también devolverá "true"
  • #{empty clase.atributo}


Condicionales en EL

Para hacer uso de estos se emplea el operador ternario con la sintaxis:
  • #{ condición ? valorTrue : valorFalse}

Ejemplo:

<p class=" #{clase.atributo eq 5 ? 'class5' : 'class10'} ">
 
Del ejemplo se comprueba si el atributo recuperado es 5, de ser el caso la clase será "class5", sino será "class10". Tener mucha atención en el uso de comillas simples y dobles.

Otra manera de emplear los condicionales es el atributo "rendered", si este tiene como valor una condición verdadera, el elemento que posee este atributo se hará visible, de lo contrario tendrá visibilidad oculta.

Ejemplo:
<!--  Elemento invisible, porque 11 no es igual a 10 -->
<h:outputText value="Primer saludo" rendered="#{11 eq 10}"/>
<br/>
<!--  Elemento visible porque 10 es igual a 10 -->
<h:outputText value="Segundo saludo" rendered="#{10 eq 10}"/>


Resultado visual:
  • Segundo saludo