Updating pe:Sheet generated by <ui:repeat>

Community Driven Extensions Project
clementine
Posts: 11
Joined: 05 Nov 2019, 20:39

27 Mar 2020, 01:14

Can Sheet be dynamically generated (the entire sheet, not just columns or rows)? I'm generating multiple Sheets with <ui:repeat>.

Code: Select all

<ui:repeat value="#{bean.tableContentMap}" var="day">
	<pe:sheet value=#{bean.tableContentMap.get(day)}
			  var="row">
			  <p:ajax event="change" listener="#{bean.sheetCellChangeEvent}"/>
	</pe:sheet>
</ui:repeat>
Let's say I have 2 entries in "tableContentMap": {day:Integer, content:TableRowObject}

Rendering is fine. Everything shows up the way it's supposed to: two separate Sheet's are generated, displaying the correct values, each cell calling its respective getter. However, when I try to change/update a cell in the 2nd Sheet (where "day= 2"), it's not calling the setter of that cell. Neither does the change show up in "event.getSheet().getUpdates()".

Works in the 1st Sheet though.

Melloware
Posts: 3717
Joined: 22 Apr 2013, 15:48

27 Mar 2020, 13:50

Hmm ok a couple of things to ask /try.

Looks similar to this ticket: https://github.com/primefaces/primefaces/issues/3812

1. Are you using MyFaces or Mojarra and which version?

2. have you tried p:repeat instead of ui:repeat ?

I feel like there is definitely a bug in here somewhere.
PrimeFaces Developer | PrimeFaces Extensions Developer
GitHub Profile: https://github.com/melloware
PrimeFaces Elite 13.0.0 / PF Extensions 13.0.0
PrimeReact 9.6.1

clementine
Posts: 11
Joined: 05 Nov 2019, 20:39

27 Mar 2020, 17:50

Environment:
- Primefaces 7.0
- Primefaces-extensions 7.0.3
I don't think we're using MyFaces or Mojarra (don't seem them in my pom).

I've tried <p:repeat> and it gave me the same result. I even tried <c:forEach> as it was used in the Sheet demo (https://www.primefaces.org/showcase-ext ... olumns.jsf) then realized it was deprecated and caused even more problems.

Melloware
Posts: 3717
Joined: 22 Apr 2013, 15:48

28 Mar 2020, 13:58

Is there any way you could put together a small example showing the issue using the Primefaces Test project?

https://github.com/primefaces/primefaces-test

That way I can debug it and fix it.

Also "c:forEach" is not deprecated? What makes you think its deprecated?
PrimeFaces Developer | PrimeFaces Extensions Developer
GitHub Profile: https://github.com/melloware
PrimeFaces Elite 13.0.0 / PF Extensions 13.0.0
PrimeReact 9.6.1

clementine
Posts: 11
Joined: 05 Nov 2019, 20:39

01 Apr 2020, 23:09

I cloned the Primefaces Test project and made changes to the following files:

pom.xml

Code: Select all

<dependency>
            <groupId>org.primefaces.extensions</groupId>
            <artifactId>primefaces-extensions</artifactId>
            <version>7.0.3</version>
</dependency>

<dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>7.0</version>
</dependency>
test.xhtml

Code: Select all

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

    <h:head>
        <title>PrimeFaces Test</title>
    </h:head>
    <h:body>

        <h1>#{testView.testString}</h1>

        <h:form id="form">

            <h3>Sheet Outside of ui:repeat (Day 0 data)</h3>
            <pe:sheet id="testSheet"
                      widgetVar="sheetWidget"
                      value="#{testView.testMap.get(testView.testList.get(0))}"
                      var="row"
                      height="150"
                      rowKey="#{row.id}">

                <p:ajax event="change"
                        listener="#{testView.cellChangeEvent}"
                        update="changedValues"/>

                <pe:sheetcolumn headerText="Data [String]"
                                value="#{row.dataString}"/>

                <pe:sheetcolumn headerText="Data [Integer]"
                                value="#{row.dataInteger}"/>
            </pe:sheet>



            <!-- Test whether ajax update is not working in general, or just in pe:sheet-->
            <p:commandButton value="Test AJAX update"
                             action="#{testView.testAjax()}"
                             update="changedValues"/>



            <h3>Sheets Inside ui:repeat</h3>
            <p:outputPanel id="changedValues">
                <h:panelGroup >
                    <p:panel id="testAjax">
                        <h:outputText value="AJAX update: " style="font-weight: bold; color: dodgerblue" />
                        <h:outputText value="#{testView.testAjaxValue}" /><br/><br/>
                    </p:panel>

                    <p:panel id="changedValue0">
                        <h:outputText value="Day 0 Row 1 'Data [String]' value: " style="font-weight: bold; color: dodgerblue"/>
                        <h:outputText value="#{testView.testMap.get(testView.testList.get(0)).get(0).dataString}" /><br/><br/>
                    </p:panel>

                    <p:panel id="changedValue1">
                        <h:outputText value="Day 1 Row 1 'Data [String]' value: " style="font-weight: bold; color: dodgerblue"/>
                        <h:outputText value="#{testView.testMap.get(testView.testList.get(1)).get(0).dataString}" /><br/><br/>
                    </p:panel>

                    <p:panel id="changedValue2">
                        <h:outputText value="Day 2 Row 1 'Data [String]' value: " style="font-weight: bold; color: dodgerblue"/>
                        <h:outputText value="#{testView.testMap.get(testView.testList.get(2)).get(0).dataString}" /><br/><br/>
                    </p:panel>
                </h:panelGroup>
            </p:outputPanel><br/><br/>




            <ui:repeat value="#{testView.testList}" var="day">
                <h:panelGroup id="sheetPanel">

                    <h:outputText value="DAY #{day}"/>

                    <pe:sheet id="sheet"
                              widgetVar="sheetWidget"
                              value="#{testView.testMap.get(day)}"
                              var="row"
                              height="150"
                              rowKey="#{row.id}">

                        <p:ajax event="change"
                                listener="#{testView.cellChangeEvent}"
                                update="@form:changedValues"/>

                        <pe:sheetcolumn headerText="Data [String]"
                                        value="#{row.dataString}"/>

                        <pe:sheetcolumn headerText="Data [Integer]"
                                        value="#{row.dataInteger}"/>
                    </pe:sheet>
                </h:panelGroup>
            </ui:repeat>


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

TestView.java

Code: Select all

package org.primefaces.test;
import org.primefaces.extensions.component.sheet.Sheet;
import org.primefaces.extensions.event.SheetEvent;
import org.primefaces.extensions.model.sheet.SheetUpdate;

import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.util.*;

@Named
@ViewScoped
public class TestView implements Serializable {
    
    private String testString;
    private HashMap<Integer, List<SheetDataRow>> testMap;
    private List<Integer> testList;
    private String testAjaxValue;
    
    @PostConstruct  
    public void init() {
        testString = "Welcome to PrimeFaces!!!";

        // generate sheet data
        testMap = new HashMap<>(3);
        testList = new ArrayList<>(3);
        for(int i = 0; i < 3; i++) {
            List<SheetDataRow> sheetDataRows = new ArrayList<>(2);
            for(int j = 0; j < 2; j++) {
                SheetDataRow row = new SheetDataRow("String data " + i + j, i + j);
                sheetDataRows.add(row);
            }

            testMap.put(i, sheetDataRows);
            testList.add(i);
        }

        testAjaxValue = "click 'Test AJAX update' button to change me";
    }

    public String getTestString() { return testString; }
    public void setTestString(String testString) { this.testString = testString; }

    public HashMap<Integer, List<SheetDataRow>> getTestMap() { return testMap; }
    public void setTestMap(HashMap<Integer, List<SheetDataRow>> inMap) { testMap = inMap; }

    public List<Integer> getTestList() { return testList; }
    public void setTestList(List<Integer> testList) { this.testList = testList; }

    public String getTestAjaxValue() { return testAjaxValue; }
    public void setTestAjaxValue(String testAjaxValue) { this.testAjaxValue = testAjaxValue; }

    public void cellChangeEvent(SheetEvent event) {
        System.out.println("inside cellChangeEvent()");

        Sheet sheet = event.getSheet();
        List<SheetUpdate> updates = sheet.getUpdates();
        if(updates != null && updates.size() > 0) {
            for(SheetUpdate sheetUpdate : updates)
            {
                System.out.println("updates are getting through :)");
            }
        } else {
            System.out.println("updates NOT getting through :(");
        }

        sheet.commitUpdates();
    }

    public void testAjax() {
        testAjaxValue = "AJAX update via commandButton works!";
    }
}
New file: SheetDataRow.java

Code: Select all

package org.primefaces.test;

import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

@Named
@ViewScoped
public class SheetDataRow implements Serializable {
    
    private Integer id;
    private String dataString;
    private Integer dataInteger;

    
    public SheetDataRow(){}
    public SheetDataRow(String inDataString, Integer inDataInteger) {
        dataString = inDataString;
        dataInteger = inDataInteger;
        id = inDataInteger;
    }


    @PostConstruct
    public void init() {}

    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }

    public String getDataString() { return dataString; }
    public void setDataString(String dataString) { this.dataString = dataString; }

    public Integer getDataInteger() { return dataInteger; }
    public void setDataInteger(Integer dataInteger) { this.dataInteger = dataInteger; }
}

I'm unable to exactly reproduce the issue I see in my own project. I couldn't figure out how to get pe:sheet to update at all in the Primefaces test project environment (inside or outside ui:repeat). My server shows the following custom message when I change a cell value:

Code: Select all

[INFO] Started Jetty Server
inside cellChangeEvent()
updates NOT getting through :(

Melloware
Posts: 3717
Joined: 22 Apr 2013, 15:48

02 Apr 2020, 00:13

Can you zip up your project somewhere (excluding the target folder) that I could grab it?
PrimeFaces Developer | PrimeFaces Extensions Developer
GitHub Profile: https://github.com/melloware
PrimeFaces Elite 13.0.0 / PF Extensions 13.0.0
PrimeReact 9.6.1


Melloware
Posts: 3717
Joined: 22 Apr 2013, 15:48

02 Apr 2020, 13:59

Thanks I will investigate and get back to you.
PrimeFaces Developer | PrimeFaces Extensions Developer
GitHub Profile: https://github.com/melloware
PrimeFaces Elite 13.0.0 / PF Extensions 13.0.0
PrimeReact 9.6.1

Melloware
Posts: 3717
Joined: 22 Apr 2013, 15:48

02 Apr 2020, 16:28

OK I agree with you, something really whacky is going on here. I even separated yours into form1 and form2 where the ui:repeat is in form2 and if I edit a cell on form1 its submitted form2 when I hit F12 and watch the Network traffic.
PrimeFaces Developer | PrimeFaces Extensions Developer
GitHub Profile: https://github.com/melloware
PrimeFaces Elite 13.0.0 / PF Extensions 13.0.0
PrimeReact 9.6.1

clementine
Posts: 11
Joined: 05 Nov 2019, 20:39

08 Apr 2020, 17:25

Separating the form into two was a good idea; it fixed some of the other problems I ran into with Sheet. But you're right, it doesn't fix this particular problem.

Is there a plan to fix this? Can I wait for a fix, or should I avoid wrapping Sheet inside ui:repeat altogether? It would be really powerful to have this functionality working.

Thank you for your help!

Post Reply

Return to “Extensions”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 21 guests