Designing interactive elements that conceal individual paragraphs

I am working on a project that involves 3 buttons and 3 paragraphs. My goal is to create a JavaScript function that will hide all paragraphs except the one with the same letter as the button clicked. I want to achieve this by applying a CSS rule that adds the class "hidden".

After trying various methods, I have only been able to toggle the hidden class for all paragraphs. Can someone provide guidance on how I can accomplish this task?

function toggle(clicked, id) {
  var el = document.querySelectorAll(".text");
  var length = el.length;

  for (let i = 0; i < length; i++) {
    el[i].classList.add("hidden");
  }
}
.hidden {
  display: none;
}
<div class="button">
  <button class="a" onClick="toggle(this,id)">a</button>
  <button class="b" onClick="toggle(this,id)">b</button>
  <button class="c" onClick="toggle(this,id)">c</button>
</div>

<div class="main">
  <div class="a text">
    <p>a</p>
  </div>
  
  <div class="b text">
    <p>b</p>
  </div>
  
  <div class="c text">
    <p>c</p>
  </div>
</div>

Answer №1

If you are looking to solve this issue using JavaScript instead of relying on the linked duplicate, then this answer is for you. However, if it turns out to be a duplicate, please mark it as such and both the question and this answer will be automatically removed in 30 days.

In contemporary JavaScript practices, it is advisable to separate HTML and JS functionalities. This separation allows for better caching and reusability of JS code across multiple HTML pages. By avoiding direct coupling through attributes like onclick, making changes becomes easier as modifications can be done in one location only, rather than in multiple files. Therefore, it is recommended to utilize addEventListener for this purpose.

To start, you need to select all the buttons you want to work with using querySelectorAll. This method returns a Node List, which is akin to an array-like object containing a list of elements. Consequently, you must iterate through this list using looping methods such as for-loops or forEach.

You can initially add an event listener to each button along with an anonymous function (similar to lambda) to extract information, such as a data-attribute representing the target element's id.

Subsequently, iterate through the paragraphs in a similar manner as before with the buttons. You can employ

classList.toggle('class', statement)
to apply a class based on the truth value of the statement to toggle visibility.

const BUTTONS = document.querySelectorAll('button');
const PARAGRAPHS = document.querySelectorAll('p');

BUTTONS.forEach(button => {
  button.addEventListener('click', function() {
    PARAGRAPHS.forEach(paragraph => {
      paragraph.classList.toggle('d-none', paragraph.id !== this.dataset.id)
    })
  })
})
.d-none {
  display: none;
}
  <button data-id="paraA">A</button>
  <button data-id="paraB">B</button>
  <button data-id="paraC">C</button>
  <br>
  <p id="paraA">A</p>
  <p id="paraB">B</p>
  <p id="paraC">C</p>

Answer №2

Store the state using data attributes instead of classes.

You can connect an element like data-toggle and another element like data-ref.

function toggle(event) {
  const { toggle } = event.target.dataset;
  if (!toggle) return;
  toggleClass(`[data-ref="${toggle}"]`, 'hidden');
}

function toggleClass(elementOrSelector, className) {
  const el = typeof elementOrSelector === 'string'
    ? document.querySelector(elementOrSelector)
    : elementOrSelector;
  el.classList.toggle(className);
}
.hidden {
  display: none;
}
<div class="button">
  <button data-toggle="a" onClick="toggle(event)">a</button>
  <button data-toggle="b" onClick="toggle(event)">b</button>
  <button data-toggle="c" onClick="toggle(event)">c</button>
</div>

<div class="main">
  <div class="text" data-ref="a">
    <p>a</p>
  </div>
  <div class="text" data-ref="b">
    <p>b</p>
  </div>
  <div class="text" data-ref="c">
    <p>c</p>
  </div>
</div>

Answer №3

One easy way to achieve this is by utilizing the details element along with its open attribute.

You can also take it a step further by incorporating CSS for additional styling!

document.body.querySelectorAll('summary').forEach((e) => e.addEventListener("click", (e) => {
   document.body.querySelectorAll('details').forEach((e) => (e.hasAttribute('open')) ? e.removeAttribute('open') : '')
}))
<details>
    <summary>A</summary>
    A content
</details>

<details>
    <summary>B</summary>
    B content
</details>

<details>
    <summary>C</summary>
    C content
</details>

Source

Answer №4

If you are seeking to match the content of a button with the content of a paragraph to be displayed, here is a code snippet that achieves this:

<head>
  <style>
    .hidden {
      display: none;
    }
  </style>
</head>

<body>
  <button>A</button>
  <button>B</button>
  <button>C</button>
  <br>
  <p>A</p>
  <p>B</p>
  <p>C</p>
  <script>
    const buttons = document.querySelectorAll('button');
    const ps = document.querySelectorAll('p');

    function hideAllPs() {
      ps.forEach((p) => {
        p.classList.add('hidden');
      });
    }

    function findPWithSameText(text) {
      let el;
      ps.forEach((p) => {
        if (p.innerText == text) {
          el = p;
        }
      });
      return el;
    }

    hideAllPs();

    buttons.forEach((button) => {
      button.addEventListener('click', function() {
        hideAllPs();
        findPWithSameText(button.innerText).classList.remove('hidden');
      });
    });
  </script>
</body>

Although technically possible, displaying the same text in a button and then in a paragraph may not provide much value to users.

Various other approaches have been suggested for linking buttons to corresponding paragraphs, such as using details element, placing paragraphs next to buttons, or utilizing classes, ids, or data-values. Choose a method that best suits your needs.

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

"Add a +1/Like/Share feature to enhance the user experience of your mobile web

In the process of developing a web-based mobile application with jQuery Mobile. Looking to incorporate buttons for "+1" and "Share" (for Google+) as well as "Like" and "Share" (for Facebook), but each button utilizes a popup window which goes against crea ...

JavaScript ES6 array method for generating an object from an array

I wish to transform the following array: [ { event: "LIB", block_calendar: "YES", obs: "Lorem Ipsum", status: "Block", }, { event: "LIB" block_calendar: "YES" o ...

Steps for positioning a div beside a centered div

Is there a way to position a div next to another div that is centered on the page, like this: .firstDiv { margin-left: auto; margin-right: auto; padding: 0; } The above code centers the first div in the middle of the page. But how can I add a ...

Utilizing the fetch method for sending cross-origin JSON data to an Express backend

When attempting to use Fetch to send JSON data from a form and receive a response from an Express server, I am encountering an issue where I only see an empty object in the console instead of the expected JSON response with the form values. You can find t ...

Creating a dynamic link in Vue JS is a cinch!

I currently have the following code snippet: <b-dropdown text="Select Factory" block variant="primary" class="m-2" menu-class="w-100"> <b-dropdown-item @click="selectedFactory='China'"> ...

Toggle the panel upwards using jQuery's slideToggle function

Looking to create an expandable footer triggered by a click on the '+' sign... Initially, the footer will display basic copyright information and social media links. Upon clicking the sign, I want a sitemap and additional content to slide above t ...

jquery survey quiz

Currently, I am attempting to develop a jQuery questionnaire, but my limited knowledge in the area is proving to be quite inadequate. So far, here is what I have: Upon clicking on "Questions," a pop-up window will appear with two questions. My goal is t ...

Intermittent issue with Webdriver executeScript failing to detect dynamically created elements

It has taken me quite a while to come to terms with this, and I am still facing difficulties. My goal is to access dynamically generated elements on a web page using JavaScript injection through Selenium WebDriver. For instance: String hasclass = js.exec ...

Dynamic field validation using jQuery

I am currently developing a wizard feature that retrieves employees dynamically from the backend. The employee table is created with a radio input field and then inserted into my HTML code: $.ajax({ method: "get", url: '/fetchEmployees/' ...

Image positioned at the top with text links situated at the bottom thanks to Flexbox

I am working on a project that involves placing a flex menu on top of a picture slider. I am struggling to align the items on the same baseline while keeping them on the same line. a img{ height: 40px; } .links{ display: flex; align-items: baselin ...

Issue with PHP Form data not syncing with MySQL Database

I have been attempting to create a form and upload it into my database, but unfortunately, it is not functioning properly. Here is the HTML code I am using: <form name="Form-Request" method="post" action ="icn/form.php"> <div> ...

You won't find the property 'includes' on a type of 'string[]' even if you're using ES7 features

I encountered a similar issue on another page where it was suggested to modify the lib in tsconfig.josn. However, even after changing compile to es7, the same error kept appearing and the project couldn't be compiled or built. { "compileOnSave": ...

Configuring Dialog Placement to the Top in Material-UI

I'm in the process of creating a popup dialog, but I'm encountering an issue where the dialog pops up in the center of the page. How can I position it at the very top of the page when the popup button is clicked? Below is the code snippet: < ...

Unable to apply Login Form Css to HTML

Creating a Login Form <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title>Login Form</title> <link rel = "stylesheet" type="text/css" href="{{ ...

Completely charting the dimensions of an unfamiliar object (and the most effective method for determining its extent)

I am facing a challenge with a "parent" object that contains an unknown number of children at various depths. My main objective is to efficiently map this "parent" object and all its levels of children. How can I achieve this task? Each child already inc ...

Here is a guide on determining the date variance in PHP by leveraging jQuery

I have been attempting to use the jQuery change function to calculate the variance between two dates, but I am encountering a problem as the code seems to be running smoothly without returning any results... <input type="text" name="datte1" class="form ...

JavaScript: Techniques for extracting multiple digits from a text

Enter: "WASHINGTON (Reuters) U.S. stock index futures indicated a marginal recovery on Wall Street on Thursday, as futures for the S&P 500 rose by 0.34 percent, Dow Jones futures gained 0.12 percent, and Nasdaq 100 futures increased by 0.51 percent ...

What is the best way to align text in "reverse order" to the center?

While utilizing text-align: center, I noticed that the remainder remains at the end. Here is how it currently looks: https://i.sstatic.net/DjQU4.png However, I am seeking to achieve this effect where the remainder remains at the start: https://i.sstatic ...

Configuring hostname and port within next.config.js with next.js

Currently, I am utilizing next.js 9.5.x and am in search of a method to set up the hostname and port via the next.config.js file. Despite consulting the documentation, I have yet to discover a solution to this issue. Previously, I leveraged a series of .e ...

When inserting <img>, unwanted gaps appear between div elements

When I have <img> in the child divs, there is some space between them and a blue stripe appears under the image. How do I make them stack perfectly without any gaps? I am new to HTML and CSS and trying to learn for marketing purposes. Any help or ad ...