Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to switch through tabs in bulma

Tags:

html

bulma

I' trying to implement a nav tab panel to switch through tabs. I went through Bulma documentation but couldn't find any. Here's the sample code

<div class="tabs is-toggle is-fullwidth">
  <ul>
    <li class="is-active">
      <a>
        <span class="icon is-small"><i class="fa fa-image"></i></span>
        <span>Pictures</span>
      </a>
      <p>
      Here goes pictures
      </p>
    </li>
    <li>
      <a>
        <span class="icon is-small"><i class="fa fa-music"></i></span>
        <span>Music</span>
      </a>
       <p>
      Here goes music
      </p>
    </li>
    <li>
      <a>
        <span class="icon is-small"><i class="fa fa-film"></i></span>
        <span>Videos</span>
      </a>
       <p>
      Here goes music
      </p>
    </li>
    <li>
      <a>
        <span class="icon is-small"><i class="fa fa-file-text-o"></i></span>
        <span>Documents</span>
      </a>
       <p>
      Here goes music
      </p>
    </li>
  </ul>
</div>

Here' the JSfiddle I'm trying to work on. I want "Here goes picture" to only show up when pictures tab is active and vice-versa

like image 616
Saikiran Avatar asked Dec 01 '17 10:12

Saikiran


3 Answers

You should separate the tabs and the tab content into separate containers. You can match a tab to the correct content using the data attribute.

Set the tab content to be hidden by default, unless it has the class active. When you click on a tab, the corresponding tab content receives active.

You can update the fiddle/snippet below with more appropriate elements and class/id names as you need.

fiddle

$(document).ready(function() {
  $('#tabs li').on('click', function() {
    var tab = $(this).data('tab');

    $('#tabs li').removeClass('is-active');
    $(this).addClass('is-active');

    $('#tab-content p').removeClass('is-active');
    $('p[data-content="' + tab + '"]').addClass('is-active');
  });
});
#tab-content p {
  display: none;
}

#tab-content p.is-active {
  display: block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.1/css/bulma.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tabs is-toggle is-fullwidth" id="tabs">
  <ul>
    <li class="is-active" data-tab="1">
      <a>
        <span class="icon is-small"><i class="fa fa-image"></i></span>
        <span>Pictures</span>
      </a>
    </li>
    <li data-tab="2">
      <a>
        <span class="icon is-small"><i class="fa fa-music"></i></span>
        <span>Music</span>
      </a>
    </li>
    <li data-tab="3">
      <a>
        <span class="icon is-small"><i class="fa fa-film"></i></span>
        <span>Videos</span>
      </a>
    </li>
    <li data-tab="4">
      <a>
        <span class="icon is-small"><i class="fa fa-file-text-o"></i></span>
        <span>Documents</span>
      </a>
    </li>
  </ul>
</div>
<div id="tab-content">
  <p class="is-active" data-content="1">
    Pictures
  </p>
  <p data-content="2">
    Music
  </p>
  <p data-content="3">
    Videos
  </p>
  <p data-content="4">
    Documents
  </p>
</div>

Example without jQuery

const TABS = [...document.querySelectorAll('#tabs li')];
const CONTENT = [...document.querySelectorAll('#tab-content p')];
const ACTIVE_CLASS = 'is-active';

function initTabs() {
    TABS.forEach((tab) => {
      tab.addEventListener('click', (e) => {
        let selected = tab.getAttribute('data-tab');
        updateActiveTab(tab);
        updateActiveContent(selected);
      })
    })
}

function updateActiveTab(selected) {
  TABS.forEach((tab) => {
    if (tab && tab.classList.contains(ACTIVE_CLASS)) {
      tab.classList.remove(ACTIVE_CLASS);
    }
  });
  selected.classList.add(ACTIVE_CLASS);
}

function updateActiveContent(selected) {
  CONTENT.forEach((item) => {
    if (item && item.classList.contains(ACTIVE_CLASS)) {
      item.classList.remove(ACTIVE_CLASS);
    }
    let data = item.getAttribute('data-content');
    if (data === selected) {
      item.classList.add(ACTIVE_CLASS);
    }
  });
}

initTabs();
#tab-content p {
  display: none;
}

#tab-content p.is-active {
  display: block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.1/css/bulma.css" rel="stylesheet" />
<div class="tabs is-toggle is-fullwidth" id="tabs">
  <ul>
    <li class="is-active" data-tab="1">
      <a>
        <span class="icon is-small"><i class="fa fa-image"></i></span>
        <span>Pictures</span>
      </a>
    </li>
    <li data-tab="2">
      <a>
        <span class="icon is-small"><i class="fa fa-music"></i></span>
        <span>Music</span>
      </a>
    </li>
    <li data-tab="3">
      <a>
        <span class="icon is-small"><i class="fa fa-film"></i></span>
        <span>Videos</span>
      </a>
    </li>
    <li data-tab="4">
      <a>
        <span class="icon is-small"><i class="fa fa-file-text-o"></i></span>
        <span>Documents</span>
      </a>
    </li>
  </ul>
</div>
<div id="tab-content">
  <p class="is-active" data-content="1">
    Pictures
  </p>
  <p data-content="2">
    Music
  </p>
  <p data-content="3">
    Videos
  </p>
  <p data-content="4">
    Documents
  </p>
</div>
like image 141
sol Avatar answered Oct 26 '22 05:10

sol


Another solution without the need of data attributes (using index).

HTML:

  <div class="column is-12 tabs is-medium">
    <ul>
      <li class="is-active"><a>Tab 1</a></li>
      <li><a>Tab 2</a></li>
    </ul>
  </div>
  <div class="column is-12 tabs-content">
    <div class="tab-content is-active">
      <p>Content 1</p>
    </div>
    <div class="tab-content">
      <p>Content 2</p>
    </div>
  </div>

JS (jQuery):

     $('.tabs').each(function(index) {
      var $tabParent = $(this);
      var $tabs = $tabParent.find('li');
      var $contents = $tabParent.next('.tabs-content').find('.tab-content');

      $tabs.click(function() {
        var curIndex = $(this).index();
        // toggle tabs
        $tabs.removeClass('is-active');
        $tabs.eq(curIndex).addClass('is-active');
        // toggle contents
        $contents.removeClass('is-active');
        $contents.eq(curIndex).addClass('is-active');
      });
    });

SCSS:

  .tab-content {
    display: none;

    &.is-active {
      display: block;
    }
  }
like image 31
Alchem Avatar answered Oct 26 '22 06:10

Alchem


Here is the code for Angular CLI in case anyone need that, copy an paste and it should work. (havn't checked the html)

heres is the html:

<div class="container">
    
    <section class="box" >
          <section class="hero is-dark">
              <div class="hero-body">
                <div class="container has-text-centered">
                    <h1 class="title">
                        head title here
                    </h1>
                </div>
              </div> 

              <div class="hero-foot">
                  <nav class="tabs is-boxed is-fullwidth is-medium">
                      <div class="container">
                      <ul>
                          <li class="tab is-active" (click)="openTab($event, 'id_tab_1')"><a >tab 1 title</a></li>
                          <li class="tab" (click)="openTab($event, 'id_tab_2')"><a >tab 2 title</a></li>
                          <li class="tab" (click)="openTab($event, 'id_tab_3')"><a >tab 3 title</a></li>
                      </ul>
                      </div>
                  </nav>
              </div>
          </section>        
          <div class="container section">
              <div id="id_tab_1" class="content-tab">
                  <div>
                      content here
                  </div>
              </div>
              <div id="id_tab_2" class="content-tab" style="display:none">
                  <div>
                      content here
                  </div>
              </div>
              <div id="id_tab_3" class="content-tab" style="display:none">
                  <div>
                     content here
                  </div>
              </div>
          </div>
      </section>
</div>

Here is the typescript for your component, no need to create variables with this version, it's basically just as you would do it in javascript. This could be adapted better for Angular using viewchild and such.

   
   
   openTab(event: any, tabName) {
      var i, x, tablinks;
      x = document.getElementsByClassName("content-tab");
      for (i = 0; i < x.length; i++) {
          x[i].style.display = "none";
      }
      tablinks = document.getElementsByClassName("tab");
      for (i = 0; i < x.length; i++) {
          tablinks[i].className = tablinks[i].className.replace(" is-active", "");
      }
      document.getElementById(tabName).style.display = "block";
      event.currentTarget.className += " is-active";
    }
like image 1
Luca De Acha Avatar answered Oct 26 '22 07:10

Luca De Acha