Skip navigation
Currently Being Moderated

How to disable a tab in a spark tab bar?

Jun 1, 2010 1:06 PM

I have a spark tab bar linked to a ViewStack.  In olden days, IIRC,  setting the enabled property of a viewstack member would set the corresponding tab inactive.  However, if I try that now, the tab control is still active, but the contents of the viewstack for that tab is indeed disabled.

 

To reiterate:  I want certain tabs in a spark tab bar to be disabled (i.e. unable to be chosen and displaying their disabled skin state).

 

 

<s:TabBar id="tabBar" dataProvider="{tabStack}" x="70" y="91" skinClass="CalculatorTabsSkin"/>


<mx:ViewStack id="tabStack" width="100%" height="100%" creationPolicy="all" change="tabStack_changeHandler(event)">
                    
     <s:NavigatorContent id="nc1" label="PIERS">
     <comp:Tab1 id="tab1"  width="100%" height="100%" continue="tab1_continueHandler(event)" />
     </s:NavigatorContent>
                    
     <s:NavigatorContent id="nc2" label="FOOTINGS">
     <comp:Tab2 id="tab2" width="100%" height="100%" continue="tab2_continueHandler(event)" numberOfPiers="{totalNumberPiers}" />
     </s:NavigatorContent>
                    
     <s:NavigatorContent id="nc3" label="BAGS OR TRUCK?">
     <comp:Tab3 id="tab3"  width="100%" height="100%" totalCubicYards="{totalCubicYards}" totalNumberBags="{totalNumberBags}" />
     </s:NavigatorContent>
                    
</mx:ViewStack>
 

 
Replies
  • Currently Being Moderated
    Aug 17, 2010 11:59 AM   in reply to Handycam

    I'm faced with the same situation. Instead of enabling and disabling the tab, I've been forced to remove the offending tab when not needed.

     

    To do this in my case was simple (it was only 1 tab)

     

    I built the "removable tab's" NavigatorContent object in declarations;

     

    private function setTab(tf:Boolean):void

    {

        if (tf){

     

              viewStack.addChildAt( navContent, 0);

        } else{

              viewStack.removeChildAt(0);

    }

     

    This doesn't "resolve" my issue; but it has allowed me to continue on with development until Adobe addresses this oversight.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 18, 2011 7:16 AM   in reply to Handycam

    I solved it by binding the ButtonBarButton's enabled property to the NavigatorContent's enable property inside the TabBarSkin:

     

    <s:Skin 
        xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:fb="http://ns.adobe.com/flashbuilder/2009"     
        alpha.disabled="0.5">
        
        <fx:Metadata>
            <![CDATA[ 
            /** 
             * @copy spark.skins.spark.ApplicationSkin#hostComponent
             */
            [HostComponent(spark.components.TabBar)]
            ]]>
        </fx:Metadata> 
        
        <fx:Script  fb:purpose="styling" >
            ... the AS code ...         
        </fx:Script>
        
        <s:states>
            <s:State name="normal" />
            <s:State name="disabled" />
        </s:states>
        
        <!--- @copy spark.components.SkinnableDataContainer#dataGroup -->
        <s:DataGroup id="dataGroup" width="100%" height="100%">
            <s:layout>
                <s:ButtonBarHorizontalLayout gap="-1"/>
            </s:layout>
            <s:itemRenderer>
                <fx:Component>
                    <s:ButtonBarButton skinClass="skins.tabBar.ConsusTabBarButtonSkin" enabled="{data.enabled}"/>
                </fx:Component>
            </s:itemRenderer>
        </s:DataGroup>
        
    </s:Skin>
    

     

    Hope it helps,

    Jorge

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 9, 2011 12:44 AM   in reply to Handycam

    For those who want an working answer for Flex 4.5 (probably Flex 4 also).  I finally figured out a solution.  It feels like a hack to me, but it's working for me.  Here's a simplified example.

     

     

     

        <!-- component that has the the TabBar in it... -->

     

        <fx:Script>

            <![CDATA[

        //imports here

     

        import mx.core.UIComponent;

     

        //other imports

     

        private function setTabEnabled(index:int,enabled:Boolean):void{

                  var theTab:UIComponent = theTabBar.dataGroup.getElementAt(index) as UIComponent;

                  if(theTab){theTab.enabled = enabled;}

        }

        ]]>

        </fx:Script>

     

        <s:TabBar id="theTabBar"

                  dataProvider="{viewStack}"/>

     

        <mx:ViewStack id="viewStack">

            <s:NavigatorContent label="0th Tab">

                <!-- ...Content -->

            </s:NavigatorContent>

            <s:NavigatorContent label="1st Tab">

                <!-- ...Content -->

            </s:NavigatorContent>

            <s:NavigatorContent label="2nd Tab">

                <!-- ...Content -->

            </s:NavigatorContent>

        </mx:ViewStack>

     

        <!-- rest of the component that has the the TabBar in it... -->

     

     

    Then you just call `setTabEnabled(theTabIndex,trueFalse)` in an event handler related to whatever decides why the tab is, or isn't, enabled.

     

     

    I *should* extend the TabBar to support this, but I've already spent enough time trying to figure it out.

     

     

    Happy Coding =D

     
    |
    Mark as:
  • Currently Being Moderated
    Jan 19, 2012 4:29 PM   in reply to Chaos7703

    Addendum:

    Literally two minutes after I got back to actually working, I found a more "elegant" solution.  I posted it elsewhere, but I guess I forgot to share it here. =/ So I thought I'd update this real quick. =)

     

    If you apply a custom skinClass to your tab bar you can bind the tab.enabled property just like you'd expect/want.

     

    <!-- some component that has the TabBar in it... -->

       

        <fx:Script>

             <![CDATA[

        [Bindable] private var tab2IsReady:Boolean = false;


     

        private function checkCriteria():void{

             tab2IReady = someOtherThing.isFinished;//Boolean

        }

        ]]>

        </fx:Script>


     

    <s:TabBar id="theTabBar"

       dataProvider="{viewStack}"

       skinClass="skins.CustomTabBarSkin"/>


     

    <mx:ViewStack id="viewStack">

          <s:NavigatorContent label="Tab index 0">

               <!-- Your first tab's content -->

          </s:NavigatorContent>

     

          <s:NavigatorContent label="Tab index 1" enabled="{tab2IsReady}">

               <!-- Your second tab's content -->

          </s:NavigatorContent>

    </mx:ViewStack>

     

    <!-- rest of the component that has the the TabBar in it... -->

     

     

    When you type "skinClass" use the auto complete to generate the custom skin (named whatever you want).

    The generated code will appear like below (I left out the Script tag).

     

    <?xml version="1.0" encoding="utf-8"?>

    <!-- skins/CustomTabBarSkin.mxml


    ...

    Adobe's copyright & doc comments

    ...

     

    -->


    <s:Skin

        xmlns:fx="http://ns.adobe.com/mxml/2009"

        xmlns:s="library://ns.adobe.com/flex/spark"

        xmlns:fb="http://ns.adobe.com/flashbuilder/2009"    

        alpha.disabled="0.5">

       

        <fx:Metadata>

            <![CDATA[

            /**

             * @copy spark.skins.spark.ApplicationSkin#hostComponent

             */

            [HostComponent("spark.components.TabBar")]

            ]]>

        </fx:Metadata>


     

          <!-- optional Script tag here -->

     

     

        <s:states>

            <s:State name="normal" />

            <s:State name="disabled" />

        </s:states>

       

        <!--- @copy spark.components.SkinnableDataContainer#dataGroup -->

        <s:DataGroup id="dataGroup" width="100%" height="100%">

            <s:layout>

                <s:ButtonBarHorizontalLayout gap="-1"/>

            </s:layout>

            <s:itemRenderer>

                <fx:Component>

                    <s:ButtonBarButton skinClass="spark.skins.spark.TabBarButtonSkin" />

                </fx:Component>

            </s:itemRenderer>

        </s:DataGroup>

       

    </s:Skin>

    <!-- End skins/CustomTabBarSkin.mxml -->

     

    Then add the enabled property to the ButtonBarButton & bind it to data.enabled in your skin class.

    Change:

               <fx:Component>

               <s:ButtonBarButton skinClass="spark.skins.spark.TabBarButtonSkin" />

           </fx:Component>

    To:

               <fx:Component>

               <s:ButtonBarButton skinClass="spark.skins.spark.TabBarButtonSkin"

                    enabled="{data.enabled}" />

         </fx:Component>

     

    Then any <s:NavigatorContent/> used with a TabBar using that skin will respect the enabled property and do exactly what you expect & want (be enabled when true, & disabled when false).

     

    Hope this helps some people.  WIsh I'd remembered to re-post it here when I first figured it out.

     

    Happy Coding! =D

    Todd

     

    Message was edited by: Chaos7703 - Just made one statement a bit more explicit.

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points