Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

On Primefaces datatable lazy loading complete update backing bean

Tags:

primefaces

I want to update backing bean after the primefaces datatable lazy loading is complete. I see that the API has a onSuccess & onComplete method for calling clientside code. But I would like to update backing bean based on the default selection. I have registered the "page" event with my datatable

<p:ajax event="page" update="" onstart="PF('loadingDialog').show()" onsuccess="PF('loadingDialog').hide()" listener=""/>

I could have used the listener but the problem is listener is invoked even before the server side loading method is complete.

like image 632
vinay Avatar asked Oct 23 '14 16:10

vinay


2 Answers

RemoteCommand provides a simple way to execute backing bean methods with javascript.

The example is shown below.

xhtml

<h:form id="form">
    <p:remoteCommand name="rc" update="msgs" 
                     actionListener="#{remoteCommandView.execute('Wittakarn')}" />
    <p:growl id="msgs" showDetail="true" />
    <p:dataTable var="car" value="#{dtLazyView.lazyModel}" 
                 paginator="true" rows="10"
                 paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} 
                 {PreviousPageLink} 
                 {CurrentPageReport} 
                 {NextPageLink} 
                 {LastPageLink}"
                 rowsPerPageTemplate="5,10,15" 
                 selectionMode="single" 
                 selection="#{dtLazyView.selectedCar}" 
                 id="carTable" 
                 lazy="true">
        <p:ajax event="rowSelect" 
                listener="#{dtLazyView.onRowSelect}" 
                update=":form:carDetail" 
                oncomplete="PF('carDialog').show()" />
        <p:ajax event="page" 
                update=":form:carDetail" 
                oncomplete="rc()" />
        <p:column headerText="Id" 
                  sortBy="#{car.id}" 
                  filterBy="#{car.id}">
            <h:outputText value="#{car.id}" />
        </p:column>
        <p:column headerText="Year" 
                  sortBy="#{car.year}"
                  filterBy="#{car.year}">
            <h:outputText value="#{car.year}" />
        </p:column>
        <p:column headerText="Brand" 
                  sortBy="#{car.brand}" 
                  filterBy="#{car.brand}">
            <h:outputText value="#{car.brand}" />
        </p:column>
        <p:column headerText="Color" 
                  sortBy="#{car.color}" 
                  filterBy="#{car.color}">
            <h:outputText value="#{car.color}" />
        </p:column>
    </p:dataTable>

    <p:dialog header="Car Detail" 
              widgetVar="carDialog" 
              modal="true" showEffect="fade" 
              hideEffect="fade" 
              resizable="false">
        <p:outputPanel id="carDetail" 
                       style="text-align:center;">
            <p:panelGrid  columns="2" 
                          rendered="#{not empty dtLazyView.selectedCar}" 
                          columnClasses="label,value">
                <f:facet name="header">
                    <p:graphicImage 
                        name="demo/images/car/#{dtLazyView.selectedCar.brand}-big.gif"/> 
                </f:facet>

                <h:outputText value="Id:" />
                <h:outputText value="#{dtLazyView.selectedCar.id}" />

                <h:outputText value="Year" />
                <h:outputText value="#{dtLazyView.selectedCar.year}" />

                <h:outputText value="Color:" />
                <h:outputText value="#{dtLazyView.selectedCar.color}" 
                              style="color:#{dtLazyView.selectedCar.color}"/>

                <h:outputText value="Price:" />
                <h:outputText value="#{dtLazyView.selectedCar.price}">
                    <f:convertNumber type="currency" currencySymbol="$" />
                </h:outputText>
            </p:panelGrid>
        </p:outputPanel>
    </p:dialog>
</h:form>

managedbean

@ManagedBean
public class RemoteCommandView {

    public void execute() {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Executed", "Using RemoteCommand."));
    }

    public void execute(String detail) {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, detail, "Using RemoteCommand."));
    }
}

@ManagedBean(name="dtLazyView")
@ViewScoped
public class LazyView implements Serializable {

    private LazyDataModel<Car> lazyModel;

    private Car selectedCar;

    @ManagedProperty("#{carService}")
    private CarService service;

    @PostConstruct
    public void init() {
        lazyModel = new LazyCarDataModel(service.createCars(200));
    }

    public LazyDataModel<Car> getLazyModel() {
        return lazyModel;
    }

    public Car getSelectedCar() {
        return selectedCar;
    }

    public void setSelectedCar(Car selectedCar) {
        this.selectedCar = selectedCar;
    }

    public void setService(CarService service) {
        this.service = service;
    }

    public void onRowSelect(SelectEvent event) {
        FacesMessage msg = new FacesMessage("Car Selected", ((Car) event.getObject()).getId());
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
}

model

public class Car implements Serializable {

    public String id;
    public String brand;
    public int year;
    public String color;
    public int price;
    public boolean sold;

    public Car() {}

    public Car(String id, String brand, int year, String color) {
        this.id = id;
        this.brand = brand;
        this.year = year;
        this.color = color;
    }

    public Car(String id, String brand, int year, String color, int price, boolean sold) {
        this.id = id;
        this.brand = brand;
        this.year = year;
        this.color = color;
        this.price = price;
        this.sold = sold;
    }

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }

    public int getYear() {
        return year;
    }
    public void setYear(int year) {
        this.year = year;
    }

    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }

    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }

    public boolean isSold() {
        return sold;
    }
    public void setSold(boolean sold) {
        this.sold = sold;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 59 * hash + (this.id != null ? this.id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Car other = (Car) obj;
        if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) {
            return false;
        }
        return true;
    }
}

carService

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import org.primefaces.showcase.domain.Car;

@ManagedBean(name = "carService")
@ApplicationScoped
public class CarService {

    private final static String[] colors;

    private final static String[] brands;

    static {
        colors = new String[10];
        colors[0] = "Black";
        colors[1] = "White";
        colors[2] = "Green";
        colors[3] = "Red";
        colors[4] = "Blue";
        colors[5] = "Orange";
        colors[6] = "Silver";
        colors[7] = "Yellow";
        colors[8] = "Brown";
        colors[9] = "Maroon";

        brands = new String[10];
        brands[0] = "BMW";
        brands[1] = "Mercedes";
        brands[2] = "Volvo";
        brands[3] = "Audi";
        brands[4] = "Renault";
        brands[5] = "Fiat";
        brands[6] = "Volkswagen";
        brands[7] = "Honda";
        brands[8] = "Jaguar";
        brands[9] = "Ford";
    }

    public List<Car> createCars(int size) {
        List<Car> list = new ArrayList<Car>();
        for(int i = 0 ; i < size ; i++) {
            list.add(new Car(getRandomId(), getRandomBrand(), getRandomYear(), getRandomColor(), getRandomPrice(), getRandomSoldState()));
        }

        return list;
    }

    private String getRandomId() {
        return UUID.randomUUID().toString().substring(0, 8);
    }

    private int getRandomYear() {
        return (int) (Math.random() * 50 + 1960);
    }

    private String getRandomColor() {
        return colors[(int) (Math.random() * 10)];
    }

    private String getRandomBrand() {
        return brands[(int) (Math.random() * 10)];
    }

    private int getRandomPrice() {
        return (int) (Math.random() * 100000);
    }

    private boolean getRandomSoldState() {
        return (Math.random() > 0.5) ? true: false;
    }

    public List<String> getColors() {
        return Arrays.asList(colors);
    }

    public List<String> getBrands() {
        return Arrays.asList(brands);
    }
}

You can see more detail: RemoteCommand

like image 191
wittakarn Avatar answered Oct 24 '22 19:10

wittakarn


Since I prefer using vanilla JSF, I would do the following

put this above your table

<h:commandButton id="call-me-after-page"
                style="display:none;" action="#{myBean.myAction}">
                <f:ajax execute="@form" render="@form"></f:ajax>
            </h:commandButton>

and set the oncomplete like this:

<p:ajax event="page" oncomplete="$('#call-me-after-page').click();"></p:ajax>
like image 42
Daniel Avatar answered Oct 24 '22 17:10

Daniel