How to switch through tabs in bulma
Asked Answered
B

5

11

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

Brammer answered 1/12, 2017 at 10:34 Comment(0)
E
19

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>
Esperance answered 1/12, 2017 at 10:50 Comment(6)
this doesn't seem to work if you have a form input within one of the areasFormality
@Formality Did you try changing #tab-content p.is-active to #tab-content form.is-active?Esperance
are you have solution without using jquery ?Jurdi
@samnikzad AddedEsperance
This is high quality JS for stackoverflow! Great example, thank youTijuanatike
Would it be possible to add a smoothing transition effect between each page?Like on this page genesilico.pl/DNAmoreDB/searchadvanceLook
M
4

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;
    }
  }
Merilynmeringue answered 17/8, 2018 at 7:47 Comment(0)
B
1

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";
    }
Bracket answered 11/5, 2020 at 21:42 Comment(0)
P
1

If you are using alpine.js you could do it by:

<div class="tabs is-toggle" x-data="{ one: true, 
                                      two: false, 
                                      three: false,
                                     }">
     <ul>
        <li x-bind:class="one ? 'is-active' : ''" >         
         <a x-on:click="one = true; two = false; three = false"
            >
           
           <p>FIRST</p>
           
         </a>
       </li>
       <li x-bind:class="two ? 'is-active' : ''" >
         <a x-on:click="two = true; one = false; three = false">
           
           <p>SECOND</p>
           
         </a>
       </li>
       <li x-bind:class="three ? 'is-active' : ''" >
         <a x-on:click="three = true; one = false; two = false">
           
           <p>THIRD</p> 
          
         </a>
       </li>
     </ul>
  </div>

Most simple solution!

Phelgen answered 2/3 at 3:37 Comment(0)
M
0

import React, { useState } from 'react';
import styled from 'styled-components';

const TabWrapper = styled.div``;

const allTypes = ['New Arrivals', 'Best Sellers', 'On Sale'];

const ArrivalType = () => {
  const [active, setActive] = useState(allTypes[0]);
  return (
    <TabWrapper className="tabs is-centered">
      <ul>
        {allTypes.map((type) => (
          <li
            className={active === type && 'is-active'}
            key={type}
            aria-hidden
            onClick={() => setActive(type)}>
            <a>{type}</a>
          </li>
        ))}
      </ul>
    </TabWrapper>
  );
};

export default ArrivalType;


Mccready answered 14/12, 2021 at 19:31 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Peipus

© 2022 - 2024 — McMap. All rights reserved.