ICEfaces
  1. ICEfaces
  2. ICE-5634

Refactor new Tab component to support putting tab panes in separate forms from the tab control.

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0-Alpha3
    • Fix Version/s: 2.0-Beta2, 2.0.0
    • Component/s: ICE-Components
    • Labels:
      None
    • Environment:
      Sparkle Tab component
    • Affects:
      Documentation (User Guide, Ref. Guide, etc.), Sample App./Tutorial

      Description

      Currently, the Sparkle Tab component can be used in one of two ways:

      1. Entire tab component and all tab panes, and their children, contained in a single form. This is consistent with the ICEfaces 1.x panelTab component.

      2. Tab component itself is not contained in a form at all, and each tab panel can use a form to wrap components it contains as required.

      However, this mechanism requires the use of the so-called "formless" submit feature that was originally part of early Glimmer core.This notion of components not requiring a form is no longer seen as desirable, certainly, at least, the tab should not require it's use.

      Instead, the tab should be refactored such that the tab control itself can reside in one form, while the tab panes may each reside in forms of their own (or contain forms of their own). One way this could be achieved is if the tabPanes are not specified within a Tab component tag (heriarchical), but instead, use a "for=xxx" attribute to specify the tab control that they are associated with. Using this approach, the tab-control can be placed in one form and each tab pane can be placed in another, or all tab panes in one form and the tab control in another, or all in one form, etc.

        Activity

        Hide
        Adnan Durrani added a comment -

        The YUI tab set requires following HTML markup structure to be present.

        <div id="demo" class="yui-navset">
        <ul>
        <li><a href="#tab1"><em>Tab One Label</em></a></li>
        <li><a href="#tab2"><em>Tab Two Label</em></a></li>
        <li><a href="#tab3"><em>Tab Three Label</em></a></li>
        </ul>
        <div class="yui-content">
        <div><p>Tab One Content</p></div>
        <div><p>Tab Two Content</p></div>
        <div><p>Tab Three Content</p></div>
        </div>
        </div>

        Currently Sparkle tabset jsp looks something like this:

        <h:form>
        <ann:tabset id="myTabSet">

        <ann:tab>
        <h:input required="true"/>
        </ann:tab>

        <ann:tab>
        <h:input required="true"/>
        </ann:tab>

        </ann:tabset>
        </h:form>

        And tabset render renders the following markup. Pretty straight forward.
        <form>
        <div id="demo" class="yui-navset">
        <ul class="yui-nav">
        <li><a href="#tab2"><em>Tab Two Label</em></a></li>
        <li><a href="#tab3"><em>Tab Three Label</em></a></li>
        </ul>
        <div class="yui-content">
        <div><input type="text"/></div>
        <div><input type="text"/></div>
        </div>
        </div>
        <form>

        But to support tabset and tab component using "for" notation. I am puzzled about how we are going to render the markup so we can put tabset and tabs in different forms as well as conform with the YUI required markup.

        Let see how the JSP markup will look like with "for" attribute.

        //The Tabset component in its own form
        <h:form>
        <ann:tabset id="myTabSet"/>
        < some_other_components />
        </h:form>

        //The tab component in its own form
        <h:form>
        <ann:tab id="tabOne" for="myTabSet">
        <h:input required="true"/>
        </ann:tab>
        <h:form>

        //The tab component contains forms.
        <ann:tab id="tabTwo" for="myTabSet">
        <h:form>
        <h:input required="true"/>
        <h:form>

        <h:form>
        <h:input required="true"/>
        <h:form>
        </ann:tab>

        So I don't see a way to renderer markup for above JSP, while also conforming the YUI markup? Any idea.

        There is a property on YUI tab component, which allows you to define the element which contains contents of the tab. (e.g.)
        tabOne.set('contentEl', element);

        but If I use above function to reference the tab content element, YUI removes the element from its original location and append it to the tab DIV.

        Show
        Adnan Durrani added a comment - The YUI tab set requires following HTML markup structure to be present. <div id="demo" class="yui-navset"> <ul> <li><a href="#tab1"><em>Tab One Label</em></a></li> <li><a href="#tab2"><em>Tab Two Label</em></a></li> <li><a href="#tab3"><em>Tab Three Label</em></a></li> </ul> <div class="yui-content"> <div><p>Tab One Content</p></div> <div><p>Tab Two Content</p></div> <div><p>Tab Three Content</p></div> </div> </div> Currently Sparkle tabset jsp looks something like this: <h:form> <ann:tabset id="myTabSet"> <ann:tab> <h:input required="true"/> </ann:tab> <ann:tab> <h:input required="true"/> </ann:tab> </ann:tabset> </h:form> And tabset render renders the following markup. Pretty straight forward. <form> <div id="demo" class="yui-navset"> <ul class="yui-nav"> <li><a href="#tab2"><em>Tab Two Label</em></a></li> <li><a href="#tab3"><em>Tab Three Label</em></a></li> </ul> <div class="yui-content"> <div><input type="text"/></div> <div><input type="text"/></div> </div> </div> <form> But to support tabset and tab component using "for" notation. I am puzzled about how we are going to render the markup so we can put tabset and tabs in different forms as well as conform with the YUI required markup. Let see how the JSP markup will look like with "for" attribute. //The Tabset component in its own form <h:form> <ann:tabset id="myTabSet"/> < some_other_components /> </h:form> //The tab component in its own form <h:form> <ann:tab id="tabOne" for="myTabSet"> <h:input required="true"/> </ann:tab> <h:form> //The tab component contains forms. <ann:tab id="tabTwo" for="myTabSet"> <h:form> <h:input required="true"/> <h:form> <h:form> <h:input required="true"/> <h:form> </ann:tab> So I don't see a way to renderer markup for above JSP, while also conforming the YUI markup? Any idea. There is a property on YUI tab component, which allows you to define the element which contains contents of the tab. (e.g.) tabOne.set('contentEl', element); but If I use above function to reference the tab content element, YUI removes the element from its original location and append it to the tab DIV.
        Hide
        Ken Fyten added a comment -

        It seems that we might be able to proceed with this change by supporting the markup in the facelet page as described in the JIRA description, with separate components for the tab control and tab panes, using a "for" attribute to associate the tab panes with a single tab control, and the ability to place the tab control and each tab pane in one or more forms in the page.

        The idea is to translate that page source markup in such a way that when rendered in the client by the YUI component, the component is configured correctly to display the correct tab panes in the correct tabs, etc. For the form issue, the tab-control submits could be dynamically mapped into the form control that it "belongs" to in the original page markup, even though the component itself is not rendered inside that form on the client page. The same thing would done for the tab panes, any submits triggered within a tab pane would be associated into the correct form dynamically, even though the component itself may not reside inside the form tag in the browser dom.

        Please investigate the feasibility of this approach.

        Show
        Ken Fyten added a comment - It seems that we might be able to proceed with this change by supporting the markup in the facelet page as described in the JIRA description, with separate components for the tab control and tab panes, using a "for" attribute to associate the tab panes with a single tab control, and the ability to place the tab control and each tab pane in one or more forms in the page. The idea is to translate that page source markup in such a way that when rendered in the client by the YUI component, the component is configured correctly to display the correct tab panes in the correct tabs, etc. For the form issue, the tab-control submits could be dynamically mapped into the form control that it "belongs" to in the original page markup, even though the component itself is not rendered inside that form on the client page. The same thing would done for the tab panes, any submits triggered within a tab pane would be associated into the correct form dynamically, even though the component itself may not reside inside the form tag in the browser dom. Please investigate the feasibility of this approach.
        Hide
        Adnan Durrani added a comment - - edited

        We can use dynamic form for "tabset" component but it can not be used with tab component. It is due to the fact that a tab component can have input type of components and input component expect that they are enclosed inside a form. We can change our findForm() function to use dynamic form for tabs, it will fix ICEFaces components but third part components will not be able to make a submit when inside a tab component which is using dynamic reference of form.

        Finally I came to a conclusion that, if we make following rule then we can achieve our goal.

        Rule: If a "tab" component is using "for" attribute and its not a child of a tabSet, then the tab component can not be put inside a form, however it can have one or more forms.

        If we follow above rule then I am sure that we can offer following Markup.

        Example 1: tab and tabset is inside a form. Same as current behaviour.

        <h:body>
        <ice:form>
        <ann:tabset>

        <ann:tab>
        <h:input required="true"/>
        </ann:tab>

        <ann:tab>
        <h:input required="true"/>
        </ann:tab>

        </ann:tabset>
        <ice:form>
        </h:body>

        Example 2: tabset is inside a separate form
        <h:body>
        <ice:form>
        <ann:tabset id="myTabSet"/>
        <ice:form>

        //tab has its own forms
        <ann:tab label="Tab One" for="myTabSet" >

        <ice:form>
        <h:input required="true"/>
        <ice:form>

        <ice:form>
        <h:input required="true"/>
        <ice:form>

        </ann:tab>

        //tab has its own form for contents as well as label facet.
        <ann:tab for="myTabSet">

        <f:facet name="label">
        <ice:form>
        <h:outputText value="Tab Two"/>
        <h:input required="true"/>
        <ice:form>
        </f:facet>

        <ice:form>
        <h:input required="true"/>
        <ice:form>

        </ann:tab>
        <h:body>

        Example 3: This should not be allowed, and should throw a error message.

        <ice:form>
        <ann:tabset id="myTabSet">
        <ice:form>

        //ERROR (tab component can not be inside a form when using for attribute)
        <ice:form>
        <ann:tab label="Tab One" for="myTab" >
        <h:input required="true"/>
        </ann:tab>
        <ice:form>

        Show
        Adnan Durrani added a comment - - edited We can use dynamic form for "tabset" component but it can not be used with tab component. It is due to the fact that a tab component can have input type of components and input component expect that they are enclosed inside a form. We can change our findForm() function to use dynamic form for tabs, it will fix ICEFaces components but third part components will not be able to make a submit when inside a tab component which is using dynamic reference of form. Finally I came to a conclusion that, if we make following rule then we can achieve our goal. Rule: If a "tab" component is using "for" attribute and its not a child of a tabSet, then the tab component can not be put inside a form, however it can have one or more forms. If we follow above rule then I am sure that we can offer following Markup. Example 1: tab and tabset is inside a form. Same as current behaviour. <h:body> <ice:form> <ann:tabset> <ann:tab> <h:input required="true"/> </ann:tab> <ann:tab> <h:input required="true"/> </ann:tab> </ann:tabset> <ice:form> </h:body> Example 2: tabset is inside a separate form <h:body> <ice:form> <ann:tabset id="myTabSet"/> <ice:form> //tab has its own forms <ann:tab label="Tab One" for="myTabSet" > <ice:form> <h:input required="true"/> <ice:form> <ice:form> <h:input required="true"/> <ice:form> </ann:tab> //tab has its own form for contents as well as label facet. <ann:tab for="myTabSet"> <f:facet name="label"> <ice:form> <h:outputText value="Tab Two"/> <h:input required="true"/> <ice:form> </f:facet> <ice:form> <h:input required="true"/> <ice:form> </ann:tab> <h:body> Example 3: This should not be allowed, and should throw a error message. <ice:form> <ann:tabset id="myTabSet"> <ice:form> //ERROR (tab component can not be inside a form when using for attribute) <ice:form> <ann:tab label="Tab One" for="myTab" > <h:input required="true"/> </ann:tab> <ice:form>
        Hide
        Adnan Durrani added a comment -

        As per our discussion, I have created a "tabSetController" component. Which refer its tabset using "for" attribute.(e.g.)

        <ann:tabset id="myTabset">
        ..........
        <ann:tabset>

        <h:form>
        <ann:tabSetController for="myTabSet"/>
        </h:form>

        This fix also make sure that there should be only one filed per form. Regardless of number of tabset components inside a form.

        Command: Commit
        Modified: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\resources\org.icefaces.component.tab\tabset.js
        Adding: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\src\org\icefaces\component\tab\TabSetController.java
        Adding: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\src\org\icefaces\component\tab\TabSetControllerMeta.java
        Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\resources\org.icefaces.component.tab\tabset.js
        Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\src\org\icefaces\component\tab\TabSetControllerMeta.java
        Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\src\org\icefaces\component\tab\TabSetController.java
        Completed: At revision: 21416

        Show
        Adnan Durrani added a comment - As per our discussion, I have created a "tabSetController" component. Which refer its tabset using "for" attribute.(e.g.) <ann:tabset id="myTabset"> .......... <ann:tabset> <h:form> <ann:tabSetController for="myTabSet"/> </h:form> This fix also make sure that there should be only one filed per form. Regardless of number of tabset components inside a form. Command: Commit Modified: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\resources\org.icefaces.component.tab\tabset.js Adding: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\src\org\icefaces\component\tab\TabSetController.java Adding: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\src\org\icefaces\component\tab\TabSetControllerMeta.java Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\resources\org.icefaces.component.tab\tabset.js Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\src\org\icefaces\component\tab\TabSetControllerMeta.java Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\src\org\icefaces\component\tab\TabSetController.java Completed: At revision: 21416
        Hide
        Adnan Durrani added a comment -

        Its working fine with current glimmer.

        Show
        Adnan Durrani added a comment - Its working fine with current glimmer.
        Hide
        Adnan Durrani added a comment -

        Client side state machine added.

        Command: Commit
        Modified: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\resources\org.icefaces.component.tab\tabset.js
        Modified: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\resources\org.icefaces.component.util\component.js
        Modified: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\showcase\test\src\org\icefaces\tabset\Bean.java
        Adding: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\showcase\test\web\clientside_tabset.xhtml
        Modified: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\showcase\test\web\index.html
        Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\showcase\test\src\org\icefaces\tabset\Bean.java
        Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\showcase\test\web\index.html
        Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\resources\org.icefaces.component.tab\tabset.js
        Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\showcase\test\web\clientside_tabset.xhtml
        Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\resources\org.icefaces.component.util\component.js
        Completed: At revision: 21499

        Show
        Adnan Durrani added a comment - Client side state machine added. Command: Commit Modified: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\resources\org.icefaces.component.tab\tabset.js Modified: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\resources\org.icefaces.component.util\component.js Modified: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\showcase\test\src\org\icefaces\tabset\Bean.java Adding: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\showcase\test\web\clientside_tabset.xhtml Modified: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\showcase\test\web\index.html Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\showcase\test\src\org\icefaces\tabset\Bean.java Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\showcase\test\web\index.html Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\resources\org.icefaces.component.tab\tabset.js Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\showcase\test\web\clientside_tabset.xhtml Sending content: D:\work\development\head\svn\ossrepo\icefaces\scratchpads\sparkle\component\resources\org.icefaces.component.util\component.js Completed: At revision: 21499

          People

          • Assignee:
            Adnan Durrani
            Reporter:
            Ken Fyten
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: