1
votes

In my application I need to decide selection mode dynamically either 'single' or 'multiple' for datatable (I'm using primefaces 5.0) and depends on that selection assigned. Below are the el expressions i have binded.

XHTML:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:h="http://java.sun.com/jsf/html" 
      xmlns:p="http://primefaces.org/ui"
      xmlns:ui="http://java.sun.com/jsf/facelets"      
      >
    <h:head>

        <title>Primefaces Data Table</title>

        <script type="text/javascript" src="Test.js"/>

    </h:head>

    <h:body>
        <h:form id="form">

        <p:growl id="msgs" showDetail="true" />

        <p:dataTable id="T" var="car" widgetVar="T_wv" value="#{ECTestScreen.cars}" selectionMode="#{ECTestScreen.selectionMode}" selection="#{ECTestScreen.selectionMode ne 'multiple'? ECTestScreen.selectedCar :ECTestScreen.selectedCars}" rowKey="#{car.id}" paginator="true" rows="5" paginatorAlwaysVisible="true">

            <f:facet name="header">
                Row Selection on Click
            </f:facet>
            <p:column headerText="Car Id">
                <h:outputText value="#{car.id}" />
            </p:column>
            <p:column headerText="Year">
                <h:outputText value="#{car.year}" />
            </p:column>
            <p:column headerText="Brand">
                <p:inputTextarea id="ta" rows="10" cols="30" style="height: 22px; overflow:auto;" value="#{car.brand}" />
            </p:column>
            <p:column headerText="Color">
               <h:inputText value="#{car.color}" onmouseup="onCellFocus1(event, $(this).parent(), [{name: 'screenletId', value: 'T'}, {name: 'rowIndex', value: '5'}, {name: 'colName', value: 'Color'}]);"/>
            </p:column> 

           <p:ajax event="rowSelect" listener="#{ECTestScreen.onRowSelect}" update=":form:msgs" />

        </p:dataTable>

         <p:commandButton value="Update Table" actionListener="#{ECTestScreen.onButtonClick}"/>

        </h:form>
    </h:body>
</html>

Java code:

@ManagedBean(name = "ECTestScreen")
@ViewScoped
public class ECTestScreen implements Serializable {
    private static final long serialVersionUID = -855625904411046273L;

    private List<String> products = new ArrayList<>();
    private List<Integer> rowList = new ArrayList<>();
    private List<Car> cars = new ArrayList<>();
    private Car selectedCar ;
    private List<Car> selectedCars = new ArrayList<>();
    private String selectionMode="multiple";

    public List<Integer> getRowList() {
        return rowList;
    }

    public void setRowList(List<Integer> rowList) {
        this.rowList = rowList;
    }

    public List<String> getProducts() {     
        return products;
    }

    public void setProducts(List<String> products) {
        this.products = products;
    }

    public List<Car> getCars() {
        for(int j=1; j<10;j++){
            this.cars.add(new Car(j, (2000+j), "Merc-"+j, "Black-"+j));
        }
        return cars;
    }

    public void setCars(List<Car> cars) {       
        this.cars = cars;
    }

    public Car getSelectedCar() {       
        return selectedCar;
    }

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

    public List<Car> getSelectedCars() {
        FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add("form");
        return selectedCars;
    }

    public void setSelectedCars(List<Car> selectedCars) {
        this.selectedCars = selectedCars;
    }

    public String onButtonClick(){
        for(int i=1; i<6; i++){
            rowList.add(i);

        }

        for(int j=1; j<4;j++){
            products.add("td="+j);
        }

        for(int j=1; j<10;j++){
            cars.add(new Car(j, (2000+j), "Merc-"+j, "Black-"+j));
        }

        FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add("form");
        return "";
    }

    public String getSelectionMode(){
        return selectionMode;
    }

    public void setSelectionMode(String selectionMode){
                 selectionMode="multiple";

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

    public void onRowUnselect(UnselectEvent event) {
        FacesMessage msg = new FacesMessage("Car Unselected: ", ((Car) event.getObject()).getBrand());
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

Now the problem is if i assign selectionMode to either single or multiple through el or hardcoding and for selection if i point to only one function(either #{ECTestScreen.selectedCar} or #{ECTestScreen.selectedCars)) it works fine. But using above code if i decide selection mode dynamically either single or multiple depends on that if i add selection through above el the data table selection is not working means when selecting the row the setter is not at all called. and of course pagination also not working. it always stays in first page.

actually in case of single selection expects a single object where as in multiple selection list/array of objects...how to club these two..

Please help..

Primefaces version 5.0

2

2 Answers

0
votes

I don't really know why you would make that distinction, since a multiselection dataTable should also cover the single selection requirements.

But if you insist, then i would probably make 2 dataTables - one single and one multiple selection and make them "rendered" based on a boolean.

0
votes

selectedCars must be an array, not a List. The showcase presents example with a List, but it's not working that way.