ICEfaces
  1. ICEfaces
  2. ICE-1140

ice:columns Sticking to First Column

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Incomplete
    • Affects Version/s: 1.5.1
    • Fix Version/s: 1.6DR#3
    • Component/s: ICE-Components
    • Labels:
      None
    • Environment:
      Operating System: Windows XP
      Platform: PC

      Description

      The "dynamic columns using ice:columns" posting on the icefaces.org forum
      outlines the problem.

      The table is rendering fine the first time, but on subsequent renderings, the
      columns all have the same content. Upon testing, the submitter of the post
      found that columnDataModel.getRowIndex() was returning 0 each time after the
      first render.

      I did some testing on my machine with an older version of ColumnsBean in the
      Component Showcase. I found that not changing the columnDataModel recreated
      the problem.

      The problem is not evident in the current form of the Columns demo because the
      content is the same in each column. However, using Rev. 11545 of ColumnsBean
      will give you dynamic cell content in different columns. In this version of
      ColumnsBean, the columnDataModel changes each time as the header String is
      modified to reflect the new range of values in the column. When you make the
      content of the columnDataModel static, (the same headers all the time) you
      will see the first column repeated across all the columns.
      1. columns.xhtml
        2 kB
        dukehoops
      2. Example3.java
        2 kB
        dukehoops
      3. Example3.java
        1 kB
        adnan_d

        Activity

        Hide
        dukehoops added a comment -

        I have a repro if one is needed

        Show
        dukehoops added a comment - I have a repro if one is needed
        Hide
        adnan_d added a comment -

        I have read through the forum posting, and created some examples which manifests application of ice:columns component including the one mentioned on the following forum by Kepatronik:

        http://www.icefaces.org/JForum/posts/list/3284.page

        I never found any problem of rowIndex with ice:columns component. I simulated the same test as kepatronik was mentioned and it is working very well.

        The application of ice:columns component is not as straigh forward as other components which creates confusion among developers. The ice:columns could be used for many different scenarios.

        First of all here is the default rendering of ice:columns component, which is not useful in this case (e.g.)

        • The "value" attribute of "dataTable" binds with the rowModel that represents rows of the table and each row is combination of both "column" or "columns" component.
        • The "value" attribute of "columns" component represents the columnModel, which renders each row of its model vertically as column. Sounds a bit confusing, let see in action(e.g.)

        bean code snippt:
        Strin[] rowModel =

        {"row1", "row2", "row2"}

        String[] columnsModel =

        {"col1", "col2", "col3"}

        jspx:
        <ice:dataTable value="#

        {bea.rowModel}

        " var="row"/>
        &ice:column>
        &ltice:outputText value="#

        {row}

        " />
        &lt/ice:column>

        &ice:columns value="#

        {bea.columnsModel}

        " var="column" >
        &ltice:outputText value="#

        {column}

        " />
        &lt/ice:columns>
        </ice:dataTable>

        rendered result:
        row1 col1 col2 col3
        row2 col1 col2 col3
        row3 col1 col2 col3

        As it can be seen above that it is not useful to have same column for each row, so when it would be useful? how about crossJoin? (e.g.)

        Task: Write a javascript events support among different browsers.

        String[] events=

        {"onclcik", "onkeyup", "ondrag"}

        String[] browsers =

        {"IE", "Firefox", "Safari"}

        DataModel rowModel = new ArrayDataModel(events);
        DataModel columnsModel = new ArrayDataModel(browsers);

        Map<String, String> eventSupport = new HashMap<String, String>();
        .....
        //Assume ondrag event is not supported by Safari
        for (String event: events) {
        for (String browser: browsers)

        { eventSupport.put(event+browser, String.valueOf(!(event.equals("ondrag") && browser.equals("Safari")))); }

        }
        .......
        .......
        public Object getCellValue(){
        DataModel rowDataModel = getRowModel();
        if (rowDataModel.isRowAvailable())
        {
        Object event = getRowModel().getRowData();
        DataModel columnsDataModel = getColumnsModel();
        if (columnsDataModel.isRowAvailable())

        { Object browser = columnsDataModel.getRowData(); return eventSupport.get(event+browser.toString()); }

        }
        return null;
        }
        .......
        JSPX:

        <ice:dataTable value="#

        {bean.rowModel}

        "
        var="event" >

        &ltice:column&gt
        &ltice:outputText value="#

        {event}

        " style="font-weight: bold;"/&gt
        &lt/ice:column&gt

        &ltice:columns value="#

        {bean.columnsModel}

        " var="broswer">
        &ltf:facet name="header">
        &lth:outputText value="#

        {broswer}

        " />
        &lt/f:facet>
        &ltice:outputText value="#

        {bean.cellValue}

        " style="color:#

        {bean.cellValue eq 'true'?'green':'red'}

        ;"/&gt
        </ice:columns>
        </ice:dataTable>

        Rendered output
        IE Firefox Safari
        onclcik true true true
        onkeyup true true true
        ondrag true true false

        Show
        adnan_d added a comment - I have read through the forum posting, and created some examples which manifests application of ice:columns component including the one mentioned on the following forum by Kepatronik: http://www.icefaces.org/JForum/posts/list/3284.page I never found any problem of rowIndex with ice:columns component. I simulated the same test as kepatronik was mentioned and it is working very well. The application of ice:columns component is not as straigh forward as other components which creates confusion among developers. The ice:columns could be used for many different scenarios. First of all here is the default rendering of ice:columns component, which is not useful in this case (e.g.) The "value" attribute of "dataTable" binds with the rowModel that represents rows of the table and each row is combination of both "column" or "columns" component. The "value" attribute of "columns" component represents the columnModel, which renders each row of its model vertically as column. Sounds a bit confusing, let see in action(e.g.) bean code snippt: Strin[] rowModel = {"row1", "row2", "row2"} String[] columnsModel = {"col1", "col2", "col3"} jspx: <ice:dataTable value="# {bea.rowModel} " var="row"/> &ice:column> &ltice:outputText value="# {row} " /> &lt/ice:column> &ice:columns value="# {bea.columnsModel} " var="column" > &ltice:outputText value="# {column} " /> &lt/ice:columns> </ice:dataTable> rendered result: row1 col1 col2 col3 row2 col1 col2 col3 row3 col1 col2 col3 As it can be seen above that it is not useful to have same column for each row, so when it would be useful? how about crossJoin? (e.g.) Task: Write a javascript events support among different browsers. String[] events= {"onclcik", "onkeyup", "ondrag"} String[] browsers = {"IE", "Firefox", "Safari"} DataModel rowModel = new ArrayDataModel(events); DataModel columnsModel = new ArrayDataModel(browsers); Map<String, String> eventSupport = new HashMap<String, String>(); ..... //Assume ondrag event is not supported by Safari for (String event: events) { for (String browser: browsers) { eventSupport.put(event+browser, String.valueOf(!(event.equals("ondrag") && browser.equals("Safari")))); } } ....... ....... public Object getCellValue(){ DataModel rowDataModel = getRowModel(); if (rowDataModel.isRowAvailable()) { Object event = getRowModel().getRowData(); DataModel columnsDataModel = getColumnsModel(); if (columnsDataModel.isRowAvailable()) { Object browser = columnsDataModel.getRowData(); return eventSupport.get(event+browser.toString()); } } return null; } ....... JSPX: <ice:dataTable value="# {bean.rowModel} " var="event" > &ltice:column&gt &ltice:outputText value="# {event} " style="font-weight: bold;"/&gt &lt/ice:column&gt &ltice:columns value="# {bean.columnsModel} " var="broswer"> &ltf:facet name="header"> &lth:outputText value="# {broswer} " /> &lt/f:facet> &ltice:outputText value="# {bean.cellValue} " style="color:# {bean.cellValue eq 'true'?'green':'red'} ;"/&gt </ice:columns> </ice:dataTable> Rendered output IE Firefox Safari onclcik true true true onkeyup true true true ondrag true true false
        Hide
        adnan_d added a comment -

        Here is the same version of demo with facelets, as I never used "header" facet inside the ice:columns, so this would only work with ICEFaces version >=1.6DR#1. If you want to run this demo with earlier version of ICEFaces then please add "header" facet inside the ice:column component.

        Show
        adnan_d added a comment - Here is the same version of demo with facelets, as I never used "header" facet inside the ice:columns, so this would only work with ICEFaces version >=1.6DR#1. If you want to run this demo with earlier version of ICEFaces then please add "header" facet inside the ice:column component.
        Hide
        dukehoops added a comment -

        I tried your example3 and as you've provided it, it did produce desired results. However the fact that you're incrementing an index in the getter of a property that's to be displayed produces these problems:

        1. add another button to the same page (but in a different form). This button is NOT supposed to alter state of data table. click it. dataTable pages forward (because ++ is executed during RENDER_RESPONSE). This means one cannot have other links/buttons or failing validation in the same page as dataTable. (which is quite unrealistic).
        2. cannot use this with session-scoped beans (and refresh page) - will advance dataTable forward because ++ will execute again.

        I'd augmented Example3 to fix the above and am posting it here. Search code for "NIKITA" to see the changes made. (Attaching Example3.java and columns.xhtml)

        -nikita
        http://themusiclounge.com

        Show
        dukehoops added a comment - I tried your example3 and as you've provided it, it did produce desired results. However the fact that you're incrementing an index in the getter of a property that's to be displayed produces these problems: 1. add another button to the same page (but in a different form). This button is NOT supposed to alter state of data table. click it. dataTable pages forward (because ++ is executed during RENDER_RESPONSE). This means one cannot have other links/buttons or failing validation in the same page as dataTable. (which is quite unrealistic). 2. cannot use this with session-scoped beans (and refresh page) - will advance dataTable forward because ++ will execute again. I'd augmented Example3 to fix the above and am posting it here. Search code for "NIKITA" to see the changes made. (Attaching Example3.java and columns.xhtml) -nikita http://themusiclounge.com
        Hide
        adnan_d added a comment -

        While I was writing this demo I never thought of multi buttons scenario, however again it is application problem not the component. I have re-factored the demo version to support multi buttons and change dataTable only if associated button was clicked.

        Show
        adnan_d added a comment - While I was writing this demo I never thought of multi buttons scenario, however again it is application problem not the component. I have re-factored the demo version to support multi buttons and change dataTable only if associated button was clicked.
        Hide
        dukehoops added a comment -

        what happens if, in example3 it is desired to print 'support info' twice for each cell? ie replace:

        <ice:outputText value="#

        {example3.suportInfo}"/>

        with:
        <ice:outputText value="#{example3.suportInfo}

        _#

        {example3.suportInfo}

        "/>
        ?

        Well, getSuportInfo() will be executed 2x per cell, and - because suportInfo is being incremented in the getter, instead of seeing "1_1" in a given cell, you'll see "1_2".

        Do you deem this an "application problem" as well? Should the client developer really change the way cell coordinates are computed depending on what is rendered inside this cell, or what other forms are present on the same page?

        What works better is this:

        (in getSuportInfo()):

        DataModel rowModel = this.getRowModel();
        DataModel colModel = this.getColumnsModel();
        int rIdx = rowModel.getRowIndex();
        int cIdx = colModel.getRowIndex();
        int pageOffset = rIdx*colModel.getRowCount() + cIdx;

        return suportInfo + pageOffset;

        -nikita

        Show
        dukehoops added a comment - what happens if, in example3 it is desired to print 'support info' twice for each cell? ie replace: <ice:outputText value="# {example3.suportInfo}"/> with: <ice:outputText value="#{example3.suportInfo} _# {example3.suportInfo} "/> ? Well, getSuportInfo() will be executed 2x per cell, and - because suportInfo is being incremented in the getter, instead of seeing "1_1" in a given cell, you'll see "1_2". Do you deem this an "application problem" as well? Should the client developer really change the way cell coordinates are computed depending on what is rendered inside this cell, or what other forms are present on the same page? What works better is this: (in getSuportInfo()): DataModel rowModel = this.getRowModel(); DataModel colModel = this.getColumnsModel(); int rIdx = rowModel.getRowIndex(); int cIdx = colModel.getRowIndex(); int pageOffset = rIdx*colModel.getRowCount() + cIdx; return suportInfo + pageOffset; -nikita
        Hide
        adnan_d added a comment -

        So did you get problem fixed??
        All attached demo were made to manifest that there isn't any bug or problem with the component itself. It is what requirements are and how developer designs it.
        As you found my design not to be promising enough for the scenario you mentioned, but you have right way to do it.

        Show
        adnan_d added a comment - So did you get problem fixed?? All attached demo were made to manifest that there isn't any bug or problem with the component itself. It is what requirements are and how developer designs it. As you found my design not to be promising enough for the scenario you mentioned, but you have right way to do it.
        Hide
        dukehoops added a comment -

        In short, no it didn't. Two problems:

        1. if a page contains two <ice:columns> tags on render I get the following error message:
        Mar 26, 2007 1:53:47 PM com.icesoft.faces.facelets.D2DFaceletViewHandler verifyUniqueComponentIds
        SEVERE: Multiple UIComponents found, which are wrongfully using the same id: -10. Most recent UIComponent: com.icesoft.faces.component.ext.UIColumns@a16b7c
        Mar 26, 2007 1:53:56 PM com.icesoft.faces.facelets.D2DFaceletViewHandler verifyUniqueComponentIds

        2. after some navigating to/from page (and/or doing page refresh) I can get the page into a state where a given row in dataTable has same value in every cell. This seems to happen because columnDataModel.getRowIndex() starts always returning '0's. At this point I cannot figure out a nav/refresh pattern that triggers this condition.
        Could #1 be causing this? Where in icefaces source should I look to see what affects DataModel.getRowIndex()? I've been looking through UIColumns.java and UISeries.java w/o any success.

        Show
        dukehoops added a comment - In short, no it didn't. Two problems: 1. if a page contains two <ice:columns> tags on render I get the following error message: Mar 26, 2007 1:53:47 PM com.icesoft.faces.facelets.D2DFaceletViewHandler verifyUniqueComponentIds SEVERE: Multiple UIComponents found, which are wrongfully using the same id: -10. Most recent UIComponent: com.icesoft.faces.component.ext.UIColumns@a16b7c Mar 26, 2007 1:53:56 PM com.icesoft.faces.facelets.D2DFaceletViewHandler verifyUniqueComponentIds 2. after some navigating to/from page (and/or doing page refresh) I can get the page into a state where a given row in dataTable has same value in every cell. This seems to happen because columnDataModel.getRowIndex() starts always returning '0's. At this point I cannot figure out a nav/refresh pattern that triggers this condition. Could #1 be causing this? Where in icefaces source should I look to see what affects DataModel.getRowIndex()? I've been looking through UIColumns.java and UISeries.java w/o any success.
        Hide
        Ken Fyten added a comment -

        This is not an ICEfaces issue.

        Show
        Ken Fyten added a comment - This is not an ICEfaces issue.

          People

          • Assignee:
            Adnan Durrani
            Reporter:
            Brad Kroeger
          • Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: