1
votes

I have created a dataTable with an editable cell (component <p:cellEditor>), taking as reference the primefaces example.

<h:form id="form">
    <p:dataTable id="table" value="#{cars}" var="entity" editable="true" editMode="cell" tableStyle="width:auto">
        <p:ajax event="cellEdit" listener="#{carBean.onCellEdit}" />
        <p:column headerText="Owner">
            <p:cellEditor id="ownerCell">
                <f:facet name="input">
                    <p:selectOneMenu value="#{entity.owner.id}" style="width:100%">
                        <f:selectItems value="#{ownerBean.owners}" var="owner" itemLabel="#{owner.name}" itemValue="#{owner.id}" />
                    </p:selectOneMenu>
                </f:facet>
                <f:facet name="output">
                    <h:panelGroup id="ownerOutput"><h:outputText value="#{entity.owner.name}" /></h:panelGroup>
                </f:facet>
            </p:cellEditor>
        </p:column>

My problem is the update of the cell. I can change the value of the selectOneMenu element but the facet component output (id="ownerOutput") is not updated. I have checked that only when the facet input and output have the same value of the attribute value, i.e.

<p:selectOneMenu value="#{entity.owner.name}" style="width:100%">
    <f:selectItems value="#{ownerBean.owners}" var="owner" itemLabel="#{owner.name}" itemValue="#{owner.name}" />

then the code works. But I want to use my original code with id. Other solutions that I tried without success:

  1. Solution 1:

    <p:ajax event="cellEdit" listener="#{carBean.onCellEdit}" update="table" />
    
  2. Solution 2:

    public void onCellEdit(CellEditEvent event) {
    Object newValue = event.getNewValue();
    if(newValue != null) {
        int alteredRow = event.getRowIndex();
        String columnName = event.getColumn().getHeaderText();
        FacesContext context = FacesContext.getCurrentInstance();
        Account entity = context.getApplication().evaluateExpressionGet(context, "#{entity}", Car.class);
        entity = service.findAndLoadEntityWithLazyReferencesById(Car.class, entity.getId());
        if(columnName.equals("Owner") {
            entity.setUsername((String) newValue);
        }
    Owner owner = service.findEntityById(Owner.class, (Long) newValue);
            entity.setOwner(owner);
    try {
            service.createOrUpdateEntity(entity);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    if(columnName.equals("Owner") {
            RequestContext.getCurrentInstance().update("form:table:" + String.valueOf(alteredRow) + ":memberCell");
        }
    
1

1 Answers

1
votes

your problem is not the update of the components, actually they're pretty well updated. its the submit. your selectOneMenu is not submitted when you choose an option. you need to put an ajax inside it. a simple <p:ajax/> will do it.

<p:selectOneMenu value="#{entity.owner.id}" style="width:100%">
    <f:selectItems value="#{ownerBean.owners}" var="owner" itemLabel="#{owner.name}" itemValue="#{owner.id}" />
    <p:ajax/>
</p:selectOneMenu>