AF: PanelAccordion ParcialTrigger en AF: SelectOneChoice Valuechangelistener
-
27-10-2019 - |
Pregunta
Soy nuevo en las caras de ADF y me enfrento a ParcialCigger A AF: PanelAccordion sobre el cambio de valor de una AF: SELECTOnECHOICE. El AF: PanelAccordion contiene múltiples AF: ShowDetailheader dentro de su AF: ShowDetailItem. Todos los AF: ShowDetailItem y su AF: ShowDetailheader se generan dinámicamente. El Bean College está en la vista del alcance y su código se da a continuación:
public class College {
private List<Department> departments;
private List<SelectItem> departmentDropDownMenu;
private String selectedDepartment;
public College() {
this.departments = new ArrayList<Department>(0);
Employee employee1 = new Employee("Employee 1", "Information");
Employee employee2 = new Employee("Employee 2", "Information");
Employee employee3 = new Employee("Employee 3", "Information");
Employee employee4 = new Employee("Employee 4", "Information");
Employee employee5 = new Employee("Employee 5", "Information");
List<Employee> employees1 = new ArrayList<Employee>(0);
employees1.add(employee1);
List<Employee> employees2 = new ArrayList<Employee>(0);
employees2.add(employee2);
List<Employee> employees3 = new ArrayList<Employee>(0);
employees3.add(employee3);
List<Employee> employees4 = new ArrayList<Employee>(0);
employees4.add(employee4);
employees4.add(employee5);
Department department1 = new Department("Department 1", employees1);
Department department2 = new Department("Department 2", employees2);
Department department3 = new Department("Department 3", employees3);
Department department4 = new Department("Department 4", employees4);
this.departments.add(department1);
this.departments.add(department2);
this.departments.add(department3);
this.departments.add(department4);
List<SelectItem> departmentDropDownMenu = new ArrayList<SelectItem>(0);
departmentDropDownMenu.add(new SelectItem("Department 1"));
departmentDropDownMenu.add(new SelectItem("Department 2"));
departmentDropDownMenu.add(new SelectItem("Department 3"));
departmentDropDownMenu.add(new SelectItem("Department 4"));
this.setDepartmentDropDownMenu(departmentDropDownMenu);
this.setSelectedDepartment("Department 1");
}
public void departmentDropDrownValueChangeListener(ValueChangeEvent event) {
String oldValue = event.getOldValue().toString();
String newValue = event.getNewValue().toString();
if(oldValue.equalsIgnoreCase(newValue)) {
return;
}
List<Department> departmentUpdated = new ArrayList<Department>(0);
for (Department department : departments) {
if(department.getDepartmentName().equals(newValue)) {
departmentUpdated.add(department);
break;
}
}
for (Department department : departments) {
if(!department.getDepartmentName().equals(newValue)) {
departmentUpdated.add(department);
}
}
this.setDepartments(departmentUpdated);
}
public void setDepartments(List<Department> departments) {
this.departments = departments;
}
public List<Department> getDepartments() {
return departments;
}
public void setDepartmentDropDownMenu(List<SelectItem> departmentDropDownMenu) {
this.departmentDropDownMenu = departmentDropDownMenu;
}
public List<SelectItem> getDepartmentDropDownMenu() {
return departmentDropDownMenu;
}
public void setSelectedDepartment(String selectedDepartment) {
this.selectedDepartment = selectedDepartment;
}
public String getSelectedDepartment() {
return selectedDepartment;
}
}
Las clases de Departamento y Empleados son simples POJO. La clase de departamento contiene solo dos campos: 1. Nombre de departamento de cadena y 2. Listar a los empleados con sus accesorios. También la clase de empleados contiene dos campos: 1. Nombre de cadena y 2. Información de cadena.
El código JSPX de la página se proporciona a continuación:
<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<jsp:directive.page contentType="text/html;charset=UTF-8"/>
<f:view>
<af:document title="Page.jspx" id="d1">
<af:form id="f1">
<af:panelStretchLayout id="psl1">
<f:facet name="center">
<af:panelGroupLayout id="pgl2">
<af:selectOneChoice label="Department" value="#{college.selectedDepartment}" id="soc1"
unselectedLabel="" autoSubmit="true" immediate="true"
valueChangeListener="#{college.departmentDropDrownValueChangeListener}">
<f:selectItems value="#{college.departmentDropDownMenu}" id="si1"/>
</af:selectOneChoice>
<af:panelAccordion id="pa1" discloseNone="true" partialTriggers="soc1" discloseMany="true">
<af:forEach items="#{college.departments}" var="department">
<af:showDetailItem text="#{department.departmentName}" id="sdi1">
<af:forEach items="#{department.employees}" var="employee">
<af:showDetailHeader text="#{employee.name}" disclosed="false" id="sdh1">
<af:outputText value="#{employee.info}" id="ot1"/>
</af:showDetailHeader>
</af:forEach>
</af:showDetailItem>
</af:forEach>
</af:panelAccordion>
</af:panelGroupLayout>
</f:facet>
</af:panelStretchLayout>
</af:form>
</af:document>
</f:view>
</jsp:root>
Lo que quiero hacer es reorganizar el AF: ShowDetailItem dependiendo del valor seleccionado del AF: SelectOneCoice.
Estoy mostrando el problema en las imágenes:
Como puede ver, la primera imagen es la condición normal después de la carga de la página. El Departamento 1 tiene solo un empleado, a saber, el empleado 1 y el Departamento 4 tiene dos empleados empleados 1, empleado 2. Después de seleccionar el departamento 4 del menú desplegable, el departamento 3 entra en el último puesto, pero allí en el departamento 3 el panel tiene dos AF: showDetailItem en el Imagen pero originalmente tiene solo un empleado. También esa AF adicional: ShowDetailItem no se puede hacer clic.
Si alguien, por favor, haga alguna sugerencia, me será muy útil.
Gracias.
Solución
El problema está en usar <af:forEach/>
. De acuerdo con la documentación de etiqueta:
Objetos en los elementos de un
<af:forEach>
La etiqueta no se debe agregar, eliminar o reordenar una vez que se haya creado el árbol de componentes
Puedes usar un <af:iterator/>
etiqueta en su lugar. JDEV se quejará de que no es un hijo válido de <af:panelAccordion/>
, pero funciona.
Este diseño de página parece funcionar. Nota, moví el <af:selectOneChoice/>
a la faceta superior y abandonó la <af:panelGroupLayout/>
Para forzar el acordeón a estirarse y hacer que todos los niños sean visibles.
<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<jsp:directive.page contentType="text/html;charset=UTF-8"/>
<f:view>
<af:document title="Page.jspx" id="d1">
<af:form id="f1">
<af:panelStretchLayout id="psl1">
<f:facet name="center">
<af:panelAccordion id="pa1" discloseNone="false" partialTriggers="soc1" discloseMany="true" reorder="enable">
<af:iterator value="#{college.departments}" var="department">
<af:showDetailItem text="#{department.departmentName}" id="sdi1">
<af:iterator value="#{department.employees}" var="employee">
<af:showDetailHeader text="#{employee.name}" disclosed="false" id="sdh1">
<af:outputText value="#{employee.info}" id="ot1"/>
</af:showDetailHeader>
</af:iterator>
</af:showDetailItem>
</af:iterator>
</af:panelAccordion>
</f:facet>
<f:facet name="top">
<af:selectOneChoice label="Department" value="#{college.selectedDepartment}" id="soc1" unselectedLabel="" autoSubmit="true"
valueChangeListener="#{college.departmentDropDrownValueChangeListener}" immediate="true">
<f:selectItems value="#{college.departmentDropDownMenu}" id="si1"/>
</af:selectOneChoice>
</f:facet>
</af:panelStretchLayout>
</af:form>
</af:document>
</f:view>
</jsp:root>
Espero que esto ayude. Bienvenido la confusión que es ADF. :)