Board index JavaServer Faces General LazyDataModel and p:dialog Questions

LazyDataModel and p:dialog Questions

Components, Ajax Framework, Utilities and More.


Posts: 34
A few questions regarding Primefaces 2.0.2 datable, JSF 2, NetBeans IDE 6.9:

I am trying to create a quality improvement program using a MySQL database of my patients and their surgical procedures and subsequent outcomes. I can create a nice datatable using Primefaces with the lazyDataModel. My first problem is that I cannot use a computed number for the total number of rows.

public class PatientsController {

    private Patients selected;
    @EJB
    private PatientsFacade ejbFacade;
    private int selectedItemIndex;
    private LazyDataModel<Patients> lazyModel;
    private Patients item;
    private List<Patients> itemList;

    public PatientsController() {

        lazyModel = new LazyDataModel<Patients>(10000) {

            @Override
            public List<Patients> fetchLazyData(int first, int pageSize) {
                System.out.println("**** Loading the lazy data **** "
                        + first + "  " + pageSize);
                return ejbFacade.findRange(first, pageSize);
            }
        };
    }

getters and setters . . . . .

The above works. However, I end of with many table views w/o data as I only have approximately 8400 patients at this time. There is a method in PatientsFacade, named count() that returns an integer representing the total number of patients. I have tried numerous ways to get this value to replace the 10000, but always get a can't instantiate the PatientsController class. What suggestions might be out there? My JSF code is as follows:

<ui:composition template="/template.xhtml">
        <ui:define name="title">
            <h:outputText value="#{bundle.ListPatientsTitle}"></h:outputText>
        </ui:define>
        <ui:define name="body">
            <h:form styleClass="jsfcrud_list_form">
                <br />
                <h:commandLink value="#{bundle.ListPatientsIndexLink}" action="/index" immediate="true" />
                <br />
                <h:panelGroup id="messagePanel" layout="block">
                    <h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>
                </h:panelGroup>
                <h:outputText value="rendered text" rendered="#{patientsController.lazyModel.rowCount > 0}" />
                <h:panelGroup rendered="true">
                    <p:dataTable id="ptTable" var="pt" value="#{patientsController.lazyModel}" paginator="true"
                                 dynamic="true" lazy="true" rows="20" rowsPerPageTemplate="20, 50, 100"
                                 selectionMode="single" selection="#{patientsController.selected}"
                                 update="display" onselectComplete="ptDialog.show()"  >
                        <p:column sortBy="#{pt.patientFileID}" filterBy="#{pt.patientFileID}">
                            <f:facet name="header">
                                <h:outputText value="Patient File ID" />
                            </f:facet>
                            <h:outputText value="#{pt.patientFileID}" />
                        </p:column>
Plus many other columns that display correctly...

As you will notice, I have filterable and sortable columns, but these don't work currently.

I also have set up a p:dialog so that when I select a patient, it will show me their brief demographics (Name, DOB, DOD) and a datatable listing their surgeries. Problem: I can select patient A and see patient A's surgeries. When I select Patient B (on same or different page of data), I still see Patient's A surgeries, even though I'm seeing patient B's demographics.
                    <p:dialog header="Patient Detail" widgetVar="ptDialog"
                              modal="true" fixedCenter="true" draggable="false" width="550px">

                        <h:panelGrid id="display" columns="2">
                            <h:outputText value="Patient File ID:" />
                            <h:outputText value="#{patientsController.selected.patientFileID}" style="font-weight:bold"/>

                            <h:outputText value="Full Name:" />
                            <h:outputText value="#{patientsController.selected.fullname}" style="font-weight:bold"/>

                            <h:outputText value="DOB:" />
                            <h:outputText value="#{patientsController.selected.dob}" style="font-weight:bold" >
                                <f:convertDateTime dateStyle="default" />
                            </h:outputText>

                            <h:outputText value="DOD:" />
                            <h:outputText value="#{patientsController.selected.dod}" style="font-weight:bold"
                                          rendered="#{patientsController.selected.dod > patientsController.selected.dob}">
                                <f:convertDateTime dateStyle="default"/>
                            </h:outputText>

                        </h:panelGrid>
                        <h:panelGrid id="surgDisplay" columns="2" rendered="true">
                            <p:dataTable id="surgTable" var="surg" value="#{patientsController.selected.surgeryList}"
                                         dynamic="true" lazy="true" rows="5">
                                <p:column sortBy="#{surg.invoiceCPTStartSerDate}">
                                    <f:facet name="header">
                                        <h:outputText value="Surgery Date"/>
                                    </f:facet>
                                    <h:outputText value="#{surg.invoiceCPTStartSerDate}" >
                                        <f:convertDateTime dateStyle="default"/>
                                    </h:outputText>
                                </p:column>
                                <p:column >
                                    <f:facet name="header">
                                        <h:outputText value="POS"/>
                                    </f:facet>
                                    <h:outputText value="#{surg.pos}"/>
                                </p:column>
                            </p:dataTable>
                        </h:panelGrid>

                       

                    </p:dialog>


Any ideas or suggestions would be greatly appreciated. I'm trying to learn web programming and fill a need in my practice...

Thanks in advance.
PF 3.5
NetBeans 7.2.1
GF 3.1.2
Mojarra 2.1.17


Posts: 768
Hi,

The dependency injection of the EJB happens after the constructor runs, but before the @PostConstruct method is called, if there is such a method. The EJB therefore can't be used in the constructor. You can initialize lazyModel the way you want to initialize it in a @PostConstruct method.

I can't figure out why sorting and filtering are not working. Perhaps someone else will spot the problem.

The update attribute for dataTable only specifies that component "display" should be updated. However, you want to update both component "display" and component "surgDisplay". Changing to the update attribute to update="display surgDisplay" should solve the problem.


Posts: 15107
Location: Cybertron

LazyDataModel does not support filtering and sorting yet.
PrimeFaces Lead


Posts: 34
Thanks for above comments. I added the @PostContruct() to the code and used an integer numPatientRecords to hold the value. When I run the app, I only get one page of data on my List.xhtml page. The Glassfish output is provided below:

    private List<Patients> itemList;
    private int numPatientRecords;

    public PatientsController() {

        lazyModel = new LazyDataModel<Patients>(numPatientRecords) {

            @Override
            public List<Patients> fetchLazyData(int first, int pageSize) {
                System.out.println("**** Loading the lazy data **** "
                        + first + "  " + pageSize + "  " + numPatientRecords);
                return ejbFacade.findRange(first, pageSize);
            }
        };
    }

    @PostConstruct()
    public void loadDefaults() {
        System.out.println ("@PostConstruct, set numpatientrecords");
        numPatientRecords = ejbFacade.count();
        System.out.println("NumPatientRecords = " + numPatientRecords);
    }


INFO: WebApplication5 was successfully deployed in 12,578 milliseconds.
INFO: Portable JNDI names for EJB PatientsFacade : [java:global/WebApplication5/PatientsFacade!Facades.PatientsFacade, java:global/WebApplication5/PatientsFacade]
INFO: Portable JNDI names for EJB SurgeryFacade : [java:global/WebApplication5/SurgeryFacade, java:global/WebApplication5/SurgeryFacade!Facades.SurgeryFacade]
INFO: Initializing Mojarra 2.0.2 (FCS b10) for context '/WebApplication5'
INFO: Monitoring jndi:/server/WebApplication5/WEB-INF/faces-config.xml for modifications
INFO: Loading application WebApplication5 at /WebApplication5
INFO: WebApplication5 was successfully deployed in 3,125 milliseconds.
INFO: @PostConstruct, set numpatientrecords
INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
INFO: EclipseLink, version: Eclipse Persistence Services - 2.0.1.v20100213-r6600
INFO: file:/C:/wamp/www/WebApplication5/build/web/WEB-INF/classes/_WebApplication5PU login successful
INFO: NumPatientRecords = 8394
WARNING: JSF1063: WARNING! Setting non-serializable attribute value into HttpSession (key: patientsController, value class: JSFControllers.PatientsController).
INFO: **** Loading the lazy data **** 0  20  8394


Changing the update="display surgData" did not 'refresh' the surgData table when selecting a new patient. I also tried update='ptDialog.display ptDialog.surgData" without success.

Thanks in advance.
PF 3.5
NetBeans 7.2.1
GF 3.1.2
Mojarra 2.1.17


Posts: 768
Remove the constructor completely and initialize lazyModel in the @PostConstruct method.

    private List<Patients> itemList;
    private int numPatientRecords;

    // public PatientsController() {
    // }

    @PostConstruct()
    public void loadDefaults() {
        System.out.println ("@PostConstruct, set numpatientrecords");
        numPatientRecords = ejbFacade.count();
        System.out.println("NumPatientRecords = " + numPatientRecords);

        lazyModel = new LazyDataModel<Patients>(numPatientRecords) {

            @Override
            public List<Patients> fetchLazyData(int first, int pageSize) {
                System.out.println("**** Loading the lazy data **** "
                        + first + "  " + pageSize + "  " + numPatientRecords);
                return ejbFacade.findRange(first, pageSize);
            }
        };
    }


The dialog has two panelGrids, one called "display", and one called "surgDisplay" (not "surgData"). There doesn't appear to be a component called "surgData" that can be updated.


Posts: 34
BINGO !
Moving the lazy data model to the @PostContruct() worked !

Sorry for my typos regarding the surgData vs surgDisplay -- I got that to work also when I used the right labels.

Again, Thanks to all who provided support/answers.
PF 3.5
NetBeans 7.2.1
GF 3.1.2
Mojarra 2.1.17


Posts: 15107
Location: Cybertron

Thanks for confirming the solution.
PrimeFaces Lead


Return to General