En algunas ocasiones necesitamos utilizar autocomplemente con selecciones mĆŗltiples que estĆ©n relacionados.
- Usaremos el compenente <p:autocomplete> de Primefaces estableciendo multiple="true"
- El autocomplete debemos usar evento <p:ajax> itemSelect se dispara al seleccionar un elemento
- TambiƩn usaremos el evento <p:ajax> itemUnselect, que se activara al remover un elemento del autocomplete.
- Usaremos una base de datos mongodb
- Implementamos ejbjmoordb
Ejemplo:
- Seleccionar mĆŗltiples facultades
- Impedir seleccionar una facultad que este en la lista previamente
- Seleccionar las carreras de las facultades seleccionadas solamente
- Si se elimina una facultad del autocomplete, eliminar automƔticamente las carreras de esa facultad que se seleccionaron en el autocomplete Carrera.
Entitys
Entity Carrera.java
public class Carrera {
@Id
private Integer idcarrera;
private String descripcion;
private String activo;
@Referenced(documment = "Facultad",
field = "idfacultad", javatype = "Integer", lazy = false,
repository = "com.avbravo.commonejb.repository.FacultadRepository")
Facultad facultad;
@Embedded
List<UserInfo> userInfo;
public Carrera() {
}
//set/get
}
Facultad.java
public class Facultad {
@Id
private Integer idfacultad;
private String descripcion;
private String activo;
@Embedded
List<UserInfo> userInfo;
public Facultad() {
}
//set/get
}
CĆ³digo .xhtml
multiple="true"
<p:ajax event="itemSelect" listener="#{solicitudController.handleSelect}"
update=":form:content" />
<p:ajax event="itemUnselect" listener="#{solicitudController.itemUnselect}"
update=":form:content"
/>
exit: Ctrl + ↩
<p:outputLabel value="#{msg['field.facultad']}" />
<p:autoComplete dropdown="false"
multiple="true"
scrollHeight="250"
size="15"
emptyMessage="#{app['info.nohayregistros']}"
value="#{solicitudController.facultadList}"
completeMethod="#{solicitudController.completeFiltradoFacultad}"
var="p"
required="true"
itemLabel="#{p.descripcion}"
itemValue="#{p}" forceSelection="true">
<f:converter binding="#{facultadConverter}"/>
<f:attribute name="field" value="descripcion"/>
<f:attribute name="fielddropdown" value="false"/>
<f:attribute name="fieldquerylenth" value="1"/>
<p:ajax event="itemSelect" listener="#{solicitudController.handleSelect}"
update=":form:content" />
<p:ajax event="itemUnselect" listener="#{solicitudController.itemUnselect}"
update=":form:content" />
<f:facet name="itemtip">
<h:panelGrid columns="1" cellpadding="5">
<h:outputText value="#{msg['field.descripcion']} #{p.descripcion}" />
</h:panelGrid>
</f:facet>
</p:autoComplete>
<p:outputLabel value="#{msg['field.carrera']}" />
<p:autoComplete dropdown="false"
id="carrera"
multiple="true"
scrollHeight="250"
size="15"
emptyMessage="#{app['info.nohayregistros']}"
value="#{solicitudController.carreraList}"
completeMethod="#{solicitudController.completeFiltradoCarrera}"
var="p"
required="true"
itemLabel="#{p.descripcion}"
itemValue="#{p}" forceSelection="true">
<f:converter binding="#{carreraConverter}"/>
<f:attribute name="field" value="descripcion"/>
<f:attribute name="fielddropdown" value="false"/>
<f:attribute name="fieldquerylenth" value="1"/>
<p:ajax event="itemSelect" listener="#{solicitudController.handleSelect}"
update=":form:content" />
<p:ajax event="itemUnselect" listener="#{solicitudController.itemUnselect}"
update=":form:content" />
<f:facet name="itemtip">
<h:panelGrid columns="1" cellpadding="5">
<h:outputText value="#{msg['field.descripcion']} #{p.descripcion}" />
</h:panelGrid>
</f:facet>
avbravo
</p:autoComplete>
Controller
@Named
@ViewScoped
public class SolicitudController implements Serializable, IController {
//Para los autocomplete
List<Facultad> suggestionsFacultad = new ArrayList<>();
List<Carrera> suggestionsCarrera = new ArrayList<>();
//Repository
@Inject
FacultadRepository facultadRepository;
@Inject
CarreraRepository carreraRepository;
public List<Facultad> completeFiltradoFacultad(String query) {
suggestionsFacultad = new ArrayList<>();
List<Facultad> temp = new ArrayList<>();
try {
Boolean found = false;
query = query.trim();
if (query.length() < 1) {
return suggestionsFacultad;
}
String field = (String) UIComponent.getCurrentComponent(FacesContext.getCurrentInstance()).getAttributes().get("field");
temp = facultadRepository.findRegexInText(field, query, true, new Document(field, 1));
if (facultadList == null || facultadList.isEmpty()) {
if (!temp.isEmpty()) {
suggestionsFacultad = temp;
}
} else {
if (!temp.isEmpty()) {
temp.stream().forEach(f -> addFacultad(f));
}
}
} catch (Exception e) {
JsfUtil.errorMessage("completeFiltradoFacultad() " + e.getLocalizedMessage());
}
return suggestionsFacultad;
}
private Boolean addFacultad(Facultad facultad) {
try {
if (!foundFacultad(facultad.getIdfacultad())) {
suggestionsFacultad.add(facultad);
}
} catch (Exception e) {
JsfUtil.errorMessage("addFacultad()" + e.getLocalizedMessage());
}
return false;
}
private Boolean foundFacultad(Integer idfacultad) {
Boolean _found = true;
try {
Facultad facultad = facultadList.stream()
.filter(x -> x.getIdfacultad() == idfacultad)
.findAny() // If 'findAny' then return found
.orElse(null);
if (facultad == null) {
_found = false;
}
} catch (Exception e) {
JsfUtil.errorMessage("foundFacultad() " + e.getLocalizedMessage());
}
return _found;
}
//Cuando se elimina un elmento del autocomplete
public void itemUnselect(UnselectEvent event) {
try {
if (carreraList != null && !carreraList.isEmpty()) {
carreraList = removeByNotFoundFacultad(carreraList);
}
} catch (Exception ex) {
JsfUtil.errorMessage("itemUnselec() " + ex.getLocalizedMessage());
}
}
private List<Carrera> removeByNotFoundFacultad(List<Carrera> carreraList) {
List<Carrera> list = new ArrayList<>();
try {
//1.recorre las facultades
//2.filtra las carreras de esa facultad
//3.crea una lista
//4. luego va agregando esa lista a la otra por cada facultad
if (facultadList == null || facultadList.isEmpty()) {
return list;
}
facultadList.forEach((f) -> {
List<Carrera> temp = carreraList.stream()
.parallel()
.filter(p -> p.getFacultad().getIdfacultad().equals(f.getIdfacultad()))
.collect(Collectors.toCollection(ArrayList::new));
temp.forEach((c) -> {
list.add(c);
});
});
} catch (Exception e) {
JsfUtil.errorMessage("removeByNotFoundFacultad() " + e.getLocalizedMessage());
}
return list;
}
Para las carreras creamos los mƩtodos similares.
Nota:
Si no colocamos el itemUnSelect, no realiza los filtros respectivos al quitar un objeto y tratar de agregarlo nuevamente.
Comments