Details

    • Type: New Feature New Feature
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.7DR#2
    • Fix Version/s: 1.7DR#3, 1.7
    • Component/s: ICE-Components
    • Labels:
      None
    • Environment:
      All
    • Affects:
      Documentation (User Guide, Ref. Guide, etc.), Sample App./Tutorial

      Description

      [Q#] blocks represent questions that have to be investigated


      Right now, if you use a menuPopup with MenuItem actionListener, you can't tell which component was clicked on. We need a means of passing that information back to the server, where application level code see what summoned the popup, and hence, on what to do the actions.

      At the minimum, we need the clientId of the summoner component, and if a bean method can be invoked while UIData/UISeries iteration has arrived at that summoner component, then all of the current row / column relationships should be properly setup, when that bean method is invoked, to know exactly what context the application needs to do its action. [Q1] Assuming that all of our container components are UISeries components, encode their row information in their children's clientIds. Investigate: panelSeries, dataTable, etc. [/Q1] [Q2] It should be possible to use a simple ValueBinding bean property setter, invoked in the UPDATE_MODEL phase, since I think that iteration happens then too [/Q2] The ValueBinding property, called menuContext, would have to be on the summoner component, since the menuPopup won't necessarily be near it in the component tree, so it might have different UISeries iteration. It would set a reference to the summoner UIComponent itself, which applications should not keep beyond the life of that setter method's execution. As well, any intra-component context info could be set as well, such as selectInputDate setting which specific date was context-clicked on. This would have to be passed in, from the Javascript, to the request map, along with the summoner clientId.

      The summoner clientId will have to be setup to go to the server when the onContextClick event is caught, but it will only be transmitted if one of the MenuItems has been clicked. So if the menu is closed without anything being clicked, that clientId should be discarded, so it's not sent when some other non-menuPopup submit occurs.

      The problem with the simple solution above is that it will probably require component bindings in the bean, to query the UISeries what their current row is. Bindings cause problems in Seam, and it's generally preferred to do a POJO approach. In that light, it's advantageous to be able to directly pass to the bean the row information directly, so it doesn't have to go to the components, but can just directly access the data models, and extract the info from there.

      Now, the clientIds technically hold that information already, but each container can encode their row information differently, so it would be their responsibility to decode that information as well. Just like how the summoner component and its intra-component context was set, the containers could also set themselves and their row information into the bean.

      [IF Q1]
      In the DECODE phase the containers can examine the summoner clientId in the request map, and derive their row from there, for setting in the UPDATE_MODEL phase.
      [ELSE]
      If the clientIds don't contain all of the information already, and we're not relying on component bindings, then we have to make it so that the onContextClick event will bubble up all of the way, except that while the first receiver of the event, the summoner, will make the menuPopup show, the others higher up the tree will simply save their clientIds and row information for the upcoming submit, along with where the summoner saved its clientId and intra-component context.
      [ENDIF]

      Since there are several components all calling setters on the bean, one after the other, with references to themselves, and any row indexes, or intra-component context, there should be some standard wrapper object that would encapsulate that, along with a terminal boolean to tell the bean that it's finally gotten the setter for the actual summoner, and not just a parent container.

        Activity

        Hide
        Ted Goddard added a comment -

        Please provide sample code showing usage of the menuPopup.

        Show
        Ted Goddard added a comment - Please provide sample code showing usage of the menuPopup.
        Hide
        Mark Collette added a comment -

        <ice:panelSeries var="city" value="#

        {bean.cities}

        "
        menuPopup="cityPopup" menuContext="#

        {bean.cityContext}

        ">
        <ice:outputText value="#

        {city.name}

        "/>
        <br/>
        <ice:outputText value="#

        {city.province}

        "/>

        <ice:dataTable var="hospital" value="#

        {city.hospitals}

        "
        menuPopup="hospitalPopup" menuContext="#

        {bean.hospitalContext}

        ">
        <ice:columns var="hospital_detail" value="#

        {bean.hospital_details}

        " <!-- name, address, bed_capacity -->
        menuContext="#

        {bean.hospitalDetailContext}

        ">
        <ice:outputText value="#

        {hospital_detail}

        "
        menuContext="#

        {bean.outputContext}

        "/>
        </ice:columns>
        </ice:dataTable>
        </ice:panelSeries>

        <ice:menuPopup id="cityPopup">
        <ice:menuItem .../>
        <ice:menuItem .../>
        </ice:menuPopup>

        <ice:menuPopup id="hospitalPopup">
        <ice:menuItems .../>
        </ice:menuPopup>

        So, if I context-click in the hospital_detail outputText, it will use the inner-most menu on it or up its parents, which is the hospitalPopup. If a menu item from the hospitalPopup menuPopup is clicked, then Bean.setCityContext will be called with a reference to the ice:panelSeries and the integer row of which city that hospital is in. Bean.setHospitalContext will be called with a reference to the ice:dataTable and the integer row of the specific hospital. Bean.setHospitalDetailContext will be called with a reference to the ice:columns and the integer column that was clicked in. Bean.outputContext will be called with a reference to the ice:outputText that was context-clicked in, and the terminal flag will be set, so that we know this is the most precisely what was clicked on. As each of these Bean.set* methods are called, the panelSeries will be setup to be on that specific iteration, the dataTable will be on that current row, and the columns on that specific column, so that methods calls on them will do the expected thing.

        Now, if the city name or city province outputTexts are context-clicked on, then cityPopup popup menu will be shown, and if a menuitem from it is clicked, then only the Bean.setCityContext method will be called.

        Show
        Mark Collette added a comment - <ice:panelSeries var="city" value="# {bean.cities} " menuPopup="cityPopup" menuContext="# {bean.cityContext} "> <ice:outputText value="# {city.name} "/> <br/> <ice:outputText value="# {city.province} "/> <ice:dataTable var="hospital" value="# {city.hospitals} " menuPopup="hospitalPopup" menuContext="# {bean.hospitalContext} "> <ice:columns var="hospital_detail" value="# {bean.hospital_details} " <!-- name, address, bed_capacity --> menuContext="# {bean.hospitalDetailContext} "> <ice:outputText value="# {hospital_detail} " menuContext="# {bean.outputContext} "/> </ice:columns> </ice:dataTable> </ice:panelSeries> <ice:menuPopup id="cityPopup"> <ice:menuItem .../> <ice:menuItem .../> </ice:menuPopup> <ice:menuPopup id="hospitalPopup"> <ice:menuItems .../> </ice:menuPopup> So, if I context-click in the hospital_detail outputText, it will use the inner-most menu on it or up its parents, which is the hospitalPopup. If a menu item from the hospitalPopup menuPopup is clicked, then Bean.setCityContext will be called with a reference to the ice:panelSeries and the integer row of which city that hospital is in. Bean.setHospitalContext will be called with a reference to the ice:dataTable and the integer row of the specific hospital. Bean.setHospitalDetailContext will be called with a reference to the ice:columns and the integer column that was clicked in. Bean.outputContext will be called with a reference to the ice:outputText that was context-clicked in, and the terminal flag will be set, so that we know this is the most precisely what was clicked on. As each of these Bean.set* methods are called, the panelSeries will be setup to be on that specific iteration, the dataTable will be on that current row, and the columns on that specific column, so that methods calls on them will do the expected thing. Now, if the city name or city province outputTexts are context-clicked on, then cityPopup popup menu will be shown, and if a menuitem from it is clicked, then only the Bean.setCityContext method will be called.
        Hide
        Mark Collette added a comment -

        As it stands, one would get menuPopup context by wrapping their inner-most component in a panelGroup. The panelGroup can have its menuPopup attribute set to specify which menuPopup to show, and have its menuContext attribute set to a write-only ValueBinding, which takes a MenuContextEvent argument. If one wanted more context, from other containers, like panelSeries or dataTable, then one could add an <f:attribute name="menuContext" value="#

        {bean.xyz}

        "/> tag to them, and the bean's setXyz(MenuContextEvent) method would be called. The menuContext methods would be called before the MenuItem actionListener method, if the user clicked on a menu item.

        Subversion 15355
        icefaces\bridge\component\menu.js
        icefaces\bridge\src\submit.js
        icefaces\component-metadata\src\main\resources\conf\ice_properties\ice-att-menuPopup-props.xml
        icefaces\component\src\com\icesoft\faces\component\ext\HtmlPanelGroup.java
        icefaces\component\src\com\icesoft\faces\component\ext\renderkit\GroupRenderer.java
        icefaces\component\src\com\icesoft\faces\component\menupopup\MenuContextEvent.java
        icefaces\component\src\com\icesoft\faces\component\menupopup\MenuPopupHelper.java
        icefaces\core\src\com\icesoft\faces\renderkit\dom_html_basic\DomBasicRenderer.java

        Show
        Mark Collette added a comment - As it stands, one would get menuPopup context by wrapping their inner-most component in a panelGroup. The panelGroup can have its menuPopup attribute set to specify which menuPopup to show, and have its menuContext attribute set to a write-only ValueBinding, which takes a MenuContextEvent argument. If one wanted more context, from other containers, like panelSeries or dataTable, then one could add an <f:attribute name="menuContext" value="# {bean.xyz} "/> tag to them, and the bean's setXyz(MenuContextEvent) method would be called. The menuContext methods would be called before the MenuItem actionListener method, if the user clicked on a menu item. Subversion 15355 icefaces\bridge\component\menu.js icefaces\bridge\src\submit.js icefaces\component-metadata\src\main\resources\conf\ice_properties\ice-att-menuPopup-props.xml icefaces\component\src\com\icesoft\faces\component\ext\HtmlPanelGroup.java icefaces\component\src\com\icesoft\faces\component\ext\renderkit\GroupRenderer.java icefaces\component\src\com\icesoft\faces\component\menupopup\MenuContextEvent.java icefaces\component\src\com\icesoft\faces\component\menupopup\MenuPopupHelper.java icefaces\core\src\com\icesoft\faces\renderkit\dom_html_basic\DomBasicRenderer.java
        Hide
        Mark Collette added a comment -

        I modified the component-showcase's MenuBar/MenuPopup section and the Table Columns section to both demonstrate the menuPopup with menuContext. It should be possible to make the MenuBar/MenuPopup text highlight and the image pulsate. In the Table Columns, you can right-click to select a cell, and change its styleClass to show a blue background color.

        Subversion 15358
        icefaces\samples\component-showcase\src\com\icesoft\icefaces\samples\showcase\components\menuBar\MenuBarBean.java
        icefaces\samples\component-showcase\src\com\icesoft\icefaces\samples\showcase\components\table\ColumnsBean.java
        icefaces\samples\component-showcase\src\com\icesoft\icefaces\samples\showcase\resources\messages.properties
        icefaces\samples\component-showcase\web\css\showcase_style.css
        icefaces\samples\component-showcase\web\inc\components\menuBar.jspx
        icefaces\samples\component-showcase\web\inc\components\tableColumns.jspx

        Show
        Mark Collette added a comment - I modified the component-showcase's MenuBar/MenuPopup section and the Table Columns section to both demonstrate the menuPopup with menuContext. It should be possible to make the MenuBar/MenuPopup text highlight and the image pulsate. In the Table Columns, you can right-click to select a cell, and change its styleClass to show a blue background color. Subversion 15358 icefaces\samples\component-showcase\src\com\icesoft\icefaces\samples\showcase\components\menuBar\MenuBarBean.java icefaces\samples\component-showcase\src\com\icesoft\icefaces\samples\showcase\components\table\ColumnsBean.java icefaces\samples\component-showcase\src\com\icesoft\icefaces\samples\showcase\resources\messages.properties icefaces\samples\component-showcase\web\css\showcase_style.css icefaces\samples\component-showcase\web\inc\components\menuBar.jspx icefaces\samples\component-showcase\web\inc\components\tableColumns.jspx
        Hide
        Mark Collette added a comment -

        Apparently Facelets is way better than regular JSP based JSF. The following changes will let the JSP component-showcase function at all. But, the menuPopup menuContext feature won't work in the Table Columns section, without adding the menuContext attribute to a whole bunch of components, which will have to wait a little bit.

        Subversion 15367
        icefaces\core\src\com\icesoft\faces\application\D2DViewHandler.java
        icefaces\samples\component-showcase\src\com\icesoft\icefaces\samples\showcase\components\menuBar\MenuBarBean.java
        icefaces\samples\component-showcase\src\com\icesoft\icefaces\samples\showcase\components\table\ColumnsBean.java
        icefaces\samples\component-showcase\web\inc\components\tableColumns.jspx

        Show
        Mark Collette added a comment - Apparently Facelets is way better than regular JSP based JSF. The following changes will let the JSP component-showcase function at all. But, the menuPopup menuContext feature won't work in the Table Columns section, without adding the menuContext attribute to a whole bunch of components, which will have to wait a little bit. Subversion 15367 icefaces\core\src\com\icesoft\faces\application\D2DViewHandler.java icefaces\samples\component-showcase\src\com\icesoft\icefaces\samples\showcase\components\menuBar\MenuBarBean.java icefaces\samples\component-showcase\src\com\icesoft\icefaces\samples\showcase\components\table\ColumnsBean.java icefaces\samples\component-showcase\web\inc\components\tableColumns.jspx
        Hide
        Mark Collette added a comment -

        I should mention that the previous commit to D2DViewHandler added a special syntax to component ID resolution. JSF already allows for relative IDs within the current NamingContainer and its children, and absolute IDs from the UIViewRoot. Now you can use a "::" prefix to access relative IDs outside/above the current NamingContainer.

        I added the menuContext attribute to ice:column, ice:columns, ice:dataTable, ice:panelGroup, ice:panelPositioned, ice:panelSeries, ice:panelTabSet, so that it will work fine with JSP, Facelets, and whichever IDEs for code completion.

        Subversion 15416.
        [Whole bunch of files]

        Show
        Mark Collette added a comment - I should mention that the previous commit to D2DViewHandler added a special syntax to component ID resolution. JSF already allows for relative IDs within the current NamingContainer and its children, and absolute IDs from the UIViewRoot. Now you can use a "::" prefix to access relative IDs outside/above the current NamingContainer. I added the menuContext attribute to ice:column, ice:columns, ice:dataTable, ice:panelGroup, ice:panelPositioned, ice:panelSeries, ice:panelTabSet, so that it will work fine with JSP, Facelets, and whichever IDEs for code completion. Subversion 15416. [Whole bunch of files]

          People

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

            Dates

            • Created:
              Updated:
              Resolved: