Personalizar un componente usando <p:autocomplete> con genricos y ejbmoordb
Cuando desarrollamos aplicaciones Java Enterprise Edition / Jakarta, podemos usar una combinación de frameworks si utilizamos Java Server Faces, (podemos mezclar Primefaces + Bootfaces +Omnifaces), podemos crear componentes que nos faciliten el trabajo con la aplicación.
Por ejemplo deseamos un <p:autocomplete> que personalizaremos e integremos en múltiples formularios sin necesidad de reescribir el código, que realice búsquedas por cualquier atributo de una colección en mongodb mediante ejbmoordb.
en la carpeta
/resources/extensions creamos el componente autocompleterol
Creamos una clase RolServices donde definimos el método complete que invocara = repository.complete(query);
Cuando desarrollamos aplicaciones Java Enterprise Edition / Jakarta, podemos usar una combinación de frameworks si utilizamos Java Server Faces, (podemos mezclar Primefaces + Bootfaces +Omnifaces), podemos crear componentes que nos faciliten el trabajo con la aplicación.
Por ejemplo deseamos un <p:autocomplete> que personalizaremos e integremos en múltiples formularios sin necesidad de reescribir el código, que realice búsquedas por cualquier atributo de una colección en mongodb mediante ejbmoordb.
en la carpeta
/resources/extensions creamos el componente autocompleterol
código del componente
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<composite:interface >
<composite:attribute name="value" />
<composite:attribute name="disabled" default="false" />
<composite:attribute name="multiple" default="false" />
<composite:attribute name="dropdown" default="false"/>
<composite:attribute name="minQueryLength" default="1"/>
<composite:attribute name="itemLabel" />
<composite:attribute name="update" />
<composite:attribute name="rendered"/>
<composite:attribute name="field"/>
<composite:attribute name="fromstart" default="true"/>
<composite:attribute name="required" default="false" />
<composite:attribute name="size" default="25"/>
<composite:attribute name="listener"
method-signature="void handleSelect(org.primefaces.event.SelectEvent)" />
</composite:interface>
<composite:implementation>
<p:autoComplete dropdown="#{cc.attrs.dropdown}"
disabled="#{cc.attrs.disabled}"
scrollHeight="250"
size="#{cc.attrs.size}"
multiple="#{cc.attrs.multiple}"
emptyMessage="#{app['info.nohayregistros']}"
value="#{cc.attrs.value}"
completeMethod="#{rolController.rolServices.complete}"
var="p"
required="#{cc.attrs.required}"
itemLabel="#{cc.attrs.itemLabel}"
itemValue="#{p}" forceSelection="true">
<f:converter binding="#{rolConverter}"/>
<f:attribute name="field" value="#{cc.attrs.field}"/>
<f:attribute name="fromstart" value="#{cc.attrs.fromstart}"/>
<f:attribute name="fielddropdown" value="#{cc.attrs.dropdown}"/>
<f:attribute name="fieldminquerylength" value="#{cc.attrs.minQueryLength}"/>
<p:ajax event="itemSelect" listener="#{cc.attrs.listener}"
update="#{cc.attrs.update}" />
<f:facet name="itemtip">
<h:panelGrid columns="1" cellpadding="5">
<h:outputText value="#{msg['field.idrol']} #{p.idrol}" />
<h:outputText value="#{msg['field.rol']} #{p.rol}" />
</h:panelGrid>
</f:facet>
</p:autoComplete>
</composite:implementation>
</html>
ejbjmoordb
En ejbmoordb se agrego el método de manera que permite procesar cualquier clase que le indiquemos, solo lo invocas con repository.complete(query);
public List<T> complete(String query) {
Document sortQuery = new Document();
list = new ArrayList<>();
try {
query = query.trim();
String field = (String) UIComponent.getCurrentComponent(FacesContext.getCurrentInstance()).getAttributes().get("field");
String fromstart = (String) UIComponent.getCurrentComponent(FacesContext.getCurrentInstance()).getAttributes().get("fromstart");
String fielddropdown = (String) UIComponent.getCurrentComponent(FacesContext.getCurrentInstance()).getAttributes().get("fielddropdown");
String fieldminquerylength = (String) UIComponent.getCurrentComponent(FacesContext.getCurrentInstance()).getAttributes().get("fieldminquerylength");
if (query.length() < Integer.parseInt(fieldminquerylength)) {
return list;
}
if (fielddropdown.equals("false")) {
if (fromstart.equals("true")) {
list = findRegex(field, query, true, new Document(field, 1));
} else {
list = findRegexInText(field, query, true, new Document(field, 1));
}
} else {
list = findRegexInText(field, query, true, new Document(field, 1));
}
} catch (Exception e) {
Logger.getLogger(Repository.class.getName()).log(Level.SEVERE, null, e);
exception = new Exception("complete()", e);
}
return list;
}// </editor-fold>
De esta manera cuando trabajemos en el proyecto
Creamos una clase RolServices donde definimos el método complete que invocara = repository.complete(query);
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.avbravo.storeejb.services;
import com.avbravo.storeejb.repository.RolRepository;
import com.avbravo.avbravoutils.JsfUtil;
import com.avbravo.storeejb.entity.*;
import com.avbravo.storeejb.repository.UsuarioRepository;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javax.ejb.Stateless;
import javax.inject.Inject;
import org.bson.Document;
/**
*
* @authoravbravo
*/
@Stateless
public class RolServices {
@Inject
RolRepository repository;
@Inject
UsuarioRepository usuarioRepository;
List<Rol> rolList = new ArrayList<>();
// <editor-fold defaultstate="collapsed" desc="complete">
public List<Rol> complete(String query) {
List<Rol> suggestions = new ArrayList<>();
try {
suggestions = repository.complete(query);
} catch (Exception e) {
JsfUtil.errorMessage("complete() " + e.getLocalizedMessage());
}
return suggestions;
}// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="getRolList()">
public List<Rol> getRolList() {
try {
rolList = repository.findAll(new Document("rol", 1));
} catch (Exception e) {
JsfUtil.errorMessage("getRolList() " + e.getLocalizedMessage());
}
return rolList;
}// </editor-fold>
public void setRolList(List<Rol> rolList) {
this.rolList = rolList;
}
// <editor-fold defaultstate="collapsed" desc="isDeleted(Rol rol)">
public Boolean isDeleted(Rol rol) {
Boolean found = false;
try {
Document doc = new Document("rol.idrol", rol.getIdrol());
Integer count = usuarioRepository.count(doc);
if (count > 0) {
return false;
}
} catch (Exception e) {
JsfUtil.errorMessage("isDeleted() " + e.getLocalizedMessage());
}
return true;
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="findById(String id)">
public Rol findById(String id){
Rol rol = new Rol();
try {
rol.setIdrol(id);
Optional<Rol> optional = repository.findById(rol);
if (optional.isPresent()) {
return optional.get();
}
} catch (Exception e) {
JsfUtil.errorMessage("findById() " + e.getLocalizedMessage());
}
return rol;
}
// </editor-fold>
}
Para usarlo en cualquier formulario
<p:outputLabel value="#{msg['field.rol']}" />
<e:autocompleterol listener="#{usuarioController.handleSelect}"
value="#{usuarioController.rolList}"
itemLabel="#{p.rol}"
dropdown="true"
multiple="true"
required="true"
minQueryLength="0"
field="idrol"
/>
Comments