Home > Blockchain >  Why doesn't my click handler show the correct table element?
Why doesn't my click handler show the correct table element?

Time:10-12

I have JavaScript code which on button click shows its table. I have 4 buttons (and tables, obviously). Probably there will be more, so making function to each one of them will be bad idea. That being said, I made this code below to slightly minimize the amount of code. But, it doesn't work, and I don't quite understand why.

document.addEventListener('DOMContentLoaded', function() {
  const tab1 = document.getElementById('tab1');
  const tab2 = document.getElementById('tab2');
  const tab3 = document.getElementById('tab3');
  const tab4 = document.getElementById('tab4');
  const currentTable = ".table";
  const tables = Array.from(document.querySelectorAll(currentTable))
  const table1 = document.querySelector('.table1');
  const table2 = document.querySelector('.table2');
  const table3 = document.querySelector('.table3');
  const table4 = document.querySelector('.table4');

  //this doesnt work
  function showTable(e) {

    const target = e.target;

    if (!target || !target.matches(currentTable)) {
      return;
    }

    tables.forEach(elem => elem.classList.remove('active'));
    tables.forEach(elem => elem.classList.remove('op'));
    e.target.classList.add('active');
    setTimeout(function() {
      e.target.classList.add('op');
    }, 20);
  };

  tab1.addEventListener('click', showTable(table1));
  tab2.addEventListener('click', showTable(table2));
  tab3.addEventListener('click', showTable(table3));
  tab4.addEventListener('click', showTable(table4));
});

//this one for buttons
document.addEventListener('DOMContentLoaded', function() {
  const selector = '.table_option';
  const elems = Array.from(document.querySelectorAll(selector));
  const navigation = document.querySelector('.table-nav');

  function makeActive(e) {
    const target = e.target;

    if (!target || !target.matches(selector)) {
      return;
    }

    elems.forEach(elem => elem.classList.remove('active'));
    e.target.classList.add('active');
  };

  navigation.addEventListener('click', makeActive);
});
.table_container {
  display: flex;
  width: 100%;
}

.table_content-left {
  width: 30%;
  margin-top: 50px;
}

.table_content-left .table_option {
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
}

.table_content-left .table-nav li:not(:last-child) {
  margin-bottom: 10px;
}

.table_content-left .table_option.active {
  color: #eb5e28;
  border-left: 2px solid #252422;
  padding: 10px 15px;
  transition: all 0.8s;
}

.table_content-right {
  width: 70%;
}

.table {
  display: none;
  opacity: 0;
  transition: opacity 900ms;
}

.op {
  opacity: 1;
}

.table_title {
  font-size: 24px;
  font-weight: 700;
}

.table_content table {
  border-collapse: collapse;
}

.table_content td,
.table_content th {
  text-align: left;
  padding: 8px;
  width: 100%;
  font-weight: 600;
}

.table_content td {
  background-color: #ccc5b9;
}

.table_content th:first-child {
  padding: 8px 0px;
}

.table_content td:nth-child(2n 1) {
  background-color: #403d39;
  color: #fff;
}

.table_content tr:nth-child(even) {
  background-color: #ccc5b9;
  color: #fff;
}

.table_content tr:nth-child(even) td:nth-child(1n 1) {
  background-color: #403d39;
}

.table_content tr:nth-child(even) td:nth-child(2n 1) {
  background-color: #ccc5b9;
  color: #252422;
}

.active {
  display: block;
}
<div >
  <div >
    <ul role="list" >
      <li><a  id="tab1">button1</a></li>
      <li><a  id="tab2">button2</a></li>
      <li><a  id="tab3">button3</a></li>
      <li><a  id="tab4">button4</a></li>
    </ul>
  </div>
  
  <div >
    <div >
      <div >1</div>
      <table  cellspacing="0">
        <tr>
          <th>Lorem</th>
          <th>5</th>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
      </table>
    </div>
    
    <div >
      <div >2</div>
      <table  cellspacing="0">
        <tr>
          <th>Lorem</th>
          <th>5</th>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
      </table>
    </div>
    
    <div >
      <div >3</div>
      <table  cellspacing="0">
        <tr>
          <th>Lorem</th>
          <th>5</th>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
      </table>
    </div>
    
    <div >
      <div >4</div>
      <table  cellspacing="0">
        <tr>
          <th>Lorem</th>
          <th>5</th>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
      </table>
    </div>
  </div>
</div>

Where am I wrong? Can someone point me to the problem I am facing?

CodePudding user response:

I like to take a simple index-based approach to things like this. If that doesn't suit, you could add indices to the tables using data attributes which correspond to tab index.

Some other tips...

  • You were creating event listeners in every call of showTable(). That would result in a pile of event handlers you don't want.
  • You were using a rather roundabout way to collect elements (with Array.from(). That's not needed.
  • Multiple classes can be added and removed as a list.

document.addEventListener('DOMContentLoaded', function() {
  const tabs = document.querySelectorAll('.table_option');
  const tables = document.querySelectorAll('.table');

  tabs.forEach(tab => {
    tab.addEventListener('click', e => {
      const tabEl = e.currentTarget.parentNode;
      const tabIndex = [...tabEl.parentNode.children].indexOf(tabEl);

      showTable(tabIndex);
    });
  });

  const showTable = index => {
    tables.forEach(elem => elem.classList.remove('active', 'op'));
    tables[index].classList.add('active');

    setTimeout(() => {
      tables[index].classList.add('op');
    }, 20);

    tabs.forEach(elem => elem.classList.remove('active', 'op'));
    tabs[index].classList.add('active');
  }
});
.table_container {
  display: flex;
  width: 100%;
}

.table_content-left {
  width: 30%;
  margin-top: 50px;
}

.table_content-left .table_option {
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
}

.table_content-left .table-nav li:not(:last-child) {
  margin-bottom: 10px;
}

.table_content-left .table_option.active {
  color: #eb5e28;
  border-left: 2px solid #252422;
  padding: 10px 15px;
  transition: all 0.8s;
}

.table_content-right {
  width: 70%;
}

.table {
  display: none;
  opacity: 0;
  transition: opacity 900ms;
}

.op {
  opacity: 1;
}

.table_title {
  font-size: 24px;
  font-weight: 700;
}

.table_content table {
  border-collapse: collapse;
}

.table_content td,
.table_content th {
  text-align: left;
  padding: 8px;
  width: 100%;
  font-weight: 600;
}

.table_content td {
  background-color: #ccc5b9;
}

.table_content th:first-child {
  padding: 8px 0px;
}

.table_content td:nth-child(2n 1) {
  background-color: #403d39;
  color: #fff;
}

.table_content tr:nth-child(even) {
  background-color: #ccc5b9;
  color: #fff;
}

.table_content tr:nth-child(even) td:nth-child(1n 1) {
  background-color: #403d39;
}

.table_content tr:nth-child(even) td:nth-child(2n 1) {
  background-color: #ccc5b9;
  color: #252422;
}

.active {
  display: block;
}
<div >
  <div >
    <ul role="list" >
      <li><a  id="tab1">button1</a></li>
      <li><a  id="tab2">button2</a></li>
      <li><a  id="tab3">button3</a></li>
      <li><a  id="tab4">button4</a></li>
    </ul>
  </div>
  
  <div >
    <div >
      <div >1</div>
      <table  cellspacing="0">
        <tr>
          <th>Lorem</th>
          <th>5</th>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
      </table>
    </div>
    
    <div >
      <div >2</div>
      <table  cellspacing="0">
        <tr>
          <th>Lorem</th>
          <th>5</th>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
      </table>
    </div>
    
    <div >
      <div >3</div>
      <table  cellspacing="0">
        <tr>
          <th>Lorem</th>
          <th>5</th>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
      </table>
    </div>
    
    <div >
      <div >4</div>
      <table  cellspacing="0">
        <tr>
          <th>Lorem</th>
          <th>5</th>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
        <tr>
          <td>Lorem</td>
          <td>5</td>
        </tr>
      </table>
    </div>
  </div>
</div>

  • Related