Search code examples
jsf-2primefaces

Passing multiple parameters with onRowKey (p:datatable) in PF3.1


I am looking to pass multiple parameters from the following Primefaces 3.1 p:datatable:

 <p:dataTable value="#{tableBean.carsModel}" var="var" rowkey="#{var.model}" 
              selection="#{tableBean.car}" selectionMode="single">
    <p:ajax event="rowSelect" listener="#{tableBean.onRowClick}"></p:ajax>
    <p:column>
        <f:facet name="header">
            <h:outputText styleClass="outputText" value="Model"></h:outputText>
        </f:facet>
        <h:outputText styleClass="outputText" value="#{var.model}"></h:outputText>
    </p:column>
    <p:column>
        <f:facet name="header">
            <h:outputText styleClass="outputText" value="Color"></h:outputText>
        </f:facet>
        <h:outputText styleClass="outputText" value="#{var.randomColor}"></h:outputText>
    </p:column>
</p:dataTable>

I have a situation where I have more than 1 key as primary key, I am using rowkey="#{var.model} but, how to work with multiple primary keys.

I am also using CarDataModel extends ListDataModel<Car> implements SelectableDataModel<Car>{ class. Can somebody tell me how to work with?

@Override
public Car getRowData(String rowKey) {
    //In a real app, a more efficient way like a query by rowKey 
    //should be implemented to deal with huge data
    List<Car> cars = (List<Car>) getWrappedData();
    for(Car car : cars) {
        if(car.getModel().equals(rowKey))
            return car;
    }
    return null;
}

@Override
public Object getRowKey(Car car) {
    return car.getModel();
}

Any help is appreciated.


Solution

  • You'd need to use the composite key instead as row key.

    E.g.

    rowKey="#{car.compositeKey}"
    

    Or if you insist in using SelectableDataModel:

    @Override
    public Car getRowData(String rowKey) {
        List<Car> cars = (List<Car>) getWrappedData();
    
        for (Car car : cars) {
            if (car.getCompositeKey().equals(rowKey))
                return car;
        }
    
        return null;
    }
    
    @Override
    public Object getRowKey(Car car) {
        return car.getCompositeKey();
    }
    

    As to the concrete implementation of getCompositeKey(), it's unclear what two primary keys you have and what persistence API you're using. JPA for example has already support for composite keys and so your entity should already support it. But if you're not using JPA for some reason, then here's an example which assumes that both the model and the color represent the composite key, just to illustrate the idea:

    public String getCompositeKey() {
        return model + "." + color;
    }
    

    Or

    public Object[] getCompositeKey() {
        return new Object[] { model, color };
    }
    

    Or whatever uniquely represents as composite key based on Object#equals() contract.