1

Is there a cleaner way of achieving this in JavaScript, I'm trying to show / hide items based on a click function

var overview = document.getElementById("overview"); 
var schedule = document.getElementById("schedule");
var reports = document.getElementById("reports");

    function btnOverview_Click() {
        schedule.style.display = "none";
        reports.style.display = "none";
        overview.style.display = "block";
    }       
    function btnSchedule_Click() {
        overview.style.display = "none";
        reports.style.display = "none";
        schedule.style.display = "block";
    } 
    function btnReports_Click() {
        overview.style.display = "none";
        schedule.style.display = "none";
        reports.style.display = "block";
    } 
4
  • 2
    Please, show some HTML markup - The way you're nesting your elements could be of help Commented Jun 1, 2018 at 11:55
  • "Is there a cleaner way of achieving this" if you just want to show/hide some elements then I'd say no. But if you have access to html and want to achive tab-like or accordion-like functionality then - yes. You could make code more generic using classes and data-attributes. Commented Jun 1, 2018 at 11:56
  • Do you want another way like not changing display property or want better code to do same thing Commented Jun 1, 2018 at 11:56
  • Better code to do the same thing - maybe I'm wrong but this seems like a very "bloated" solution. All the elements are at the same "level" - I don't want to access them by their selector - their position, id, class, could change. Commented Jun 1, 2018 at 12:07

2 Answers 2

3

Avoiding all possible inline styling and JavaScript,
I suggest you to do the following:

// I added a class in your HTML
var elements = document.querySelectorAll(".myClass");
var buttons = document.querySelectorAll(".myButtons");

// Function to hide all "elements" except the one we clicked
function hideExceptThis() {
  elements.forEach(elm => elm.style.display = "none");
  // Get the value in "data" attribute
  var id = this.getAttribute("data"); // "this" refers to the one you clicked
  document.querySelector(id).style.display = "block";
}

// On load, bind the above function on click for each element
buttons.forEach(but => but.addEventListener("click", hideExceptThis));
#panel {
  border-bottom: 1px solid gray;
  background: #eee;
  padding: 8px;
}

.myClass {
  width: 240px;
  height: 40px;
  margin: 8px;
  padding: 8px;
}

#overview { background-color: #fdd; }
#schedule { background-color: #dfd; }
#reports  { background-color: #ddf; }
<div id="panel">
  <button class="myButtons" data="#overview">Only overview</button>
  <button class="myButtons" data="#schedule">Only schedule</button>
  <button class="myButtons" data="#reports">Only reports</button>
</div>
<div class="myClass" id="overview">Overview</div>
<div class="myClass" id="schedule">Schedule</div>
<div class="myClass" id="reports">Reports</div>

Hope it helps.

Sign up to request clarification or add additional context in comments.

6 Comments

Absolutely better I think. And in order to make it 100% perfect, use elements.forEach(e=>e.style.display="none") and elements.forEach(e=>e.addEventListener("click", hideExceptThis))
@Attersson Thanks for the suggestion, I've changed .getElementsByClassName() to .querySelectorAll() to be able to apply it.
@Attersson, using .getElementsByClassName(), it says elements.forEach is not a function. stackoverflow.com/questions/24266313/…
Makes little sense since it is an array (woops. HTMLCollection). perhaps [].forEach.apply(e=>{e.style.display="none";}, elements)
The above hide the "button" (clicked item) - i am trying to hide the following: var overview = document.getElementById("overview"); var schedule = document.getElementById("schedule"); var reports = document.getElementById("reports");
|
0

This is not really clean, but at least it saves some lines of code.

Pass this (the element that fires the function) to your function and set all elements to display: none;, but set the element that got clicked back to display: block;.

var overview = document.getElementById("overview");
var schedule = document.getElementById("schedule");
var reports = document.getElementById("reports");

function hide(element) {
  overview.style.display = "none";
  schedule.style.display = "none";
  reports.style.display = "none";
  element.style.display = "block";
}
<div id="overview" style="width: 100px; height: 15px; background-color: green" onclick="hide(this)"></div>
<div id="schedule" style="width: 100px; height: 15px; background-color: yellow" onclick="hide(this)"></div>
<div id="reports" style="width: 100px; height: 15px; background-color: blue" onclick="hide(this)"></div>

5 Comments

Argh! All that inline styling and script!…
@TakitIsy Indeed. :p
@TakitIsy +1 for your answer, it's much better than mine. x)
Thanks, I appreciate! :)
@EdwardDoyle I think you didn't comment the right answer… ;) CodeF0x, sorry to have stolen you the "correct answer"!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.