Versión: 4.0.6
En esta sección vamos a exponer los componentes primefaces recomendados desde MNCS para desarrollar las aplicaciones Fundeweb 2.0. En caso de querer consultar el listado completo de los componentes primefaces disponibles, podéis visitar su página de demostración en la url http://www.primefaces.org/showcase/ui/home.jsf
Es importante destacar que la versión de primefaces que contiene esa página de demo no está disponible aún para los desarrolladores, por lo que algún componente puede comportarse de manera ligeramente diferente a la vista en la demo. Los componentes sujetos a cambios en la versión están sombreados en el menú de demostración de primefaces.
Los componentes básicos o con una explicación suficiente en la demo de primefaces aparecen únicamente referenciados en esta guía. Los que hemos encontrado algo más complejos, novedosos, o que requieren un comportamiento especial han sido analizados. Estos análisis se pueden ampliar en base a las necesidades que surjan durante los desarrollos.
http://www.primefaces.org/showcase/ui/autocompleteHome.jsf
Este componente es una variante del componente InputText que filtra en el modelo los valores que concuerden con los caracteres introducidos en el filtro. Se puede permitir que se introduzcan valores no existentes en el filtro o impedirlo (según se desee).
Las propiedades a destacar son las siguientes:
Un ejemplo del código html
<p:autoComplete value="#{manejadorComponentesInput.provinciaSeleccionada}" id="autocompletePojo" completeMethod="#{manejadorComponentesInput.autocompleteProvincia}" var="provincia" itemLabel="#{provincia.proNombre}" itemValue="#{provincia}" converter="conversorProvincias" forceSelection="true" />
En este caso hemos mapeado directamente los datos a POJOs por lo que el código del conversor quedaría de la siguiente manera:
@FacesConverter(value = "conversorProvincias", forClass = Provincias.class) @RequestScoped public class ConversorProvincias implements Converter { private static final Logger log = Logger .getLogger(ConversorProvincias.class); //BeanManager necesario para recuperar los beans que hay cargados en el servidor //es el equivalente el Component.getInstance private BeanManager bm; @Override public Object getAsObject(FacesContext context, UIComponent component, String value) { ResourcesUtil ru = null; try { bm = (BeanManager) InitialContext.doLookup("java:comp/BeanManager"); //Recuperamos un bean de utilidad que contiene al entityManager que necesitamos //para realizar la búsqueda for (Bean b : bm.getBeans(ResourcesUtil.class)) { ru = (ResourcesUtil) bm.getReference(b, ResourcesUtil.class, bm.createCreationalContext(b)); } } catch (NamingException e) { log.error("Error obteniendo entityManager", e); } if (!UtilString.esCadenaVacia(value)) { Query consulta = ru.getEm().createNamedQuery("obtenerProvinciasId"); consulta.setParameter("codigo", value); return consulta.getSingleResult(); } else { return null; } } @Override public String getAsString(FacesContext context, UIComponent component, Object value) { if (value != null) { return ((Provincias) value).getProCodigo(); } else { return ""; } } }
Por último el código del método que devuelve la lista de opciones en base a los datos introducidos:
public List<Provincias> autocompleteProvincia(String query) { List<Provincias> provincias = new ArrayList<Provincias>(); Query consulta = em.createNamedQuery("obtenerProvinciasLike"); consulta.setParameter("filtro",query.toUpperCase()+"%"); provincias = consulta.getResultList(); return provincias; }
http://www.primefaces.org/showcase/ui/calendarAjax.jsf
Componente simple de selección de fecha, que o bien puede mostrarse al hacer click sobre el campo de texto asociado, o bien mediante un botón. Dentro de las características principales podemos destacar las siguientes:
Importante: Fundeweb ya incluye las librerias necesarias para el locale en castellano, no obstante si se quiere añadir otro idioma diferente del inglés o el español, o bien para aplicaciones no Fundeweb, es necesario, aparte de especificar el locale al componente, añadir en el directorio de recursos un fichero de nombre “calendar_(nombre del locale).js” (calendar_es.js para español). Un ejemplo del contenido de ese fichero (en español) es el siguiente:
PrimeFaces.locales['es'] = { closeText: 'Cerrar', prevText: 'Anterior', nextText: 'Siguiente', monthNames: ['Enero','Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'], monthNamesShort: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun','Jul','Ago','Sep','Oct','Nov','Dic'], dayNames: ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'], dayNamesShort: ['Dom','Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab'], dayNamesMin: ['D','L','M','X','J','V','S'], weekHeader: 'Semana', firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: '', timeOnlyTitle: 'Sólo hora', timeText: 'Tiempo', hourText: 'Hora', minuteText: 'Minuto', secondText: 'Segundo', currentText: 'Fecha actual', ampm: false, month: 'Mes', week: 'Semana', day: 'Día', allDayText : 'Todo el día' }
Un ejemplo del código del componente sería el siguiente:
<p:calendar id="fechaAnuncio" pattern="dd/MM/yyyy" value="#{manejadorAnuncios.anuncioSeleccionado.fechaPublicacion}" locale="es" />
http://www.primefaces.org/showcase/ui/editor.jsf
Editor de texto enriquecido con barra de opciones configurable mediante la propiedad “controls”. El contenido del editor se guarda en formato html utilizando los caracteres de escape para los signos reservados. Las posibles opciones de configuración de la propiedad “controls” se especifican una a una separas por espacios.
Estas opciones son las siguientes: bold, italic, underline, strikethrough, subscript, superscript, font, size, style, color, highlight, removeformat, bullets, numbering, outdent, indent alignleft, center, alignright, justify, undo, redo, rule, image, link, unlink, cut, copy, paste, pastetext, print, source (muestra el codigo html que se va generando)
Un ejemplo de código sería el siguiente:
<p:editor id="editAnuncio" width="600" controls="bold italic underline strikethrough size font bullets numbering" rendered="#{manejadorAnuncios.modoEdicion}" value="#{manejadorAnuncios.anuncioSeleccionado.descripcion}" readonly="#{manejadorAnuncios.modoEdicion}" />
http://www.primefaces.org/showcase/ui/fileUploadMultiple.jsf
Componente de subida de ficheros. Permite subir múltiples ficheros y limitar tanto el tamaño y tipo de los mismos, como la cantidad máxima de ficheros a subir. Podemos hacer uso de dos casos, el simple que utiliza características del navegador y presenta una funcionalidad más recortada, o el avanzado que amplia las funcionalidades del componente, modifica el estilo visual y está basado en HTML5 (importante asegurar la compatibilidad del navegador).
Modo simple Este modo es parecido al que se puede simular por javascript. Recoge un fichero simple y lo sube al servidor tras hacer submit. Requiere, por tanto, un botón para ejecutar la acción que suba el documento.
<p:fileUpload value="#{manejadorFicheros.fichero}" mode="simple" /> <p:commandButton value="Submit" ajax="false" actionListener="#{manejadorFicheros.agregaFichero()}" />
Modo avanzado En este modo se nos permiten funcionalidades avanzadas como subir múltiples documentos a la vez usando ajax. Validaciones directas en el componente, visualización del listado de documentos, etc…
Las propiedades más relevantes son:
El componente por defecto limpia la lista de los ficheros que se han subido, en caso de querer mantenerla, de momento, se debe hacer mediante un componente a parte que se refresque con los nombres de los mismos.
El código de ejemplo es el siguiente:
<p:fileUpload fileUploadListener="#{manejadorComponentesInput.subidaFichero}" mode="advanced" dragDropSupport="true" multiple="true" update=":messages" sizeLimit="10000000" fileLimit="3" invalidFileMessage="#{messages['fileupload.invalid.type']}" invalidSizeMessage="#{messages['fileupload.invalid.size']}" fileLimitMessage="#{messages['fileupload.invalid.fileNumber']}" cancelLabel="#{messages['value.cancel']}" label="#{messages['fileupload.label.upload']}" auto="true" allowTypes="/(\.|\/)(pdf|gif|jpeg|png)$/" />
http://www.primefaces.org/showcase/ui/inputMask.jsf
Este componente nos permite asignar un patrón a un inputText de manera que los datos que introduzcamos se ajusten al patrón especificado.
Para completar la funcionalidad podemos añadir un validador de patrones para lanzar los posibles errores que pudiera ocasionar la inserción de los datos. La propiedad pattern nos permite indicar el patrón que tendrá el valor a introducir. Para ver más ejemplos de patrones, visitad el enlace del componente.
El código de ejemplo es el siguiente:
<div style="float: left;"> <p:outputLabel for="mask" value="Fecha manual " style="margin-right:10px;" styleClass="nombreLabel" /> <p:inputMask id="mask" value="#{manejadorComponentesInput.fecha}" mask="99/99/9999" required="true" validator="#{manejadorComponentesInput.validaFecha}" validatorMessage="#{messages['form.fecha.invalida']}"> <!-- Agregamos un validador para el patron de fecha --> <f:validateRegex pattern="[0-9]{2}/[0-1][0-9]/[0-9]{4}" for="mask" /> <!-- Rerenderizamos los mensajes de error cuando el componente pierde el foco --> <p:ajax update="iconoErrorFecha" event="blur" /> </p:inputMask> </div> <div style="float: left"> <!-- Muestra un icono de error junto al inputText --> <p:message for="mask" id="iconoErrorFecha" display="icon" showDetail="false" /> </div>
http://www.primefaces.org/showcase/ui/picklist.jsf
Este componente nos permite seleccionar un conjunto de elementos en una lista. Primefaces incorpora una clase Java DualListModel que permite especificar la lista origen y la lista destino. http://www.primefaces.org/docs/api/3.4/org/primefaces/model/DualListModel.html
Nota: Para ocultar los botontes añadir o eliminar todos hay que sobreescribir el css del botón:
.ui-picklist-button-add-all { visibility: hidden !important; } .ui-picklist-button-remove-all { visibility: hidden !important; }
El código del componente
<p:pickList id="provinciasPic" value="#{manejadorComponentesInput.provinciasPick}" var="provincia" itemValue="#{provincia}" itemLabel="#{provincia.proNombre}" converter="conversorProvincias"> <f:facet name="sourceCaption">Disponibles</f:facet> <f:facet name="targetCaption">Seleccionadas</f:facet> <p:ajax event="transfer" listener="#{manejadorComponentesInput.onTransfer}" /> </p:pickList>
Este componente nos provee de una agenda al estilo Outlook para anotar diferentes eventos. Permite crearlos, modificarlos y moverlos. Este componente debe estar controlado por un bean de tipo sesión.
Las propiedades más importantes son:
El componente tiene una serie de eventos que nos sirven para interactuar con él. Los más destacados son:
El código fuente es el siguiente:
<p:schedule id="agenda" value="#{agendaBean.agenda}" widgetVar="agendaWV" timeZone="GMT+1" allDaySlot="false" > <p:ajax event="dateSelect" listener="#{agendaBean.onDateSelect}" update="eventDetails" oncomplete="dialogoEvento.show()" /> <p:ajax event="eventSelect" listener="#{agendaBean.onEventSelect}" update="eventDetails" oncomplete="dialogoEvento.show()" /> <p:ajax event="eventMove" listener="#{agendaBean.onEventMove}" update=":messages" /> <p:ajax event="eventResize" listener="#{agendaBean.onEventResize}" update=":messages" /> </p:schedule> <p:dialog widgetVar="dialogoEvento" header="Event Details"showEffect="clip" hideEffect="clip"> <h:panelGrid id="eventDetails" columns="2"> <h:outputLabel for="title" value="#{messages['agenda.evento.nombre']}" /> <p:inputText id="title" value="#{agendaBean.eventoSeleccionado.title}" required="true" /> <h:outputLabel for="from" value="#{messages['agenda.evento.desde']}" /> <p:inputMask id="from" value="#{agendaBean.eventoSeleccionado.startDate}" mask="99/99/9999"> <f:convertDateTime pattern="dd/MM/yyyy" timeZone="GMT+1" locale="es_ES" /> </p:inputMask> <h:outputLabel for="to" value="#{messages['agenda.evento.hasta']}" /> <p:inputMask id="to" value="#{agendaBean.eventoSeleccionado.endDate}" mask="99/99/9999"> <f:convertDateTime pattern="dd/MM/yyyy" timeZone="GMT+1" locale="es_ES" /> </p:inputMask> <p:commandButton id="addButton" value="Save" actionListener="#{agendaBean.guaradarEvento}" update="agenda" oncomplete="dialogoEvento.hide();" /> <p:commandButton type="reset" value="Reset" oncomplete="dialogoEvento.hide();" /> </h:panelGrid> </p:dialog>
http://www.primefaces.org/showcase/ui/selectOneMenu.jsf
Este componente, está representado por un ComboBox que nos permite seleccionar un valor. En este ejemplo hemos ilustrado este componente mostrando los resultados ordenados por grupos.
El codigo html de ejemplo es:
<p:selectOneMenu id="selectOneMenu" value="#{manejadorComponentesInput.provinciaSeleccionada}"> <f:selectItem itemLabel="Elija provincia" itemValue="" /> <f:selectItems value="#{manejadorComponentesInput.provinciasAlfabeticas}" /> </p:selectOneMenu>
Para poder agrupar los resultados deberemos crear SelectItems e introducirlos en SelectItemGroup de la siguiente manera:
//Key es el label que queremos que se muestre en el grupo SelectItemGroup grupo = new SelectItemGroup(key); //setSelectItems requiere un array, para ello transformamos a array una lista de objetos de tipo SelectItems //Para ello hacemos uso de la clase Arrays grupo.setSelectItems(Arrays.copyOf(provs.get(key).toArray(), provs.get(key).toArray().length, SelectItem[].class));
http://www.primefaces.org/showcase/ui/selectOneRadio.jsf
Este componente crea un grupo de radiobuttons que nos permite seleccionar una opción de entre las expuestas. Al mismo tiempo nos permite diseñar el layout de los botones como queramos dándonos total libertad y permitiéndonos combinarlo con otro tipo de componentes.
Para poder crear un diseño personalizado tenemos que poner la opcion layout con valor custom. Para posteriormente codificar la visualización del mismo.
En el ejemplo que mostraremos a continuación hemos diseñado un radiobutton vertical con un componente adicional en cada opción.
<p:outputPanel id="panelRadio"> <p:selectOneRadio id="radiobut" value="#{manejadorComponentesInput.radioOption}" layout="custom"> <f:selectItem itemLabel="Opcion 1" itemValue="1" /> <f:selectItem itemLabel="Opcion 2" itemValue="2" /> <f:selectItem itemLabel="Opcion 3" itemValue="3" /> <p:ajax update="panelRadio" /> </p:selectOneRadio> <h:outputText value="#{manejadorComponentesInput.radioOption}" /> <h:panelGrid columns="3" cellspacing="10px;" id="panelCustomRadio"> <p:outputLabel for="opcion1" value="Valor" styleClass="nombreLabel" style="font-size:0.7em;" /> <p:radioButton id="opcion1" for="radiobut" itemIndex="0" /> <p:spinner style="margin-left:20px;" disabled="#{manejadorComponentesInput.radioOption!=1}" /> <p:outputLabel for="opcion2" value="Valoración" styleClass="nombreLabel" style="font-size:0.7em;" /> <p:radioButton id="opcion2" for="radiobut" itemIndex="1" /> <p:rating style="margin-left:20px;" disabled="#{manejadorComponentesInput.radioOption!=2}" /> <p:outputLabel for="opcion3" value="Teléfono" styleClass="nombreLabel" style="font-size:0.7em;" /> <p:radioButton id="opcion3" for="radiobut" itemIndex="2" /> <p:inputMask id="maskTlf" style="margin-left:20px;" value="#{manejadorComponentesInput.fecha}" mask="+99(999)-999999" required="true" validator="#{manejadorComponentesInput.validaFecha}" disabled="#{manejadorComponentesInput.radioOption!=3}"> </p:inputMask> </h:panelGrid> </p:outputPanel>
Importante: Actualmente hay un bug en chrome e IE que al refrescar con ajax el componente se queda deshabilitado, funciona correctamente en Firefox.
http://www.primefaces.org/showcase/ui/treeTableHome.jsf
Este componente nos permite combinar la funcionalidad de árbol con la claridad de agrupación de una tabla. La principal diferencia con un árbol es que todos los objetos deben devolver algún valor para cada una de las columnas, por lo que hay que tener en cuenta esto a la hora de mostrar los datos.
Este componente permite que se le añada un menú contextual para realizar acciones avanzadas. Este menú se mostrará al hacer clic derecho sobre el nodo correspondiente.
El código de ejemplo es el siguiente
<p:contextMenu for="treetable"> <p:menuitem value="View" icon="ui-icon-search"/> <p:menuitem value="Delete" icon="ui-icon-close" /> </p:contextMenu> <p:treeTable id="treetable" style="width:70%;" emptyMessage="No hay datos" selectionMode="single" value="#{manejadorComponentesInput.root}" var="prov"> <f:facet name="header"> Selector de provincias </f:facet> <p:column style="width:12%"> <f:facet name="header"> Provincia </f:facet> <h:outputText value="#{prov.proNombre}" /> </p:column> <p:column style="width:12%"> <f:facet name="header"> Longitud Nombre </f:facet> <h:outputText value="#{!prov.proCodigo.equals('no') ? prov.proNombre.length() : '--'}" /> </p:column> <p:column style="width:4%"> <f:facet name="header"> Acciones </f:facet> <p:commandLink styleClass="ui-icon ui-icon-search" /> </p:column> </p:treeTable>
NOTA: No funciona bien en primefaces 3.5.8 https://code.google.com/p/primefaces/issues/detail?id=5823
http://www.primefaces.org/showcase/ui/wizard.jsf
Este componente permite de manera sencilla crear un wizard para la inserción de datos en el sistema permitiéndonos navegación hacia delante y hacia atrás. Este comportamiento no incluye un botón “Finalizar” en la última pantalla por defecto, por lo que deberemos añadirlo nosotros mismos en el último formulario, o bien hacer un estilo de botones personalizado.
Las propiedades más relevantes del componente son las siguientes:
Un ejemplo de código
<p:wizard id="wizard" flowListener="#{wizardBean.cambioMenu}" widgetVar="wiz" backLabel="#{messages['pagination.before']}" nextLabel="#{messages['pagination.next']}"> <p:tab id="personal" title="#{messages['wizard.datos.pers']}"> <p:panel> <h:panelGrid columns="3" cellspacing="20px;"> <h:panelGroup> <p:outputLabel value="#{messages['madet.nombre.head']}" styleClass="nombreLabel" for="nombre" /> <p:inputText id="nombre" style="margin-left:20px;" required="true" /> </h:panelGroup> <h:panelGroup> <p:outputLabel value="#{messages['wizard.apellid']}" styleClass="nombreLabel" for="apellidos" /> <p:inputText id="apellidos" style="margin-left:20px;" required="true" /> </h:panelGroup> <h:panelGroup> <p:outputLabel value="#{messages['wizard.nacimiento']}" styleClass="nombreLabel" for="autocompletePojo" /> <p:autoComplete style="margin-left:20px;" value="#{manejadorComponentesInput.provinciaSeleccionada}" id="autocompletePojo" completeMethod="#{manejadorComponentesInput.autocompleteProvincia}" var="provincia" itemLabel="#{provincia.proNombre}" itemValue="#{provincia}" converter="conversorProvincias" forceSelection="true" required="true" /> </h:panelGroup> </h:panelGrid> </p:panel> </p:tab> <p:tab id="estadisticos" title="#{messages['wizard.datos.est']}"> <p:panel> <h3>Panel datos estadísticos</h3> </p:panel> </p:tab> <p:tab id="asignaturas" title="#{messages['wizard.datos.asig']}"> <p:panel> <h3>Selección de asignaturas</h3> </p:panel> </p:tab> <p:tab id="pago" title="#{messages['wizard.datos.pago']}"> <p:panel> <h3>Detalles del pago</h3> </p:panel> </p:tab> <p:tab id="fin" title="#{messages['wizard.datos.fin']}"> <p:panel> <h3>Panel resumen final</h3> </p:panel> </p:tab> </p:wizard>
En el caso que queramos personalizar los botones del wizard debemos ocultar la barra de navegacion showNavBar:false e incorporar después del wizard los botones correspondientes.
Para poder navegar hacia delante o hacia atrás debemos invocar la acción javascript correspondiente del wizard, para ello lo invocaremos usando el valor de la propiedad widgetVar=“wiz” de la siguiente manera:
<p:commandButton action="#{wizardBean.accion()}" id="anterior" oncomplete="wiz.back()" value="#{messages['pagination.before']}" style="float:left;"/> <p:commandButton action="#{wizardBean.accion()}" id="siguiente" oncomplete="wiz.next()" style="float:right;" value="Siguiente"/>
http://www.primefaces.org/showcase/ui/barChart.jsf
Este componente permite dibujar diferentes diagramas para mostrar datos. En este caso hemos escogido el diagrama de barras que tiene las siguientes propiedades de interés:
El código fuente para el diagrama es el siguiente:
<p:barChart id="basico" value="#{manejadorComponentesInput.chartBarras}" legendPosition="nw" title="#{messages['diagrama.barras.titulo']}" min="0" max="210" style="height:400px" legendCols="1" shadow="true" animate="true" showDatatip="true" datatipFormat="#{manejadorComponentesInput.formatoBarra}" />
http://www.primefaces.org/showcase/ui/exporter.jsf
Este componente nos permite exportar en diferentes formatos(PDF,XML,XSL,CSV) el contenido de una tabla. Permitiéndonos exportar toda la tabla o sólo la página que estamos viendo. Importante: Para la exportación de PDF hay que asegurarse de que tenemos la librería de iText configurada en nuestro proyecto.
Las propiedades más importantes son:
En la tabla
En el componente
El código de ejemplo es el siguiente:
<h:commandLink style="float:right;"> <p:graphicImage value="/resources/img/xml.png" /> <p:dataExporter type="xml" target="listaAnuncios" fileName="listado" pageOnly="true" /> </h:commandLink> <p:dataTable id="listaAnuncios" var="anuncio" value="#{manejadorAnuncios.buscadorAnuncios}" paginator="true" rows="10" paginatorPosition="bottom" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15,30" selection="#{manejadorAnuncios.anuncioSeleccionado}" lazy="true" emptyMessage="#{messages['datatable.sinresultados']}"> <p:column sortBy="#{anuncio.id}"> <f:facet name="header"> <h:outputText value="#{messages['madet.num.head']}" /> </f:facet> <h:outputText value="#{anuncio.id}" /> </p:column> </p:dataTable>
http://www.primefaces.org/showcase/ui/datatablePagination.jsf
Tabla que muestra los elementos almacenados en el bean de respaldo en forma de listado. Primefaces nos proporciona diversos tipos de tablas, siendo la más recomendable la tabla paginada con carga difertida (LazyLoad DataTable) que es la que tratamos en este ejemplo.
Dicha tabla nos provee de filtrado, ordenamiento y paginación manteniendo en memoria sólo la información que se está mostrando. Para ello necesitamos crear una estructura de clases concreta para que el componente realice las cargas conforme vayamos paginando.
Las principales propiedades de este componente son las siguientes:
El código html de ejemplo de esta tabla es el siguiente:
<p:dataTable id="listaAnuncios" var="anuncio" value="#{manejadorAnuncios.buscadorAnuncios}" paginator="true" rows="10" paginatorPosition="bottom" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15,30" selection="#{manejadorAnuncios.anuncioSeleccionado}" lazy="true" emptyMessage="#{messages['datatable.sinresultados']}">
Hay que destacar que manejadorAnuncios.buscadorAnuncios, devuelve una clase que extiende la clase abstracta LazyDataModel. Esta clase nos provee del mecanismo de carga bajo demanda que necesitamos para nuestra tabla.
El código de esta clase para el ejemplo es el siguiente:
public class LazyAnuncioDataModel extends LazyDataModel<Anuncio> { private static final long serialVersionUID = -7128353552033320971L; private ServicioAnuncios servicioAnuncios; private String namedQuery; private String countQuery; private HashMap<String, Object> parametros; private List<Anuncio> anuncios; public LazyAnuncioDataModel(ServicioAnuncios servicioAnuncios) { this.servicioAnuncios = servicioAnuncios; anuncios = new ArrayList<Anuncio>(); } @Override public Object getRowKey(Anuncio anuncio) { return anuncio.getId(); } @Override public List<Anuncio> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) { // En este ejemplo básico no utilizamos ni el sort ni los filtros if (parametros == null) { parametros = new HashMap<String, Object>(); } //Obtenemos los anuncios que ocupen la posicion first hasta pageSize anuncios = servicioAnuncios.ejecutaNamedQuery(namedQuery, parametros, first, pageSize); //Indicamos el número total de registros de la consulta (para poder establecer el número de páginas) setRowCount(servicioAnuncios.obtenTotalRegistros( countQuery, parametros)); if (anuncios != null) { return anuncios; } else { return new ArrayList<Anuncio>(); } } @Override public Anuncio getRowData(String rowKey) { for (Anuncio an : anuncios) { if (Long.toString(an.getId()).equals(rowKey)) return an; } return null; } }
http://www.primefaces.org/showcase/ui/gmapHome.jsf
Este componente pinta un mapa de google en nuestra aplicación y nos permite interactuar con él. Así pues podemos dar de alta marcadores o consultar su información.
Para que el mapa se muestre hay que añadir el siguiente código a la cabecera de nuestra página web:
<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>
Importante: El componente aún no funciona correctamente (pendiente de estabilizar). Podemos utilizarlo para visualizar marcadores puestos y consultar la información que hayamos dispuesto para ellos, pero no nos permite insertar uno e inmediatamente consultar la información introducida. No se puede hacer un “update” del componente ya que desaparece, y el bean de respaldo sobre el que se basa ha de tener ámbito de Sesión.
El código a continuación mostrado combina la visualización de la información con la introducción de la misma, pero actualmente no funcionan ambas cosas a la vez.
<p:gmap id="map" center="38.022860,-1.174731" zoom="17" type="HYBRID" model="#{manejadorComponentesInput.modeloMapa}" widgetVar="map" style="width:600px;height:400px" onPointClick="preparaMarcador(event);" streetView="true"> <p:ajax event="pointSelect" listener="#{manejadorComponentesInput.onMapPointSelect}" oncomplete="crearMarcadorDialog.show()" /> <p:ajax event="overlaySelect" listener="#{manejadorComponentesInput.onMarkerSelect}"/> <!-- Ventana de informacion --> <p:gmapInfoWindow> <p:outputPanel style="text-align:center;display:block;margin:auto;"> <h:outputText value="-#{manejadorComponentesInput.marcadorSeleccionado.title}-" /> </p:outputPanel> </p:gmapInfoWindow> </p:gmap>
http://www.primefaces.org/showcase/ui/commandLink.jsf
Botón para realizar una acción contra el servidor. Como novedad, la acción ajax viene configurada como acción por defecto en vez de un submit normal. Este componente permite reRenderizado y procesamiento parcial de los datos. Las propiedades principales son las siguietnes:
Un ejemplo de código
<p:commandButton value="#{messages['madet.buscar']}" icon="ui-icon-search" id="btnBuscar" ajax="false" update=":formularioResultados" process="@this,panelFiltro" action="#{manejadorAnuncios.buscar()}" />
http://www.primefaces.org/showcase/ui/dialogHome.jsf
Componente para crear un modalPanel que aparezca como un popUp para que podamos realizar acciones adicionales, consultar datos, utilizar como ayuda, etc…
Dentro de sus propiedades principales podemos destacar:
<p:dialog id="panelModal" header="Crear comentario" width="500" position="top" height="350" widgetVar="panelComentario" style="position:fixed;margin-top:10%;" modal="true" closable="true" appendToBody="true" resizable="false"> <h:form id="modalPanelForm"> <h:outputText value="#{messages['det.coment.text']}" styleClass="nombreLabel" /> <p:editor id="editComentario" width="400" value="#{manejadorAnuncios.comentarioSeleccionado.texto}" /> <div style="position:absolute;bottom:10;width:95%;"> <p:commandButton id="btnCancelComent" value="#{messages['value.cancel']}" style="float:right;" icon="ui-icon-close" ajax="true" action="true" onclick="panelComentario.hide();"/> <p:commandButton value="#{messages['value.save']}" id="btnGuardarComent" icon="ui-icon-disk" ajax="true" action="#{manejadorAnuncios.guardarComentario()}" style="float:right;margin-right:15px;"/> </div> </h:form> </p:dialog> ... ... ... <!-- Llamada al panel --> <p:commandButton id="btnNuevoAnun" icon="ui-icon-document" style="float:right;margin-bottom:10px;" value="#{messages['det.coment.nuevo']}" onclick="panelComentario.show();" />
http://www.primefaces.org/showcase/ui/menubar.jsf
Este componente nos proporciona una barra de menú horizontal a la que podremos ir añadiéndole opciones. Se comporta de manera idéntica a una barra de menú de cualquier aplicación de escritorio. A la hora de construir el menú podemos diferenciar los siguientes elementos:
Un ejemplo de código es el siguiente:
<p:menubar id="menuBar"> <p:menuitem value="#{messages['value.link.home']}" icon="ui-icon-home" url="/paginas/home.xhtml" /> <p:submenu label="#{messages['value.link.comp']}" icon="ui-icon-document"> <p:menuitem value="#{messages['value.link.madet']}" url="/paginas/maestroAnuncios.xhtml" icon="ui-icon-newwin"/> </p:submenu> <f:facet name="options"> <p:commandButton value="Salir" icon="ui-icon-extlink" action="#{identity.logout()}" /> </f:facet> </p:menubar>
http://www.primefaces.org/showcase/ui/messages.jsf
Componente para mostrar los mensajes faces que produzca el sistema. Creará una barra superior que agrupará los mensajes del mismo tipo en ella. Fundeweb por defecto lo incorpora en sus templates, por lo tanto no es necesario introducirlo en las aplicaciones desarrolladas con este framework.
<p:messages id="messages" showDetail="false" closable="true"/>
http://www.primefaces.org/showcase/ui/blockUI.jsf
Permite bloquear componentes jsf cuando se está ejecutando ajax.
http://www.primefaces.org/showcase/ui/collector.jsf
Permite gestionar colecciones en cliente (crear, eliminar). Minimiza las llamadas al servidor.
http://www.primefaces.org/showcase/ui/hotkey.jsf
Liga las teclas al cliente para realizar acciones.
http://www.primefaces.org/showcase/ui/sticky.jsf
Este componente permite que un elemento de nuestra página siempre quede visible aunque esta tenga scroll vertical. Alinea el componente en el top de la pantalla y lo mantiene visible en todo momento.
Cuando introducimos el componente editor en un panel, a la hora de pintar el panel, lo hacemos normalmente por javascript, por lo tanto el editor no se encuentra preparado para la edición cuando se pinta, para ello debemos actualizar el formulario que contiene dicho editor.
<p:commandButton id="btnNuevoCom" icon="ui-icon-document" ajax="true" action="#{manejadorAnuncios.creaNuevoComentario()}" value="#{messages['det.coment.nuevo']}" oncomplete="panelComentario.show();" update=":modalPanelForm"/>
En este código se muestra cómo se pinta el panel desde un botón. En el “oncomplete” nos encargamos de pintar el panel mediante javascript, la modificación importante es update=“:modalPanelForm” ahí es donde indicamos que actualice el formulario, que en este caso contiene el editor.