Guide for making an accordion with a close button that is specific to multiple dynamic IDs

I am looking to create an accordion feature. The idea is that when the user clicks on "Show," the text "Show" should be hidden, and the content along with a "Close" button should be displayed. Then, when the user clicks on "Close," the content and "Close" button should be hidden, and the "Show" button should be shown again.

It is important for all text to be in the HTML rather than in JavaScript. I also need this functionality to work with dynamic ID posts in Wordpress, so that more content can be shown and hidden on the index page.

I have made an attempt at implementing this, but unfortunately, the "Close" button does not seem to work as expected.

This feature needs to work with multiple ID items since it will be connected to the index posts page in WordPress.

Is it possible to change the class of the show/close buttons? Ideally, clicking on the parent element of the "Show" button would change the class of another element, and clicking on the parent element of the "Close" button would change the class of yet another element.

var $contents = $('.tab-content');
$contents.slice().hide();
$('.tab').click(function() {
  var $target = $('#' + this.id + 'show').show();
  $contents.not($target).hide();
});
.tab {
  background: red;
  max-width: 100px;
  cursor: pointer;
}

.close {
  border: 1px solid red;
  max-width: 100px;
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="tab1" class="tab">Show 1</div>
<div id="tab1show" class="tab-content">
  content 1
  <div class="close">close</div>
</div>

<br><br><br>
<div id="tab2" class="tab">Show 2</div>
<div id="tab2show" class="tab-content">
  content 2
  <div class="close">close</div>
</div>

Answer №1

Check out this working fiddle.

Remember to include a click event for the close button as well, similar to this:

var $contents = $('.tab-content');
$contents.slice().hide();

$('.tab').click(function() {
  removeExtraClass();

  var $target = $('#' + this.id + 'show').show();
  var extraClass = 'post' + this.id.split('tab')[1] + 'long';

  $(this).hide().parent().addClass(extraClass);
  $('.tab').show();
  $contents.not($target).hide();
});

$('.close').click(function() {
  removeExtraClass();

  $(this).parent().hide();
  $(this).parent().prev('.tab').show();

  var $target = $(this).parent();
});

function removeExtraClass() {
  $contents.each(function() {
    var id = $(this).attr('id');
    var postClass = 'post' + id.split('tab')[1];

    $(this).parent().attr("class", postClass);
  });
}
.tab {
  background: blue;
  max-width: 100px;
  cursor: pointer;
}

.close {
  border: 1px solid blue;
  max-width: 100px;
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="postA">
  <div id="tabA" class="tab">View A</div>
  <div id="tabAshow" class="tab-content">
    content A
    <div class="close">close</div>
  </div>
</div>


<br><br><br>

<div class="postB">
  <div id="tabB" class="tab">View B</div>
  <div id="tabBshow" class="tab-content">
    content B
    <div class="close">close</div>
  </div>

  <br><br><br>
</div>

Answer №2

To implement the functionality, simply add an event listener on the element with the class .close.

var $contents = $('.tab-content');
$contents.slice().hide();

$('.tab').click(function() {
  var $target = $('#' + this.id + 'show').show();
  $(this).hide();
});

$('.close').click(function(){
  $(this).parent().hide();
  let parentId = $(this).parent().attr('id');
  parentId = parentId.replace('show','');
  
  $('#'+parentId).show();
  
});
.tab {background:red; max-width:100px; cursor: pointer;}
.close {border: 1px solid red; max-width:100px; cursor: pointer;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  
  <div id="tab1" class="tab">Show 1</div>
  <div id="tab1show" class="tab-content">
  content 1
  <div class="close">close</div>
  </div>



<br><br><br>
<div id="tab2" class="tab">Show 2</div>
<div id="tab2show" class="tab-content">
  content 2
  <div class="close">close</div>
</div>

<br><br><br>

Answer №3

To close an event, simply use the following code:

$('.close').on('click',function(){
   $(this).closest('.tab-content').hide();
});

Here's a snippet of how it works,

var $contents = $('.tab-content');
$contents.slice().hide();
$('.tab').click(function() {
  var $target = $('#' + this.id + 'show').show();
  post = $target.closest('.post');
  post.addClass(post.attr('data-classes') + 'long');
  $allTargets = $contents.not($target);
  $allTargets.each(function() {
    post = $(this).closest('.post');
    post.removeClass(post.attr('data-classes') + 'long');
    $(this).hide();
  });
});
$('.close').on('click', function() {
  $(this).closest('.tab-content').hide();
});
.tab {
  background: red;
  max-width: 100px;
  cursor: pointer;
}

.close {
  border: 1px solid red;
  max-width: 100px;
  cursor: pointer;
}

[class$='long'] .tab {
  color: #FFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="post1 post" data-classes='post1'>

  <div id="tab1" class="tab">Show 1</div>
  <div id="tab1show" class="tab-content">
    content 1
    <div class="close">close</div>
  </div>
</div>

<br><br><br>
<div class="post2 post" data-classes='post2'>
  <div id="tab2" class="tab">Show 2</div>
  <div id="tab2show" class="tab-content">
    content 2
    <div class="close">close</div>
  </div>
</div>
<br><br><br>

Answer №4

Here's a suggestion for you to try:

var $content = $('.tab-content');
$content.slice().hide();
$('.tab').click(function() {
  var $target = $('#' + this.id + 'show').show().addClass('long');
  $('.tab').show();
  $content.not($target).hide().removeClass('long');
  $(this).hide();
});

$('.close').click(function() {
  var tab = $('#' + $(this).attr('data-tab'));
  var tabContent = $(this).parent();

  tab.show();  
  tabContent.hide();
});
.tab {background:red; max-width:100px; cursor: pointer;}
.close {border: 1px solid red; max-width:100px; cursor: pointer;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="tab1" class="tab">Show 1</div>
<div id="tab1show" class="tab-content">
  content 1
  <div class="close" data-tab="tab1">close</div>
  </div>

<br><br><br>
<div id="tab2" class="tab">Show 2</div>
<div id="tab2show" class="tab-content">
  content 2
  <div class="close" data-tab="tab2">close</div>
</div>

<br><br><br>

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

What is the correct way to format responses written within response.write() in NodeJS?

Just starting out with NodeJS and express and following a tutorial on displaying two headings in the browser. Came across an issue where using res.send() twice wasn't working, so my instructor introduced me to the write method. Interestingly, when she ...

What is the significance of a window's "o" condition?

Recently, I came across a code snippet that looks like this: if (!('o' in window)) { o = "somelink"; l =["n", "somelink"]; p = [0.8,1]; d = new Date("2018/01/01"); if (Date.now() >= d) { r = Math.random(); v ...

Achieving a single anchor link to smoothly scroll to two distinct sections within a single page using React

There is a sidebar section alongside a content section. The sidebar contains anchor links that, when clicked, make the corresponding content scroll to the top on the right-hand side. However, I also want the sidebar link that was clicked to scroll to the ...

What methods are available in JavaScript regex for validating city names?

var cityRegex = /^[a-zA-z] ?([a-zA-z]|[a-zA-z] )*[a-zA-z]$/; is the regular expression I attempted to create. However, it fails when inputting a city name like "St. Petersburg." Update: It seems challenging to create a perfect regex pattern for city name ...

Three image resources combined to create a unique border design in CSS

I am currently working on designing a webpage and am in need of creating a background border. I have access to three image resources for this task: one for the left side, another for the top, and the third for the right side. My struggle lies in finding s ...

Hover Effect for Bootstrap Gallery

I've created a hover effect for my gallery that is embedded in a Bootstrap Grid. Although the hover effect itself works fine, on some screen sizes, the overlay ends up covering the gallery images. Does anyone have any ideas, solutions, or hints to so ...

What methods can I use to prevent floated child divs from wrapping?

I'm currently working on creating a carousel-like feature where users can select radio buttons within various div elements. The concept involves having approximately 20 divs, each 150px wide, containing radio buttons. I want to prevent these 20 divs f ...

A guide to implementing hover and mouse click effects on ImageList using Material UI version 5.11.11

I have successfully created a list of images using MaterialUI, but now I would like to enhance the user experience by adding a mouse hover effect to highlight the image under the cursor. Below is the code snippet for my image list. How can I accomplish t ...

Ways to set the initial value of an input[range] in Angular2 when the value exceeds 100

After encountering a similar issue with AngularJS, I posted a question on StackOverflow titled How to initialize the value of an input[range] using AngularJS when value is over 100. As I dive into learning Angular2, I am curious if it handles initializatio ...

Remove the footer from the main section

I'm facing an issue with the web page layout of my website. Here is a snippet of the structure: <body> <div class="container"> <div class="sidebar"> </div> <div class="content"> </div> </div> < ...

Winston is set up to only record .info errors and does not save any errors to a file or a MongoDB database

Currently, I am utilizing express-mongoose as my backend framework and winston as my logging tool. However, I have encountered an issue where winston only seems to log info messages and not errors. The logs can be found in server.log https://i.stack.imgur. ...

What is the process for updating the CSS style of every other piece of data (such as an image) retrieved

Is it possible to utilize PHP code when retrieving data from a MySQL database in order to have every other record display with unique CSS formatting? For instance, I am incorporating images similar to this in my comment system: http://prntscr.com/3hpiep ...

The functionality of updating the logo in the browser tabs is not functioning as expected in Vue.js 3

This is the code from my index.html: <!DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE ...

Interact with JSON data using CakePHP for posting and retrieving requests

Having difficulty posting and retrieving JSON data using CakePHP. In the view file, attempting to post data with code resembling the following: $.ajax({ type: "post", url: '/invoices/insertItem/', data: {'description': "th ...

Integrate user interface functionality within the server component in NextJS

When considering the Server Component located in the new app/ directory within NextJS: export default async function RootLayout({ children }) { const categories = await getCategories(); // const [navigation, setNavigation] = React.useState('hidde ...

Is it considered poor form for an Angular controller to invoke a function on a directive?

My custom Angular directive functions as a unique combobox, where clicking on the input control reveals a div below it with a list of items from a model object. The user can type text into the input control to filter the displayed list. In addition to the ...

AngularJS, the element being referenced by the directive is empty

Currently, I am in the process of transferring a jQuery plugin to AngularJS simply for the enjoyment of it. Previously, when working with jQuery, my focus was on manipulating the DOM using jQuery functions within the plugin loading function. Now that I am ...

Delete any HTML content dynamically appended by AJAX requests

I'm currently working on a page dedicated to building orders, where the functionality is fully dependent on ajax for finding products and adding them dynamically. However, I encountered an issue when attempting to remove an item that was added via aj ...

The method insertFusionCharts cannot be called in Angular when using jQuery

I have integrated the following scripts into my angular project <script defer src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script> <script src="assets/js/jquery.min.js"></script> <script ...

What is the reason behind evently recommending the use of $$(this) for saving state?

Explained in this resource, if you want to save state that needs to be accessible in various events, it is recommended to use $$(this), as shown here: $$(this).filters = "myvalue"; What does that syntax signify? Why use $$ (double dollar)? Why reference ...