ICEfaces
  1. ICEfaces
  2. ICE-9474

ace:dataExporter does not export <ui:repeat> values

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 3.1, 3.2, 3.3
    • Fix Version/s: EE-3.3.0.GA_P02, 4.0
    • Component/s: ACE-Components
    • Labels:
      None
    • Environment:
      All
    • Assignee Priority:
      P2
    • Workaround Exists:
      Yes
    • Workaround Description:
      Workaround is to use c:forEach instead of ui:repeat.

      Description

      The ace:dataExporter puts a "null" String value for coulms that are rendered using <ui:repeat> tags. For example this column is exported as "null" for every row.

      ....
      <ace:column headerText="Column">
      <ice:panelGroup>
      <ui:repeat value="#{item.connectedToDetails}" var="conection">
      <ice:commandLink value="#{conection.name}" actionListener="#{beanName.onExecuteSomeAction}">
      <f:attribute name="internalId" value="#{conection.internalId}" />
      </ice:commandLink>
      </ui:repeat>
      </ice:panelGroup>
      </ace:column>
      .....

      DataExporter type = "xls"

        Activity

        Hide
        Andrei Dorobat added a comment -

        I've narrowed the problem down to <ice:commandLink> and <h:commandLink>. When they are used inside an <ui:repeat> tag, the data exporter outputs "null" values. Any other component used (h:link, h:outputLink, h:outputText) renderes correctly when exported.

        Show
        Andrei Dorobat added a comment - I've narrowed the problem down to <ice:commandLink> and <h:commandLink>. When they are used inside an <ui:repeat> tag, the data exporter outputs "null" values. Any other component used (h:link, h:outputLink, h:outputText) renderes correctly when exported.
        Hide
        Arturo Zambrano added a comment -

        The newest code doesn't render a "null" string when components inside a table have null values; the empty string is rendered now.

        Is there a reason why ui:repeat must be used instead of c:forEach?

        The problem with ui:repeat is that it's not easy to extract it's "value". At the Render Response phase, the ui:repeat component goes through it's data model and renders each of those items for the response. The conflict is that when performing an exporting action, we don't get to the Render Response phase for all the components (only for the data exporter itself to render the generated resource URL). It's tricky to obtain what the ui:repeat component would render without getting to the rendering phase of that component. Moreover, the there's no standard ui:repeat class. The implementations of both Mojarra and MyFaces simply make the component extend from UIComponentBase and implement NamingContainer. Both APIs are different and don't offer anything particularly useful to extract what the component would render without getting to the rendering phase. Extracting the value of a ui:repeat would require a separate exporting operation.

        In contrast, when using c:forEach, the actual tags and components are added to the component tree before the Invoke Application phase, so it's easy to extract the value of each of those components in the same way it's already done.

        Show
        Arturo Zambrano added a comment - The newest code doesn't render a "null" string when components inside a table have null values; the empty string is rendered now. Is there a reason why ui:repeat must be used instead of c:forEach? The problem with ui:repeat is that it's not easy to extract it's "value". At the Render Response phase, the ui:repeat component goes through it's data model and renders each of those items for the response. The conflict is that when performing an exporting action, we don't get to the Render Response phase for all the components (only for the data exporter itself to render the generated resource URL). It's tricky to obtain what the ui:repeat component would render without getting to the rendering phase of that component. Moreover, the there's no standard ui:repeat class. The implementations of both Mojarra and MyFaces simply make the component extend from UIComponentBase and implement NamingContainer. Both APIs are different and don't offer anything particularly useful to extract what the component would render without getting to the rendering phase. Extracting the value of a ui:repeat would require a separate exporting operation. In contrast, when using c:forEach, the actual tags and components are added to the component tree before the Invoke Application phase, so it's easy to extract the value of each of those components in the same way it's already done.
        Hide
        Ken Fyten added a comment -

        Marking Won't Fix.

        Recommendation is to use c:forEach instead of ui:repeat for dynamic column display.

        Show
        Ken Fyten added a comment - Marking Won't Fix. Recommendation is to use c:forEach instead of ui:repeat for dynamic column display.
        Hide
        Michael Breu added a comment -

        Sorry, the solution is not acceptable.

        c:forEach has a different semantics compared with ui:repeat. In most circumstances it does not work. E.g.

                <ace:column headerText="Volumen">
                <TABLE><TBODY>
                  <ui:repeat var="amount" value="#{deal.volumen}">
                  <TR><TD>#{amount.value}</TD></TR>
                  </ui:repeat>
                 </TBODY></TABLE> 
                </ace:column>
        

        works

                <ace:column headerText="Volumen">
                <TABLE><TBODY>
                  <c:forEach var="amount" items="#{deal.volumen}">
                  <TR><TD>#{amount.value}</TD></TR>
                  </c:forEach>
                 </TBODY></TABLE> 
                </ace:column>
        

        renders an empty column.

        Show
        Michael Breu added a comment - Sorry, the solution is not acceptable. c:forEach has a different semantics compared with ui:repeat. In most circumstances it does not work. E.g. <ace:column headerText= "Volumen" > <TABLE> <TBODY> <ui:repeat var= "amount" value= "#{deal.volumen}" > <TR> <TD> #{amount.value} </TD> </TR> </ui:repeat> </TBODY> </TABLE> </ace:column> works <ace:column headerText= "Volumen" > <TABLE> <TBODY> <c:forEach var= "amount" items= "#{deal.volumen}" > <TR> <TD> #{amount.value} </TD> </TR> </c:forEach> </TBODY> </TABLE> </ace:column> renders an empty column.
        Hide
        Ken Fyten added a comment -

        By way of further explanation, it is not feasible to use c:forEach inside a dataTable as illustrated because the c:forEach is NOT processed at the same time the iteration of dataTable is processed. c:forEach is processed once in build JSF tree, at which time there is no "amount" variable defined. ace:dataTable defines the "amount" variable in the JSF restore/render phases. You can use the ui:repeat instead of c:forEach if you need to iterate in these phases, but note that the ace:dataExporter is not able to export these values.

        Show
        Ken Fyten added a comment - By way of further explanation, it is not feasible to use c:forEach inside a dataTable as illustrated because the c:forEach is NOT processed at the same time the iteration of dataTable is processed. c:forEach is processed once in build JSF tree, at which time there is no "amount" variable defined. ace:dataTable defines the "amount" variable in the JSF restore/render phases. You can use the ui:repeat instead of c:forEach if you need to iterate in these phases, but note that the ace:dataExporter is not able to export these values.

          People

          • Assignee:
            Arturo Zambrano
            Reporter:
            Andrei Dorobat
          • Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: