0

I'm trying to make a 5x5 matrix in JSF 2.2 with Primefaces 6.2 and Richfaces 4.5.16.Final.

Quite similar to Generate Matrix Datatable with JSF Framework like Primefaces. The only difference is, I want the option to edit every cell (with a dropdown). I managed to make the 5x5 matrix with a dataTable, but this only gives me the option to edit the entire first row.

Problem here is that the dataTable manages the data per row, while I want to access the data per cell.

My current html is:

    <rich:dataTable value="#{testBean.data}" var="line" id="matrixTable" rowKeyVar="index" columnClasses="cellWidth">
                <f:facet name="header">
                    <rich:columnGroup>
                        <rich:column rowspan="2" style="width: 150px">
                            <h:outputText value="Ernst"/>
                        </rich:column>
                        <rich:column colspan="5">
                            <h:outputText value="Waarschijnlijkheid"/>
                        </rich:column>
                        <rich:column breakRowBefore="true" width="" style="width: 150px">
                            <h:outputText value="A: Onwaarschijnlijk"/>
                        </rich:column>
                        <rich:column style="width: 150px">
                            <h:outputText value="B: Mogelijk"/>
                        </rich:column>
                        <rich:column style="width: 150px">
                            <h:outputText value="C: Waarschijnlijk"/>
                        </rich:column>
                        <rich:column style="width: 150px">
                            <h:outputText value="D: Zeer waarschijnlijk"/>
                        </rich:column>
                        <rich:column style="width: 150px">
                            <h:outputText value="E: Zeker"/>
                        </rich:column>
                    </rich:columnGroup>
                </f:facet>
                <rich:column >
                    <h:outputText value="#{line.ROW_LABELS[index + 1]}"/>
                </rich:column>

                <rich:column style="background-color: #{line.inzetmogelijkhedenList[0].kleur}">
                    <div class="tooltip">

                        <c:choose>
                            <c:when test="#{testBean.readOnly}">
                                <h:outputText value="#{testBean.data[0].inzetmogelijkhedenList[0].code}"/>
                            </c:when>
                            <c:otherwise>
                                <h:selectOneMenu value="#{testBean.data[0].inzetmogelijkhedenList[0].code}" id="a1" label="a1" disabled="#{testBean.locked}">
                                    <f:selectItems value="#{testBean.inzetmogelijkhedenList}" var="b" itemLabel="#{b.omschrijving}"/>
                                </h:selectOneMenu>
                            </c:otherwise>
                        </c:choose>

                        <span class="tooltiptext">#{line.inzetmogelijkhedenList[0].omschrijving}</span>
                    </div>
                </rich:column>
                <rich:column style="background-color: #{line.inzetmogelijkhedenList[1].kleur}">
                    <div class="tooltip">
                        <h:outputText value="#{line.inzetmogelijkhedenList[1].code}"/>
                        <span class="tooltiptext">#{line.inzetmogelijkhedenList[1].omschrijving}</span>
                    </div>
                </rich:column>
                <rich:column style="background-color: #{line.inzetmogelijkhedenList[2].kleur}">
                    <div class="tooltip">
                        <h:outputText value="#{line.inzetmogelijkhedenList[2].code}"/>
                        <span class="tooltiptext">#{line.inzetmogelijkhedenList[2].omschrijving}</span>
                    </div>
                </rich:column>
                <rich:column style="background-color: #{line.inzetmogelijkhedenList[3].kleur}">
                    <div class="tooltip">
                        <h:outputText value="#{line.inzetmogelijkhedenList[3].code}"/>
                        <span class="tooltiptext">#{line.inzetmogelijkhedenList[3].omschrijving}</span>
                    </div>
                </rich:column>
                <rich:column style="background-color: #{line.inzetmogelijkhedenList[4].kleur}">
                    <div class="tooltip">
                        <h:outputText value="#{line.inzetmogelijkhedenList[4].code}"/>
                        <span class="tooltiptext">#{line.inzetmogelijkhedenList[4].omschrijving}</span>
                    </div>
                </rich:column>
            </rich:dataTable>

This is the backing bean:

@ViewScoped
@ManagedBean(name = "testBean")
public class testBean {

public List<Inzetmogelijkheden> getInzetmogelijkhedenList() {
    return referentieService.findAllActueel(Inzetmogelijkheden.class, getUser());
}

public List<RisicomatrixRegel> getData() {
    // actuele IZM uit DB halen
    List<Inzetmogelijkheden> actueleInzetmogelijkheden = getInzetmogelijkhedenList();

    RisicomatrixRegel line1 = new RisicomatrixRegel(Arrays.asList(actueleInzetmogelijkheden.get(0), actueleInzetmogelijkheden.get(0), actueleInzetmogelijkheden.get(0), actueleInzetmogelijkheden.get(0), actueleInzetmogelijkheden.get(1)));
    RisicomatrixRegel line2 = new RisicomatrixRegel(Arrays.asList(actueleInzetmogelijkheden.get(2), actueleInzetmogelijkheden.get(2), actueleInzetmogelijkheden.get(2), actueleInzetmogelijkheden.get(2), actueleInzetmogelijkheden.get(1)));
    RisicomatrixRegel line3 = new RisicomatrixRegel(Arrays.asList(actueleInzetmogelijkheden.get(2), actueleInzetmogelijkheden.get(2), actueleInzetmogelijkheden.get(2), actueleInzetmogelijkheden.get(3), actueleInzetmogelijkheden.get(1)));
    RisicomatrixRegel line4 = new RisicomatrixRegel(Arrays.asList(actueleInzetmogelijkheden.get(3), actueleInzetmogelijkheden.get(3), actueleInzetmogelijkheden.get(3), actueleInzetmogelijkheden.get(1), actueleInzetmogelijkheden.get(1)));
    RisicomatrixRegel line5 = new RisicomatrixRegel(Arrays.asList(actueleInzetmogelijkheden.get(1), actueleInzetmogelijkheden.get(1), actueleInzetmogelijkheden.get(1), actueleInzetmogelijkheden.get(1), actueleInzetmogelijkheden.get(1)));

    return new ArrayList<>(Arrays.asList(line1, line2, line3, line4, line5));
}

}

The result in reading mode: enter image description here

The result in editing mode: enter image description here

Any hints?

Camelaria
  • 284
  • 6
  • 23

1 Answers1

3

Is there any specific reason why you're using the rich prefix while using Primefaces?

It seems you came from migrating legacy code that was attached to Richfaces instead, so, being legacy you use tag handlers instead of UI components, this is why you get an unexpected behaviour (only the first row being processed) in your Datatable.

Replace the c:choose block with conditional renders instead.

Also, you're accessing only the first line in your outputText and selectOneMenu components, replace them by line values.

Also, and finally, NEVER NEVER use getter methods to build up your structures in the JSF managed beans! They could be called more than once while the view renders. Instead, build up your data in a method annotated with @PostConstruct or use f:viewAction:

@ManagedBean
@ViewScoped
public class Bean {

    private List<RisicomatrixRegel> data;

    @PostConstruct
    public void init() {
        // actuele IZM uit DB halen
        List<Inzetmogelijkheden> actueleInzetmogelijkheden = referentieService.findAllActueel(Inzetmogelijkheden.class, getUser());

        RisicomatrixRegel line1 = new RisicomatrixRegel(Arrays.asList(actueleInzetmogelijkheden.get(0), 
            actueleInzetmogelijkheden.get(0), actueleInzetmogelijkheden.get(0), actueleInzetmogelijkheden.get(0), actueleInzetmogelijkheden.get(1)));
        RisicomatrixRegel line2 = new RisicomatrixRegel(Arrays.asList(actueleInzetmogelijkheden.get(2), 
            actueleInzetmogelijkheden.get(2), actueleInzetmogelijkheden.get(2), actueleInzetmogelijkheden.get(2), actueleInzetmogelijkheden.get(1)));
        RisicomatrixRegel line3 = new RisicomatrixRegel(Arrays.asList(actueleInzetmogelijkheden.get(2), 
            actueleInzetmogelijkheden.get(2), actueleInzetmogelijkheden.get(2), actueleInzetmogelijkheden.get(3), actueleInzetmogelijkheden.get(1)));
        RisicomatrixRegel line4 = new RisicomatrixRegel(Arrays.asList(actueleInzetmogelijkheden.get(3), 
            actueleInzetmogelijkheden.get(3), actueleInzetmogelijkheden.get(3), actueleInzetmogelijkheden.get(1), actueleInzetmogelijkheden.get(1)));
        RisicomatrixRegel line5 = new RisicomatrixRegel(Arrays.asList(actueleInzetmogelijkheden.get(1), 
            actueleInzetmogelijkheden.get(1), actueleInzetmogelijkheden.get(1), actueleInzetmogelijkheden.get(1), actueleInzetmogelijkheden.get(1)));

        data = Arrays.asList(line1, line2, line3, line4, line5);
    }

    public List<RisicomatrixRegel> getData() {
        return data;
    }

}
<h:outputText rendered="#{testBean.readOnly}" 
    value="#{line.inzetmogelijkhedenList[0].code}"/>
<h:selectOneMenu rendered="#{!testBean.readOnly}" 
    value="#{line.inzetmogelijkhedenList[0].code}" id="a1" 
    label="a1" disabled="#{testBean.locked}">
    <f:selectItems value="#{testBean.inzetmogelijkhedenList}" var="b" itemLabel="#{b.omschrijving}"/>
</h:selectOneMenu>

See also:

Aritz
  • 30,971
  • 16
  • 136
  • 217
  • Thanks for your response! I'm using JSF, Richfaces and Primefaces together, i'll edit this in my description. I tried your solution, but this gives me the same result als in my own code. Problem seems to be that the data is managed per line, so editing single cells doesn't seem possible.. – Camelaria Oct 16 '20 at 08:37
  • @Camelaria I didn't see the other things you have to fix at first sight... Just updated my answer :-) – Aritz Oct 18 '20 at 18:32
  • 1
    I love you, it works! :) I've used your code, including the @Postconstruct and getter. – Camelaria Oct 19 '20 at 09:06