Tabs

by rishul matta

HTML

<div id="tabs__container">
  <ul id="tabs__container__navigator">
  

  </ul>
  
  <div id="tabs__container__body">
  </div>

</div>

CSS

.tabs__container__navigator__tab-title {
   padding: 4px 10px;
   cursor: pointer;
   border-bottom: 1px solid #c9c9c9;
 }

.active {
  color: #f8b068;
  border-top: 1px solid #c9c9c9;
  border-right: 1px solid #c9c9c9;
  border-left: 1px solid #c9c9c9;
  border-bottom: 1px solid transparent;
}

 #tabs__container__navigator {
  display: flex;
  list-style-type: none;
 };

JavaScript

/**
	Views
*/
class TabHeader {
  constructor(conatinerId, setActiveTabCallback) {
    this.conatinerId = conatinerId;
    this.setActiveTabCallback = setActiveTabCallback;
        // we are attaching the event handler on the navigator container which is the ul tag and it is already rendered. We will use event delegation to track which tab was clicked.
    this.bindEventHandler();
  }
  
  bindEventHandler() {
  	const navigator = document.getElementById(this.conatinerId);
    navigator.addEventListener('click', this.onClick.bind(this));
  }
  
  onClick({target}) {
		// Object destructuring ES 6
  	const {id} = target;
    this.setActiveTabCallback(parseInt(id));
  }
  
  render(tabArray, activeTabId) {
  	const bodyContainer = document.getElementById(this.conatinerId);
    bodyContainer.innerHTML = tabArray.map((tab, index) => tab.getHtml(activeTabId === index)).join(" ");
  }
}


class TabNavigator {
	constructor(conatinerId, bodyConatinerId) {
    this.activeTabId = 0;
    this.tabHeader = new TabHeader(conatinerId, this.setActiveTabId.bind(this));
    this.tabs = [];

    this.tabBodyHandler = new TabBodyHandler(bodyConatinerId);
  }
  
  addTab(index, title, tabBodyView) {
    const tab = new Tab(index, title, tabBodyView);
  	this.tabs.push(tab);
  }
  
  setActiveTabId(activeTabId) {
  	this.activeTabId = activeTabId;
    this.render();
  }

  
  render() {
  // render header
  	this.tabHeader.render(this.tabs, this.activeTabId);
    
    // render body
    const activeTab = this.tabs[this.activeTabId]; // Id is same as the index of the tab in this implementation.
    this.tabBodyHandler.render(activeTab.getBody());
  }
}

class Tab {
	constructor(index, title, tabBodyView) {
  	this.id = index;
    this.title = title;
    this.tabBody = tabBodyView;
  }
  
  getHtml(isActive) {
  	return `<li id=${this.id} class='tabs__container__navigator__tab-title ${isActive ? "active":""}'> ${this.title} </li>`;
  }
  
  getBody() {
  	return this.tabBody;
 ...