ICEfaces
  1. ICEfaces
  2. ICE-7244

MyFaces 2: component ids with datatables include row index twice

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0.2
    • Fix Version/s: 3.0.RC2, 3.0
    • Component/s: Framework, ICE-Components
    • Labels:
      None
    • Environment:
      MyFaces 2 ICEfaces 2 datatables
    • Assignee Priority:
      P1
    • Affects:
      Compatibility/Configuration

      Description

      When running under MyFaces, components within datatables are being assigned ids where the row index appears to be appended twice. So for example, in Mojarra where an element within a datatable might be identified as;

      <span id="iceform:datTbl:2:number" class="iceOutTxt">1</span>

      in MyFaces, the same element is identified as:

      <span id="iceform:datTbl:2:2:number" class="iceOutTxt">1</span>

      While it doesn't appear to strictly break any application functionality that I can identify, it does cause distress to many of our Selenium tests where we attempt to find elements within a datatable.
      1. ICE-7244.patch
        10 kB
        Deryk Sinotte
      1. datatable-ids.png
        501 kB

        Issue Links

          Activity

          Hide
          Deryk Sinotte added a comment -

          As per Mark's suggestion, I copied a bunch of MyFaces code into UISeries as outlined, then ran the Row Selection example in Component Showcase. The logging shows that both UISeries.getContainerClientId and UISeries.getClientId are being exercised and the resulting ids appear to be consistent between MyFaces and Mojarra. However, it looks to be missing one aspect of the id in the table row. Currently a row renders out as:

          <tr id="iceform:employeeList" ...
          <span id="iceform:employeeList:0:Number">...

          whereas before this change, Mojarra (which I'm using as the benchmark for this) used to do:

          <tr id="iceform:employeeList:0"...
          <span id="iceform:employeeList:0:Number"...

          So it appears that the row is simply missing the index at this point. Our latest theory is that there is a bunch of code in various components and renderers related to UISeries that need to be changed to use the getContainerClientId() method instead of getClientId().

          Show
          Deryk Sinotte added a comment - As per Mark's suggestion, I copied a bunch of MyFaces code into UISeries as outlined, then ran the Row Selection example in Component Showcase. The logging shows that both UISeries.getContainerClientId and UISeries.getClientId are being exercised and the resulting ids appear to be consistent between MyFaces and Mojarra. However, it looks to be missing one aspect of the id in the table row. Currently a row renders out as: <tr id="iceform:employeeList" ... <span id="iceform:employeeList:0:Number">... whereas before this change, Mojarra (which I'm using as the benchmark for this) used to do: <tr id="iceform:employeeList:0"... <span id="iceform:employeeList:0:Number"... So it appears that the row is simply missing the index at this point. Our latest theory is that there is a bunch of code in various components and renderers related to UISeries that need to be changed to use the getContainerClientId() method instead of getClientId().
          Hide
          Deryk Sinotte added a comment -

          After discussing with Ken and Mark, I'm re-assigning to Mark as this is something that the component team may need to tackle.

          Show
          Deryk Sinotte added a comment - After discussing with Ken and Mark, I'm re-assigning to Mark as this is something that the component team may need to tackle.
          Hide
          Deryk Sinotte added a comment -

          Attaching a patch of the changes I made to UISeries class to incorporate Mark's suggestions.

          Show
          Deryk Sinotte added a comment - Attaching a patch of the changes I made to UISeries class to incorporate Mark's suggestions.
          Hide
          Mark Collette added a comment -

          Sub-classes of UISeries would need to change, in certain places, their use of getClientId() to instead use getContainerClientId(), for this patch to work.

          Show
          Mark Collette added a comment - Sub-classes of UISeries would need to change, in certain places, their use of getClientId() to instead use getContainerClientId(), for this patch to work.
          Hide
          Mark Collette added a comment -

          The main change now is that a UIData's getClientId() should just follow the same behaviour as a non-UIData, and not include the rowIndex into the clientId anymore. While getContainerClientId() will take on that responsibility. This requires that sub-classes' rendering code make use of getContainerClientId() instead of getClientId() when rendering row specific information, and getClientId() when rendering stuff for the whole component.

          I took Deryk's patch, and adapted it a bit. Worked through the sub-classes of UISeries, searching for calls to getClientId(), modifying them as appropriate. Compat dataTable had a problem interoperating with compat columns, which columns was trying to work around by incorporating the dataTable's rowIndex into its own clientId calculations. Fixed that, so that only dataTable would have to be responsible for its rowIndex and not columns. And both would follow the new technique from UISeries.

          I tried fixing some little nit picking detail where panelTabSet in a non-UIData (not using value) scenario would still append ":0" to itself. But that ended up breaking a bunch of subtle things, so I ended up reverting all that.

          icefaces3
          Subversion 26886

          A regression was found where the RowSelector was broken, which I hadn't noticed since the showcase uses pre-styling. It turned out that there was code which expected clientId to have rowIndex in it, and was stripping that out, so when I made getClientId() to not have the rowIndex, then the stripping code removed other info. This code could be called from iterating and non-iterating code, so it just needed the stripping code to be removed, and to always use getClientId() instead of getContainerClientId() sometimes.

          It also highlighted how the search for getClientId() use had maybe not been thorough enough, since I had searched for UISeriesBase.getClientId() and in some cases it was being used as UIComponent.getClientId(), so I searched for a broader usage.

          icefaces3
          Subversion 26929

          Show
          Mark Collette added a comment - The main change now is that a UIData's getClientId() should just follow the same behaviour as a non-UIData, and not include the rowIndex into the clientId anymore. While getContainerClientId() will take on that responsibility. This requires that sub-classes' rendering code make use of getContainerClientId() instead of getClientId() when rendering row specific information, and getClientId() when rendering stuff for the whole component. I took Deryk's patch, and adapted it a bit. Worked through the sub-classes of UISeries, searching for calls to getClientId(), modifying them as appropriate. Compat dataTable had a problem interoperating with compat columns, which columns was trying to work around by incorporating the dataTable's rowIndex into its own clientId calculations. Fixed that, so that only dataTable would have to be responsible for its rowIndex and not columns. And both would follow the new technique from UISeries. I tried fixing some little nit picking detail where panelTabSet in a non-UIData (not using value) scenario would still append ":0" to itself. But that ended up breaking a bunch of subtle things, so I ended up reverting all that. icefaces3 Subversion 26886 A regression was found where the RowSelector was broken, which I hadn't noticed since the showcase uses pre-styling. It turned out that there was code which expected clientId to have rowIndex in it, and was stripping that out, so when I made getClientId() to not have the rowIndex, then the stripping code removed other info. This code could be called from iterating and non-iterating code, so it just needed the stripping code to be removed, and to always use getClientId() instead of getContainerClientId() sometimes. It also highlighted how the search for getClientId() use had maybe not been thorough enough, since I had searched for UISeriesBase.getClientId() and in some cases it was being used as UIComponent.getClientId(), so I searched for a broader usage. icefaces3 Subversion 26929

            People

            • Assignee:
              Mark Collette
              Reporter:
              Deryk Sinotte
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: