Home > Net >  Show / Hide HTML Table rows using Javascript
Show / Hide HTML Table rows using Javascript

Time:08-22

I don't know why something this simple isn't working.

<table id="df">
  <tr><td>foo</td></tr>
  <tr><td>bar</td></tr>
  <tr><td>[email protected]</td></tr>
</table>

Say we have an HTML table. How would I hide all rows / only some rows, and vice versa, how would I show all rows / only some rows?

Things that aren't working:

//one

document.getElementByTagName('table').style.display = "none";

//two

var rows = document.getElementsByTagName("table")[0].rows;
rows.hidden = false;

//three

var table = document.getElementById("df");
table.style = "display:table-row";

Thanks in advance

CodePudding user response:

You can select row n using nth-child css selector

const table = document.querySelector("#df tbody")

const toggleRow = (rowIndex = 0) => {
  if (table.childElementCount < rowIndex) return

  const row = table.querySelector(`:nth-child(${rowIndex})`)

  row.style.display = row.style.display === 'none' ? 'block' : 'none'
}

toggleRow(1) // Hide first row
toggleRow(2) // Hide second row
toggleRow(4) // Will not hide because because table only have 3 rows
toggleRow(2) // Show second row
<table id="df">
  <tbody>
    <tr>
      <td>foo</td>
    </tr>
    <tr>
      <td>bar</td>
    </tr>
    <tr>
      <td>[email protected]</td>
    </tr>
  </tbody>
</table>

CodePudding user response:

try this way...

<table id="df">
  <tr id="row_1"><td>foo</td></tr>
  <tr id="row_2"><td>bar</td></tr>
  <tr id="row_3"><td>[email protected]</td></tr>
</table>

Hide all rows:

const tableRows = document.querySelectorAll('#df tr');

tableRows.forEach(tr => tr.style.display = 'none');

Hide some row:

const rowOne = document.getElementById('row_1');

rowOne.style.display = 'none';

CodePudding user response:

Actually there is some mistake in your spelling.

try this

document.getElementsByTagName("table");

document.getElementsByTagName("table")[0].rows

CodePudding user response:

First, the problems:

  1. document.getElementByTagName('table').style.display = "none";
    

getElementByTagName() doesn't exist; this will have generated an error and would have been shown to you in the developer console had you looked. While getElementsByTagName() exists, the existence of a means to get all elements of a given means (id,tag-name, class...) doesn't imply that a similar method exists to get a singular element via the same approach.

This didn't work because it couldn't work (unless you created the function yourself).

  1. var rows = document.getElementsByTagName("table")[0].rows;
    rows.hidden = false;
    

This couldn't work because while document.getElementsByTagName('table')[0] would return the first <table> in the document, HTMLTableElement.rows property returns a NodeList over which you would have to iterate to hide each row in turn. Again, this would have generated an error which you should have seen in your developer console.

Further, setting rows.hidden to false means that even if it had worked, and assigned the false value to the hidden property of the collection of elements, they would still be visible because you tried to set their hidden to false (which means they would be visible), instead of true which would hide them.

  1. var table = document.getElementById("df");
    table.style = "display:table-row";
    

I don't honestly know what you were trying to achieve with this, but displaying the <table> as if it was a <tr> was never going to hide the <table>, just make it look like something else.

const hideMethods = {
    // here we map the 'data-demo' attribute-value of each <button> to a particular function:
    getElementsByTagName: (e) =>
      // we navigate from the Event Object's currentTarget (the element to which the initiating
      // function was bound) to the closest ancestor <section> element:
      e.currentTarget.closest('section')
      // within that <section> we use getElementsByTagName() to retrieve all <table> elements,
      // and then supply the zeroeth index to get the first:
      .getElementsByTagName('table')[0]
      // we then update the 'display' property of the CSSStyleDeclaration object, setting it to
      // 'none' to have it be hidden:
      .style.display = "none",
    // here we use the 'hidden' property of various nodes:
    hidden: (e) =>
      // again, navigating to the ancestor <section>:
      e.currentTarget.closest('section')
      // using Element.querySelectorAll() to find all <tr> elements inside of <table> elements:
      .querySelectorAll('table tr')
      // and iterating over each of those <tr> elements in turn, using NodeList.prototype.forEach():
      .forEach(
        // we use an Arrow function to pass a reference to the current <tr> of the NodeList over
        // which we're iterating, and within the function body we update the
        // HTMLElement.hidden property, setting it to true, in order to hide it:
        (row) => row.hidden = true),
    querySelector: (e) =>
      // navigating to the ancestor <section>:
      e.currentTarget.closest('section')
      // using Element.querySelector to retrieve the first/only <table> within the <section>
      .querySelector('table')
      // updating the HTMLElement.hidden property to hide the element (along with its
      // descendants):
      .hidden = true
  },
  showMethods = {
    // here we map the 'data-demo' attribute-value of each <button> to a particular function:
    getElementsByTagName: (e) =>
      // we navigate from the Event Object's currentTarget (the element to which the initiating
      // function was bound) to the closest ancestor <section> element:
      e.currentTarget.closest('section')
      // within that <section> we use getElementsByTagName() to retrieve all <table> elements,
      // and then supply the zeroeth index to get the first:
      .getElementsByTagName('table')[0]
      // we then update the 'display' property of the CSSStyleDeclaration object, setting it to
      // 'block' to have it be visible:
      .style.display = "",
    // here we use the 'hidden' property of various nodes:
    hidden: (e) =>
      // again, navigating to the ancestor <section>:
      e.currentTarget.closest('section')
      // using Element.querySelectorAll() to find all <tr> elements inside of <table> elements:
      .querySelectorAll('table tr')
      // and iterating over each of those <tr> elements in turn, using NodeList.prototype.forEach():
      .forEach(
        // we use an Arrow function to pass a reference to the current <tr> of the NodeList over
        // which we're iterating, and within the function body we update the
        // HTMLElement.hidden property, setting it to false, in order to show it:
        (row) => row.hidden = false),
    querySelector: (e) =>
      // navigating to the ancestor <section>:
      e.currentTarget.closest('section')
      // using Element.querySelector to retrieve the first/only <table> within the <section>
      .querySelector('table')
      // updating the HTMLElement.hidden property to show the element (along with its
      // descendants):
      .hidden = false,
  },
  // simple function which takes an element node:
  getIndex = (el) => {
    // caches the parentNode of that element node:
    let parent = el.parentNode,
            // retrieves the iterable children NodeList from
        // the parent, and converts it into an Array:
            children = [...parent.children];
    // returns the result of calling Array.prototype.indexOf()
    // on that Array looking for the passed-in element:
    return children.indexOf(el);
  };

// retrieving all <button> elements in the document, and iterating over that collection
// with NodeList.prototype.forEach():
document.querySelectorAll('button.close').forEach(
  // Arrow function passing a reference to the current <button> into the function, in
  // which we use EventTarget.addEventListener() to bind the anonymous function as
  // the event-handler for the 'click' event on the <button>:
  (btn) => btn.addEventListener('click', (e) =>
    // here we call the functions defined in the hideMethods Object:
    hideMethods[
      // retrieving the function-name from the 'data-demo' attribute, using
      // the Element.dataset API
      btn.dataset.demo
      // passing a reference to the outer Event Object to the function:
    ](e))
)

// retrieving all <button> elements in the document, and iterating over that collection
// with NodeList.prototype.forEach():
document.querySelectorAll('button.show').forEach(
  // Arrow function passing a reference to the current <button> into the function, in
  // which we use EventTarget.addEventListener() to bind the anonymous function as
  // the event-handler for the 'click' event on the <button>:
  (btn) => btn.addEventListener('click', (e) =>
    // here we call the functions defined in the showMethods Object:
    showMethods[
      // retrieving the function-name from the 'data-demo' attribute, using
      // the Element.dataset API
      btn.dataset.demo
      // passing a reference to the outer Event Object to the function:
    ](e))
)

document.querySelectorAll('table button.hide').forEach(
    (btn) => btn.addEventListener('click', (e)=> btn.closest('tr').hidden = true)
);

// retrieving all <button> elements with a class of 'hide' inside of an ancestor
// element with a class of 'controls', and iterating over that collection with
// NodeList.prototype.forEach():
document.querySelectorAll('.controls button.hide').forEach(
    // passing the current button element into the function bocy; and binding the
  // anonymous function of EventTarget.addEventListener() as the event-handler
  // for the 'click' event:
    (btn) => btn.addEventListener('click', (e)=> {
    // caching a reference to the <tr> element, which was found by navigating
    // to the closest <section> ancestor, finding the first/only <table>
    // element inside that <section> and accessing the HTMLTableElement.rows
    // colleaction, passing in the current index of the <button> from amongst
    // its own siblings to retrieve a <tr> element of the same index in its
    // own sibling collection:
    let row = btn.closest('section').querySelector('table').rows[ getIndex(btn) ],
            // caching the current state since we're using a toggle function:
            currentState = row.hidden;
    // setting the HTMLElement.hidden property to the inverse of its current
    // state using the negation operator:
    row.hidden = !currentState;
  })
);
*,
::before,
::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

main {
  display: grid;
  gap: 0.5em;
  grid-template-columns: repeat(auto-fit, 13em);
  inline-size: clamp(13em, 80vw, 1200px);
  margin-block: 1em;
  margin-inline: auto;
}

section {
  border: 1px solid #000;
  display: flex;
  flex-flow: column nowrap;
  justify-content: space-between;
  gap: 0.5em;
  padding: 0.5em;
}

h2 {
  font-size: 1.1em;
  font-style: italic;
  font-weight: 400;
}
<main>
  <section>
    <h2>Hide the table</h2>
    <button type="button"  data-demo="getElementsByTagName">Show with 'getElementsByTagName'</button>
    <table >
      <tr>
        <td>foo</td>
      </tr>
      <tr>
        <td>bar</td>
      </tr>
      <tr>
        <td>[email protected]</td>
      </tr>
    </table>
    <button type="button"  data-demo="getElementsByTagName">Hide with 'getElementsByTagName()''</button>
  </section>
  <section>
    <h2>Hide the table</h2>
    <button type="button"  data-demo="hidden">Show with 'hidden'</button>
    <table >
      <tr>
        <td>foo</td>
      </tr>
      <tr>
        <td>bar</td>
      </tr>
      <tr>
        <td>[email protected]</td>
      </tr>
    </table>
    <button type="button"  data-demo="hidden">Hide with 'hidden'</button>
  </section>
  <section>
    <h2>Hide the table</h2>
    <button type="button"  data-demo="querySelector">Show with 'hidden'</button>
    <table >
      <tr>
        <td>foo</td>
      </tr>
      <tr>
        <td>bar</td>
      </tr>
      <tr>
        <td>[email protected]</td>
      </tr>
    </table>
    <button type="button"  data-demo="querySelector">Hide with 'hidden'</button>
  </section>
  <section>
    <h2>Hide rows</h2>
    <table >
      <tr>
        <td>foo</td><td><button type="button" >X</button></td>
      </tr>
      <tr>
        <td>bar</td><td><button type="button" >X</button></td>
      </tr>
      <tr>
        <td>[email protected]</td><td><button type="button" >X</button></td>
      </tr>
    </table>
  </section>
  <section>
    <h2>Toggle rows</h2>
    <table >
      <tr>
        <td>foo</td>
      </tr>
      <tr>
        <td>bar</td>
      </tr>
      <tr>
        <td>[email protected]</td>
      </tr>
    </table>
    <div >
      <button type="button" >1</button>
      <button type="button" >2</button>
      <button type="button" >3</button>
    </div>
  </section>
</main>

JS Fiddle demo.

References:

  • Related