"Use vanilla JavaScript to toggle an element's visibility only once by comparing data attributes with data-get

I am struggling with some issues regarding toggling. When I click on the button, it toggles only once and I can't seem to hide the element either! It should work in a way that when I click on the first button, it shows the element and clicking again should hide the element!

Link to jsFiddle

//Shortcut functions
function $(e)
{
  return document.querySelector(e);
}

function $$(e)
{
    return document.querySelectorAll(e);
}
  // All elements with toggle-option class
var toggle = $$(".toggle-option");
 //Add EventListener to all buttons with class toggle-option
for (var i = 0; i < toggle.length; i++)
{
  toggle[i].addEventListener('click', togller, false);
}

function togller()
{
  //clicked element's attribute value
  var current = this.getAttribute("data-toggle-number"),
    hidden = $$(".hidden");
  // loop to compare clicked element's attribute value with hidden elements' value     
  for (var i = 0; i < hidden.length; i++)
  {
    var hiddenAtr = hidden[i].getAttribute("data-toggle-number");

    if (current == hiddenAtr)
    {
      if (hidden[i].hasAttribute("data-toggle-number"))
      {
        hidden[i].classList.toggle("hidden")

      }
    }
  }
}
.search-bar {
   height: 50px;
   width: 50px;
   background-color: red;
 }
.add-task-bar {
   height: 50px;
   width: 50px;
   background-color: blue;
 }
 .hidden {
   display: none;
 }
<button class="fa fa-search fa-lg search-btn toggle-option" data-toggle-number="1">Search</button>
<button class="fa fa-plus-circle fa-lg add-task-btn toggle-option" data-toggle-number="2">addTask</button>

<div class="hidden search-bar option" data-toggle-number="1"></div>
<div class="hidden add-task-bar option" data-toggle-number="2"></div>

Answer №1

Update

hidden = $$(".hidden")

to

hidden = $$(".option")

As the 'hidden' class is being removed, it will no longer function properly (however, it still retains the 'option' class).

Answer №2

Trying to toggle the element with the .hidden class may not work if it is already toggled. Instead, access elements with a common fixed class like .option. Update the line hidden = $$(".hidden"); to hidden = $$(".option");

Accessing data attributes can be done more efficiently using the dataset API. Check out the code below.

    function $$(e) {
        return document.querySelectorAll(e);
      }
      // All elements with toggle-option class
    var toggle = $$(".toggle-option");
     //Add EventListener to all buttons with toggle-option class
    for (var i = 0; i < toggle.length; i++) {
      toggle[i].addEventListener('click', togller, false);
    }

    function togller() {
      //clicked element's attribute value
      var current = this.dataset.toggleNumber,
        hidden = $$(".option");
      // loop to compare clicked element's attribute value with hidden elements' value     
      for (var i = 0; i < hidden.length; i++) {
        var hiddenAtr = hidden[i].dataset.toggleNumber;
        if (current == hiddenAtr) {
          if (hidden[i].hasAttribute("data-toggle-number")) {
            hidden[i].classList.toggle("hidden")

          }
        }

      }
    }
        .search-bar {
          height: 50px;
          width: 50px;
          background-color: red;
        }
        .add-task-bar {
          height: 50px;
          width: 50px;
          background-color: blue;
        }
        .hidden {
          display: none;
        }
<button class="fa fa-search fa-lg search-btn toggle-option" data-toggle-number="1">Search</button>
<button class="fa fa-plus-circle fa-lg add-task-btn toggle-option" data-toggle-number="2">addTask</button>

<div class="hidden search-bar option" data-toggle-number="1"></div>
<div class="hidden add-task-bar option" data-toggle-number="2"></div>

The ES6 version of this code would be as follows. Note that in arrow functions, this remains bound to the enclosing context, so there is no need for current as in

var current = this.dataset.toggleNumber;

function $$(e) {
  return document.querySelectorAll(e);
}

Array(...$$(".toggle-option")).forEach(e => e.addEventListener('click', togller, false));

function togller() {
  Array(...$$(".option")).forEach(e => {
  (e.dataset.toggleNumber == this.dataset.toggleNumber) &&
  e.classList.toggle("hidden")});
}
        .search-bar {
          height: 50px;
          width: 50px;
          background-color: red;
        }
        .add-task-bar {
          height: 50px;
          width: 50px;
          background-color: blue;
        }
        .hidden {
          display: none;
        }
<button class="fa fa-search fa-lg search-btn toggle-option" data-toggle-number="1">Search</button>
<button class="fa fa-plus-circle fa-lg add-task-btn toggle-option" data-toggle-number="2">addTask</button>

<div class="hidden search-bar option" data-toggle-number="1"></div>
<div class="hidden add-task-bar option" data-toggle-number="2"></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Combining both AJAX variables and HTML classes

Having trouble combining two AJAX variables with JQuery and PHP to add to a MySQL database... Here is the code snippet: $.ajax({ url: DIR+"some.php", method: "POST", dataType: "JSON", data: { mobile: mobile.val(), d ...

Mastering the Art of Live Search in Drop Down Multi Select

I need to develop a search functionality similar to the one found on . This search should allow users to select options from a dropdown menu or type their own search query, and provide live search results. I attempted to use the jQuery plugin https://www.j ...

Delete the right-hand p-timeline-event-opposite margin from the Angular 17 PrimeNG Timeline

I am currently utilizing the PrimeNG Timeline module to showcase a few straightforward horizontal timelines with content placed on the top side in a table format. How can I eliminate the space allocated by the .p-timeline-event-opposite section? Upon inspe ...

Difficulty in centering two equal-sized columns in a Bootstrap 3 row with an offset

Here is a link to my demonstration on JSFiddle: https://jsfiddle.net/nbd2w3zb/ I am working with Bootstrap 3 and have created 2 equal-sized columns (.col-md-4) within a .row. The desired effect is to center both of these columns inside the .row, ensuring ...

Check out our website's event countdown timer featuring a server-sided event tracking system

Currently, I am in the process of developing a website and have the requirement to incorporate a timer on one of the pages. The goal is for the timer to count down from a specified time, such as DD::hh:mm 02:12:34, until it reaches zero. Once the countdown ...

Tips for minimizing the arrow size in the infowindow on a Google Maps interface

As a newcomer to customizing Google Maps, I am looking to decrease the size of the arrow in the infowindow and position it in the bottom left corner for a better appearance. I am struggling to figure out how to adjust the height and width of the arrow and ...

Using inline styles for progress bars in React

Struggling to apply styling to the element labeled as "progress", I've tried multiple options but just can't seem to get it right. Any assistance or clues would be greatly welcomed! Here is the code snippet for the component: constructor(pr ...

Complete my search input by utilizing ajax

It's only been 30 minutes since my last post, but I feel like I'm making progress with my search posts input: I've developed a model that resembles this: function matchPosts($keyword) { $this->db->get('posts'); ...

Can you provide some guidance on accessing HTTP headers while using Promises to make AJAX requests?

Currently, I am working on resolving jQuery ajax requests using bluebird.js and I have found it quite challenging to access the HTTP headers of the request. Here is a snippet of the code I am working with: Promise.resolve($.get(...)).then(function(data){ ...

The JavaScript function is not being activated by clicking on Selenium in Chrome

Take a look at the HTML snippet below: <table class="table-main "> <thead> <tbody> <!----> <tr class="" ng-if="mapCtrl.isAdded" style=""> <td/> <td> <td> <t ...

How can specific times be disabled using Laravel-9 jQuery Timepicker?

$(document).ready(function(){ $('#time').timepicker({ timeFormat: 'h:mm a', interval: 60, minTime: '9', maxTime: '4:00pm', defaultTime: '9', startTime: '9:00', dyna ...

Performing read and write operations on targeted CSS classes using C#

I'm currently developing a C# application that needs to manipulate CSS files. Imagine you have the following CSS code snippet: .ClassOne { color: #FFFFFF; font-weight:normal; font-size: 9pt; font-family: Tahoma; ...

Struggling to locate the origin of this mysterious border

After thoroughly inspecting and manipulating CSS, I am still unable to determine the source of this mysterious border... Mysterious Border Image - The Origin Unveiled Could someone take a look and provide some insights? It seems like the border is encom ...

Steps for removing form validation from non-conditional formControls

My issue is with a form-control that displays a success mark after submission, even though there are no validation conditions in place. Is there a way to disable this validation? <Form noValidate validated={validated} onSubmit={e => this.ha ...

steps to retrieve JSON object using Angular service

In the login.js file, I have a module with a method called loginUser structured like this: ...function loginUser(){ var user={ email:loginVM.Email, password:loginVM.pwd }; console.log(user); loginService.login ...

What is the best way to make a bootstrap component (container) stretch to the full width and height of the window when it first loads, and which

I am looking to achieve something similar to the design on a certain website: The goal is to have a container with a background and a form inside that resizes proportionally based on the size of the window it is opened in. The resizing should be smooth an ...

Guide on transferring a variable from a Python settings.py file to a JavaScript file

Could someone help me with accessing a variable from the settings in Python? SESSION_COOKIE_AGE = 4500 I need to use this variable in a JavaScript (JS) code snippet. I came across an article that explains one method: However, I'm wondering if ther ...

Looking for assistance in reorganizing columns in Google Sheets while appending data

Rephrasing a previous post for better understanding- I have a JSON API that I am importing into Google Sheets. However, the columns are not consistently in the same order each time it reloads, which is common for JSON data. The issue arises when I try to ...

Contrasting CSS Attribute Selectors and Pseudo-Elements in Input Tags

<input type="text" placeholder="nothing" title="google" required> **CSS Content:** input[type="text"]{ border: 2px solid red; } input::placeholder{ color:green; } input[title="google"]{ background ...

How to place a stylish font over an image and recreate hover effects

I am looking to place social media icons below an image next to the photo's title, including Facebook, Twitter, Soundcloud, and Instagram. I want these icons to rotate along with the image when it is hovered over. HTML <div class="polaroid-image ...