Home > Back-end >  How to make a button with 2 states that when clicked, triggers a different function according to the
How to make a button with 2 states that when clicked, triggers a different function according to the

Time:02-20

I would like to have a button that acts as a filter on a table, when clicked it executes a function that does the filtering, but when clicked again it undoes the filter. if it was clicked a third time it filters the table again, and so on..

the HTML is just a simple button selector:

<button id="filterButton">Click here to filter</button>

and I have this Javascript function:

window.onload = function() {
            document.getElementById('filterButton').onclick = function() {      
                FilterTable(); //this function is the one that actually does the filtering, basically setting the tr[indexOfRow].style.display="none" on some specific rows.
            };

I would like to make it so that if the button was clicked again, it would call a different function that will undo the filtering.

I tried adding a line at the very end of this function change the ID of the button to filterButtonClicked using document.getElementById("filterButton").setAttribute("id", "filterButtonClicked"); and then have another JS function that will handle the document.getElementById('filterButtonClicked').onclick event, which will undo the filtering, and then at the end of this function, change back the ID of the button to fiterButton. In theory, this will make it so that if the button was clicked for the third time, it would trigger the first JS function, which will do the filtering again and change the ID to filterButtonClicked. but in practice, this unfortunately didn't work, it would only change the ID to filterButtonClicked once, and subsequent clicks don't change it back to filterButton.

Maybe this could be implemented in a way so that if the number of clicks on the button was odd it would execute the first function, and if it was even it would execute the second one. but I don't know how to implement this.

Is there a better way to do this?

CodePudding user response:

The answer you are looking for is quite easy...

var state = 0; //This will act as the status of the button, 0 means needs unfiltered and 1 means need filtered. It will remain one in starting to show it is unfiltered
window.onload = function() {
  document.getElementById('filterButton').onclick = function() {
    buttonClickFunction()
  };
};

function buttonClickFunction() {
  //Run this function whenever the button is clicked
  if (state == 0) {
    FilterTable(); //this function is the one that actually does the filtering, basically setting the tr[indexOfRow].style.display="none" on some specific rows.
    state = 1; //Shows that it has been filtered
  } else {
    UnfilterTable(); //The function you want to run for unfilter
    state = 0; //Change it back to 0 to show its unfiltered
  }
}

function UnfilterTable() {
  //Whatever u wanna run to unfilter
}

function FilterTable() {
  //Whatever u wanna run to filter
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <button id="filterButton">Click here to filter</button>
</body>

</html>

CodePudding user response:

Declaratively, I would hide/show needed button and bind onclick handler on each

Here's an example https://codesandbox.io/s/elegant-glitter-05s6pg

CodePudding user response:

Something like this should work:

let filterActive = {
    state: false,
};

window.onload = function () {
    document.getElementById("filterButton").onclick = function () {
        if (filterActive.state === false) {
            FilterTable();
            filterActive.state = true;
        } else {
            // Function to undo the filtering here
            filterActive.state = false;
        }
    };
};

CodePudding user response:

You could use closure to keep track of the state. Depending if the table is filtered or not you could then either show everything or filter it.

  <script>
  window.onload = function () {
    document.getElementById("filterButton").onclick = function () {
      FilterToggle();
    };
  };

  function ShowAllTable() {
    // console.log("showing all the table");
  }

  function FilterTable() {
    // console.log("filtering the table");
  }

  function FilterWithClosure() {
    var filtered = false;

    return function () {
      if (filtered) {
        ShowAllTable();
        filtered = false;
      } else {
        FilterTable();
        filtered = true;
      }
    };
  }

  var FilterToggle = FilterWithClosure();
</script>
  • Related