Skip to content

Instantly share code, notes, and snippets.

@stowball
Last active August 29, 2015 14:18
Show Gist options
  • Select an option

  • Save stowball/afb5c12ad008041d18bb to your computer and use it in GitHub Desktop.

Select an option

Save stowball/afb5c12ad008041d18bb to your computer and use it in GitHub Desktop.
How I'd build a tab function
<div class="js-tabs">
<ul role="tablist" class="u-list-inline">
<li role="presentation"><a role="tab" href="#pane-curl" aria-controls="pane-curl" class="pill">cURL</a></li>
<li role="presentation"><a role="tab" href="#pane-ruby" aria-controls="pane-ruby">Ruby</a></li>
<li role="presentation"><a role="tab" href="#pane-python" aria-controls="pane-python">Python</a></li>
<li role="presentation"><a role="tab" href="#pane-php" aria-controls="pane-php">PHP</a></li>
<li role="presentation"><a role="tab" href="#pane-java" aria-controls="pane-java">Java</a></li>
<li role="presentation"><a role="tab" href="#pane-dotnet" aria-controls="pane-dotnet">.NET</a></li>
</ul>
<div class="tab-panes">
<div role="tabpanel" class="tab-panes__pane" id="pane-curl">1</div>
<div role="tabpanel" class="tab-panes__pane" id="pane-ruby">2</div>
<div role="tabpanel" class="tab-panes__pane" id="pane-python">3</div>
<div role="tabpanel" class="tab-panes__pane" id="pane-php">4</div>
<div role="tabpanel" class="tab-panes__pane" id="pane-java">5</div>
<div role="tabpanel" class="tab-panes__pane" id="pane-dotnet">6</div>
</div>
</div>
$('.js-tabs').each(function() {
var $element = $(this);
var $tabLinks = $element.find('[role="tablist"] > li [role="tab"]');
var $tabPanes = $element.find('.tab-panes:first > .tab-panes__pane');
var setTab = function(tabIndex, $tabLink) {
var $tab = $tabLink ? $tabLink : $tabLinks.eq(tabIndex);
if (!$tab.hasClass('is-active')) {
$tabLinks.removeClass('is-active').attr('aria-selected', false);
$tab.addClass('is-active').attr('aria-selected', true);
}
$tabPanes.removeClass('is-visible').attr({
'aria-hidden': true,
'aria-expanded': false
});
$tabPanes.eq(tabIndex).addClass('is-visible').attr({
'aria-hidden': false,
'aria-expanded': true
});
};
$tabLinks.each(function(tabIndex) {
var $this = $(this);
$this.on('click', function(e) {
e.preventDefault();
setTab(tabIndex, $this);
});
});
setTab(0);
});
@chriswrightdesign
Copy link
Copy Markdown

Eww hijacked by markdown

Anyway this is how I approached the markup. Just trying to write the controller, shouldn't be too difficult.

<section>
        <ul class="nav nav-pills" role="tablist">
            <li role="presentation" aria-controls="panel1" ng-class="{ active: tab.isSet(1) }">
                <a href="#" ng-click="tab.setTab(1)">
                    First
                </a>
            </li>
            <li role="presentation" aria-controls="panel2" ng-class="{ active: tab.isSet(2) }">
                <a href="#" ng-click="tab.setTab(2)">
                    Second
                </a>
            </li>
            <li role="presentation" aria-controls="panel3" ng-class="{ active: tab.isSet(3) }">
                <a href="#" ng-click="tab.setTab(3)">
                    Third
                </a>
            </li>
        </ul>
        <div id="panel1" role="tabpanel" ng-attr-aria-hidden="tab.isSet(1)" class="panel" ng-show="tab.isSet(1)">
            <h4>First</h4>
        </div>
        <div id="panel2" role="tabpanel" ng-attr-aria-hidden="tab.isSet(2)" class="panel" ng-show="tab.isSet(2)">
            <h4>Second</h4>
        </div>
        <div id="panel3" role="tabpanel" ng-attr-aria-hidden="tab.isSet(3)" class="panel" ng-show="tab.isSet(3)">
            <h4>Third</h4>
        </div>
    </section>

@chriswrightdesign
Copy link
Copy Markdown

and early tab controller, not yet setting Aria

app.controller('TabController', function(){
    this.tab = 1;

    this.setTab = function(newValue){
      this.tab = newValue;
    };

    this.isSet = function(tabName){
      return this.tab === tabName;
    };

  });

@chriswrightdesign
Copy link
Copy Markdown

Okay the markup. Keep in mind I'm no angular superstar/ninja/dragon/unicorn person.

    <section>
        <ul class="tabs" role="tablist">
            <li role="presentation" ng-class="{ active: tab.isSet(1) }">
                <a href="#" aria-controls="panel1" ng-attr-aria-selected="tab.isSet(1)" ng-click="tab.setTab(1)">
                    First
                </a>
            </li>
            <li role="presentation" ng-class="{ active: tab.isSet(2) }">
                <a href="#" aria-controls="panel2" ng-attr-aria-selected="tab.isSet(2)" ng-click="tab.setTab(2)">
                    Second
                </a>
            </li>
            <li role="presentation" ng-attr-aria-selected="tab.isSet(1)" ng-class="{ active: tab.isSet(3) }">
                <a href="#" aria-controls="panel3" ng-attr-aria-selected="tab.isSet(3)" ng-click="tab.setTab(3)">
                    Third
                </a>
            </li>
        </ul>
        <div id="panel1" role="tabpanel" ng-attr-aria-hidden="tab.setAriaPanel(1)" class="panel" ng-show="tab.isSet(1)">
            <h4>First</h4>
        </div>
        <div id="panel2" role="tabpanel" ng-attr-aria-hidden="tab.setAriaPanel(2)" class="panel" ng-show="tab.isSet(2)">
            <h4>Second</h4>
        </div>
        <div id="panel3" role="tabpanel" ng-attr-aria-hidden="tab.setAriaPanel(3)" class="panel" ng-show="tab.isSet(3)">
            <h4>Third</h4>
        </div>
    </section>

@chriswrightdesign
Copy link
Copy Markdown

and this is the controller for it. There's some duplication, I'm sure there's a better way to do this so you only just call isSet

 app.controller('TabController', function(){
    this.tab = 1;

    this.setTab = function(newValue){
      this.tab = newValue;
    };

    this.isSet = function(tabName){
      return this.tab === tabName;
    };
    this.setAriaPanel = function(tabName){
      return this.tab !== tabName;
    }

  });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment