One page master part in JSF / PrimeFaces

I am interested to know what good templates are for implementing single-page master-detail views in the JSF-PrimeFaces / JPA stack. It seems that most of the materials and tutorials on the Internet discuss a rather trivial one table for each presentation template.

But I am interested in such things as the presence of CUSTOMER and ORDER tables in the database and one xhtml page where you can view customers (for example, like p: datatable ) in the upper half and orders for the currently selected customer in the lower half (again like p: datatable ). I don’t understand how best to organize JSF / PrimeFaces / backing beans and facades / entities / JPA code to achieve the above in generally applicable mode with maximum code reuse. For instance.

  • Should I define one bean support for the entire xhtml view or two fallback beans, one for each view component (master / detail)?
  • Can a template be generalized to more than several detail tables (at the same level)? For instance. look like the CUSTOMER table in the upper half and as tabs in the lower half, consisting of two views for ORDER and PAYMENT (as for N-1 with the CUSTOMER table
  • whether the template can be generalized to more than one level of detail (for example, on one page, the view CUSTOMER , INVOICE and INVOICELINE .
  • As an easily proposed template may also contain modifications. For instance. Using editable data, you can change customer data and delete the order and complete both changes at one time using the commit commit button.
+4
source share
1 answer

On a recent training course, we will build the following proof. We created a single view with two tables, a wizard (department) and a table of parts (employees). The view was supported by two beans controllers that exchange cdi data. Resonance: BackgroundConcept has been deployed to a jee6 container (glassfish 3.1.1).

The idea is that whenever you click on the departments line, ajax-Listener fires a cdi event, which updates the controller parts and in turn updates the details table. This template can be expanded to several detailed tables or several levels of detail-part-part.

To edit your suggestions, I suggest opening an editor dialog, for example, adding an editor button to each row of your tables. To add new data, use add-Actions in the table footer and open the editor dialog box with the new object. On "ok" in your Dialog editor, you again fire the cdi event with a new entity to update depending on the detailed tables. To save your work, use one "commit" -Button, which saves the master-Entity. In the training, we used jpa with the corresponding specific objects, esp, using the orphanRemoval = true attribute in the @OneToMany relationship.

View (scott.xhtml):

<p:panel id="deptPanel" header="Departements"> <p:dataTable id="deptTable" var="dept" value="#{deptUiController.departements}" selectionMode="single" rowKey="#{dept.id}"> <p:ajax event="rowSelect" listener="#{deptUiController.onRowSelect}" update="@form"/> <p:column headerText="Name"> <h:outputText id="name" value="#{dept.dname}"/> </p:column> <p:column headerText="Location"> <h:outputText id="loc" value="#{dept.loc}"/> </p:column> <p:column headerText="# of Emps"> <h:outputText id="size" value="#{dept.emps.size()}"/> </p:column> </p:dataTable> </p:panel> <p:panel id="empPanel" header="Employees in departement #{deptUiController.currentDept.dname}"> <p:dataTable id="empTable" var="emp" value="#{empUiController.employees}"> <p:column headerText="Name"> <h:outputText id="name" value="#{emp.ename}"/> </p:column> <p:column headerText="Job"> <h:outputText id="job" value="#{emp.job}"/> </p:column> <p:column headerText="Hiredate"> <h:outputFormat id="hiredate" value="{0,date,dd.MM.yyyy}"> <f:param value="#{emp.hiredate}"/> </h:outputFormat> </p:column> </p:dataTable> </p:panel> 

Master controller:

 @Named @SessionScoped public class DeptUiController implements Serializable { private boolean initialized = false; @EJB private ScottCRUD crudEJB; private List<Departement> departements; private Departement currentDept; public void populateData() { if ( !initialized ) { departements = crudEJB.findAllDepartements(); currentDept = departements.isEmpty() ? null : departements.get(0); initialized = true; fireDeptChange(); } } @Inject private Event<Departement> deptChangeEvt; private void fireDeptChange() { deptChangeEvt.fire( currentDept ); } public void onRowSelect(SelectEvent event) { currentDept = (Departement) event.getObject(); fireDeptChange(); } ... getter, setter, more actions... } 

Controller part

 @Named @SessionScoped public class EmpUiController implements Serializable { private List<Employee> employees; private Employee currentEmp; private void populateData(Departement master) { if ( master==null ) { employees = Collections.emptyList(); } else { employees = master.getEmps(); } currentEmp = employees.isEmpty() ? null : employees.get(0); } public void observeDeptChanged( @Observes Departement master ) { populateData( master ); } ... getter, setter, more actions... } 
+2
source

Source: https://habr.com/ru/post/1441563/


All Articles