2
votes

Need some help to know if my solution is valid or not.

I have a primefaces datatable with single row selection, and I need to add a multiple selection checkbox column... My idea is to switch selection mode clicking on one button, that switch the selection mode from single to multiple and vice versa....

<pf:dataTable 
    value="${bean.notifications}" 
    var="notif" 
    selection="#{bean.isMultiple() ? consulterCorbeilleBean.selectedNotifs : consulterCorbeilleBean.selectedNotif}" 
    selectionMode="#{not bean.isMultiple() ? 'single' : ''}"
    rowKey="${notification.cle.idNotification}">

    <pf:ajax event="rowSelect" disabled="${bean.isMultiple()}"
            listener="${bean.function()}" update=":table:notificationTable" 
                    oncomplete="stopPropagationClick()" />

    <pf:column selectionMode="multiple" rendered="#{bean.isMultiple()}"/>

</pf:dataTable>

I have a problem with the selection binding. I have this error :

Illegal Syntax for Set Operation: javax.el.PropertyNotWritableException: /index.xhtml @114,50 selection="#{bean.isMultiple() ? bean.selectedNotifs : bean.selectedNotif}"

Any idea to workaround ? I use Primefaces 3.2.

Best Regards and thanks for your help :)

2

2 Answers

0
votes

You can't use dynamic setter values on the selection.

I would rethink the design if i were you, but if you really need both single and multiple selection options on the same table, you could use 2 datatables and render only 1 of them at a time, and switch between them with a button click.

0
votes

If you really need it, then you can try this work example

View

<h:form id="form">
    <p:growl id="msgs" showDetail="true" for="basicDT" />

    <p:inputSwitch value="#{dtSelectionView.multiple}">
        <p:ajax listener="#{dtSelectionView.addMessage}" update="basicDT, msgs" />
    </p:inputSwitch>

    <p:dataTable 
        id="basicDT" 
        var="car" 
        value="#{dtSelectionView.cars1}"
        rowStyleClass="#{dtSelectionView.checkSelection(car)? 'ui-state-highlight':''}"
        >

        <f:facet name="header">
            DoubleSelect
        </f:facet>

        <p:column style="width:32px">
            <p:commandButton update="basicDT,:form:msgs,:form:carDetail,:form:multiCarDetail" icon="ui-icon-check"  actionListener="#{dtSelectionView.addSelection(car)}" />
        </p:column>   

        <p:column headerText="Id">
            <h:outputText value="#{car.id}" />
        </p:column>

        <p:column headerText="Year">
            <h:outputText value="#{car.year}" />
        </p:column>

        <p:column headerText="Brand">
            <h:outputText value="#{car.brand}" />
        </p:column>

        <p:column headerText="Color">
            <h:outputText value="#{car.color}" />
        </p:column>

    </p:dataTable>


    <p:dialog header="Car Info" widgetVar="carDialog" modal="true" showEffect="fade" hideEffect="fade" resizable="false" closeOnEscape="true">
        <p:outputPanel id="carDetail" style="text-align:center;">
            <p:panelGrid  columns="2" rendered="#{not empty dtSelectionView.selectedCar}" columnClasses="label,value">
                <h:outputText value="Id:" />
                <h:outputText value="#{dtSelectionView.selectedCar.id}" />

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

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

                <h:outputText value="Price" />
                <h:outputText value="$#{dtSelectionView.selectedCar.price}" />
            </p:panelGrid>
        </p:outputPanel>
    </p:dialog>

    <p:dialog header="Selected Cars" widgetVar="multiCarDialog" modal="true" showEffect="fade" hideEffect="fade" resizable="false" width="200">
        <p:outputPanel id="multiCarDetail" style="text-align:center;">
            <ui:repeat value="#{dtSelectionView.selectedCars}" var="car">
                <h:outputText value="#{car.id} - #{car.brand}" style="display:block"/>
            </ui:repeat>
        </p:outputPanel>
    </p:dialog>

</h:form>

Model

import java.io.Serializable;

public class Car implements Serializable{

    private String Id;
    private String Brand;
    private int Year;
    private String Color;
    private int Price;
    private boolean SoldState;

    public Car(String id, String brand, int year, String color, int price,
        boolean soldState) {
        super();
        Id = id;
        Brand = brand;
        Year = year;
        Color = color;
        Price = price;
        SoldState = soldState;
    }

    @Override
    public boolean equals(Object o){
        if(o == null)                return false;
        if(!(o instanceof Car)) return false;

        Car other = (Car) o;
        if(! this.Id.equals(other.Id))      return false;
        if(! this.Brand.equals(other.Brand)) return false;
        if(this.Year != other.Year)   return false;
        if(! this.Color.equals(other.Color)) return false;
        if(this.Price != other.Price)   return false;
        if(this.SoldState != other.SoldState) return false;
        return true;
    }

    @Override
    public int hashCode(){
        return (int) Id.hashCode() * 
                Brand.hashCode() *
                Year *
                Color.hashCode() *
                Price *
                (SoldState ? 31 : 32)
                        ;
    }

  /** getters/setters */
}

Bean

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;

@ManagedBean(name="dtSelectionView")
@ViewScoped
public class SelectionView implements Serializable {

    private List<Car> cars1;
    private Car selectedCar;
    private List<Car> selectedCars;

    private boolean multiple= false;

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

    @PostConstruct
    public void init() {
        cars1 = service.createCars(10);/** random generated List. See PF showcase, datatable examples*/
        selectedCars = new ArrayList<Car>();
    }


    public boolean checkSelection(Car car){
        if(isMultiple())
            return selectedCars.contains(car) ? true : false;
        else
            return car.equals(selectedCar) ? true : false;
    }

    public void addSelection(Car car){
        String summary = "Car was ";
        if(isMultiple())
            if(selectedCars.contains(car)){
                selectedCars.remove(car);
                summary += "removed from list.";
            }
            else{
                selectedCars.add(car);
                summary += "added to list.";
                RequestContext.getCurrentInstance().execute("PF('multiCarDialog').show();");
            }
        else
            if(car.equals(selectedCar)){
                selectedCar = null;
                summary += "unselected.";
            }
            else{
                selectedCar = car;
                summary += "selected.";
                RequestContext.getCurrentInstance().execute("PF('carDialog').show();");
            }
            FacesContext.getCurrentInstance().addMessage("basicDT", new FacesMessage(summary));
    }

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

    public Car getSelectedCar() {
        return selectedCar;
    }

    public List<Car> getSelectedCars() {
        return selectedCars;
    }    

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

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

    public void addMessage() {
        selectedCar = null;
        selectedCars = new ArrayList<Car>();
        String summary = multiple ? "Checked" : "Unchecked";
        FacesContext.getCurrentInstance().addMessage("basicDT", new FacesMessage(summary));
    }
    public List<Car> getCars1() {
        return cars1;
    }

    public void setCars1(List<Car> cars1) {
        this.cars1 = cars1;
    }

    public CarService getService() {
        return service;
    }

    public boolean isMultiple() {
        return multiple;
    }

    public void setMultiple(boolean multiple) {
        this.multiple = multiple;
    }
}

Hope You'll in right direction.