What is the best way to use jQuery to toggle the hidden class on an inner div when a button inside a card is clicked?

How can I implement jQuery functionality to toggle the hidden class on an inner div by clicking a button inside a card?

I attempted to create a container div containing multiple cards. The issue arises when I click the button - it only opens the panel, but does not close it when clicked again. However, it closes if I open a new panel, which is the desired behavior.

Another issue I encountered is that the functions hideAllPanels and showMoreInfo only work when one is active.

function handleMoreInfo() {
  $(".coin-card").on("click",async function(e) {
    e.stopImmediatePropagation();
    const coinID = ($(this).find('.coin-name').text()).toLowerCase();
    const data = await fetchMoreInfo(coinID);
    if (data) showMoreInfo(data,$(this));
  });
}

const showMoreInfo = (data,thatCoin) => {
  nodeList[0].forEach(div => {
    const coinNameFromArr = $(div).find('.coin-name').text();
    if (coinNameFromArr.toLowerCase() === data.id ) {
      const panel = $(div).find('.more-info-panel').attr("class");
      const panelClassesArr = panel.split(' ');
      if(panelClassesArr.length === 1) $(div).find('.more-info-panel').addClass("hidden");
      if(panelClassesArr.length === 2) $(div).find('.more-info-panel').removeClass("hidden");
    }
  })
  thatCoin.find('.more-info-image').prop("src",data?.image?.large);
  thatCoin.find('.usd').text(`USD: $${data?.market_data?.current_price?.usd}`);
  thatCoin.find('.eur').text(`EUR: €${data?.market_data?.current_price?.eur}`);
  thatCoin.find('.ils').text(`ILS: ₪${data?.market_data?.current_price?.ils}`);
}

const hideAllPanels = () => {
  nodeList[0].forEach(div => {
    const panel = $(div).find('.more-info-panel').attr("class");
    const panelClassesArr = panel.split(' ');
    if(panelClassesArr.length === 1) $(div).find('.more-info-panel').addClass("hidden");
  });  
}

This is an example HTML for a card:

<div class="coin-card">
  <div class="headInfo">
    <p class="coin-symbol">btc</p>
    <div class="form-check form-switch"><input class="form-check-input" num1="0" type="checkbox" role="switch" onclick="addCoinsToArray()"><label class="form-check-label" for="flexSwitchCheckChecked"></label></div>
  </div>
  <p class="coin-name">Bitcoin</p><button class="btn btn-info mybtn" onclick="handleMoreInfo()" data-toggle="collapse" data-target="info" num="0">More Info</button>
  <div class="more-info-panel hidden" symbol="bitcoin"><img class="more-info-image" src="./src/img/bitcoin-g80ff29158_640.jpg">
    <p class="info-title">Coin Prices:</p>
    <p class="usd">USD: $30</p>
    <p class="eur">EUR: €30</p>
    <p class="ils">ILS: ₪30</p>
  </div>
</div>

Answer №1

Yes, I agree that your code seems a bit too complicated. The mix of onclick and jQuery .on('click') is adding a new on('click') handler to coin-card every time the button is clicked.

Here's a simpler approach:

// Remove the onclick on the button
$('.coin-card .btn-info').on('click', async function() {
  // Find the parent .coin-card of the clicked button
  const $card = $(this).closest('.coin-card');
  const $infoPanel = $card.find('.more-info-panel');
  
  // const coinName = $card.find('.coin-name').text().toLowerCase();
  // const data = await fetchMoreInfo(coinID);
  // set data...
  
  // Version 1: Allow multiple panels to be open
  //$infoPanel.toggleClass('hidden');
  
  // Version 2: Behave like an accordion, closing all other panels
  const isOpen = $infoPanel.hasClass('hidden');
  $('.coin-card .more-info-panel').addClass('hidden');
  if (isOpen) {
    $card.find('.more-info-panel').removeClass('hidden');
  }
});
.coin-card {
  border: 1px solid;
  margin: .5rem;
  padding: 1rem;
  float: left;
  width: 20%;
}
p {
  margin: 0;
}

.coin-card .more-info-panel.hidden {
  display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="coin-card">
    <div class="headInfo">
      <p class="coin-symbol">btc</p>
      <div class="form-check form-switch"><input class="form-check-input" num1="0" type="checkbox"             role="switch"
          onclick="addCoinsToArray()"><label class="form-check-label" for="flexSwitchCheckChecked"></label></div>
    </div>
    <p class="coin-name">Bitcoin</p><button class="btn btn-info mybtn" data-toggle="collapse"
      data-target="info" num="0">More Info</button>
    <div class="more-info-panel hidden" symbol="bitcoin"><img class="more-info-image"
        src="./src/img/bitcoin-g80ff29158_640.jpg">
      <p class="info-title">Coin Prices:</p>
      <p class="usd">USD: $30</p>
      <p class="eur">EUR: €30</p>
      <p class="ils">ILS: ₪30</p>
    </div>
  </div>
  
   <div class="coin-card">
    <div class="headInfo">
      <p class="coin-symbol">btc</p>
      <div class="form-check form-switch"><input class="form-check-input" num1="0" type="checkbox"             role="switch"
          onclick="addCoinsToArray()"><label class="form-check-label" for="flexSwitchCheckChecked"></label></div>
    </div>
    <p class="coin-name">Bitcoin</p><button class="btn btn-info mybtn" data-toggle="collapse"
      data-target="info" num="0">More Info</button>
    <div class="more-info-panel hidden" symbol="bitcoin"><img class="more-info-image"
        src="./src/img/bitcoin-g80ff29158_640.jpg">
      <p class="info-title">Coin Prices:</p>
      <p class="usd">USD: $30</p>
      <p class="eur">EUR: €30</p>
      <p class="ils">ILS: ₪30</p>
    </div>
  </div>
  
   <div class="coin-card">
    <div class="headInfo">
      <p class="coin-symbol">btc</p>
      <div class="form-check form-switch"><input class="form-check-input" num1="0" type="checkbox"             role="switch"
          onclick="addCoinsToArray()"><label class="form-check-label" for="flexSwitchCheckChecked"></label></div>
    </div>
    <p class="coin-name">Bitcoin</p><button class="btn btn-info mybtn" data-toggle="collapse"
      data-target="info" num="0">More Info</button>
    <div class="more-info-panel hidden" symbol="bitcoin"><img class="more-info-image"
        src="./src/img/bitcoin-g80ff29158_640.jpg">
      <p class="info-title">Coin Prices:</p>
      <p class="usd">USD: $30</p>
      <p class="eur">EUR: €30</p>
      <p class="ils">ILS: ₪30</p>
    </div>
  </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

Replace automatically generated CSS with custom styles

When using a Jquery wysiwyg editor, I have encountered an issue where it automatically adds code to the textarea at runtime. The problem arises from it inserting an inline style of style="width:320px" when I need it to be 100% width due to styles already ...

Turning a JavaScript function into jQuery

Is there a way to convert this JavaScript selected code into jQuery? I need to target a button class instead of an ID, and I've heard that using jQuery is the simplest way to achieve this. var playButton1 = $('.playButton1'); playButton1.o ...

Is there a way to direct back to the AJAX error function from the application_error in the

Why does my code keep ending up in the AJAX success function instead of the error function? What mistake am I making? $.ajax({ url: url, type: "POST", data: data, contentType: "application/json; charset=utf-8", success: function(data) ...

The application is failing to launch following an upgrade to PostCSS version 8 in a React environment

While working on my app, I discovered that I had 80 vulnerabilities. These vulnerabilities were mainly due to peer version mismatches, such as one package requiring React 16.8.0 while I had 17.0.1. However, there was one vulnerability that caught my attent ...

Enhance the readability of your Angular/Ionic applications with proper hyphenation

In my Ionic 3 app, I am using an ion-grid. Some words do not fit within the columns and are cut off, continuing on the next row without any hyphens added for proper grammar context. See image https://i.stack.imgur.com/3Q9FX.png. This layout appears quite ...

Is it possible to create a cross-sectional view of a lens using the HTML5 canvas element?

I am interested in creating a visual representation of the cross section of a lens element. Typically, these elements consist of one or two circular surfaces (front and back) with a rim of arbitrary shape. My goal is to simply connect the front and back su ...

Issues with scrolling navigation have been identified in IE8

I am puzzled by the fact that the main navigation on this website is not functioning in IE8. redacted The code for the navigation is quite simple, with a localScroll feature attached to enable the scrolling effect. <ul> <li><a href=" ...

Vue.js isn't triggering the 'created' method as expected

I have a main component called App.vue. Within this component, I have defined the created method in my methods object. However, I am noticing that this method is never being executed. <template> <div id="app"> <Header /> <Ad ...

Switch the URL to render the view using Express 4

I am facing an issue with a post request where the views are rendering to /link/123 instead of /anotherlink. Although I could use res.redirect('/anotherlink'), I need to render different data. app.post('/link/:id',function (req, res, n ...

Adding individual buttons at the bottom of each data row using Jquery: A step-by-step guide

Currently, I am receiving data from a backend using an AJAX GET method and displaying it in a list in HTML. However, I am facing some issues with including buttons within the list and making them functional by utilizing delegate and other methods. I would ...

Leverage the source code of Angular 2 in your project for seamless integration

Currently in the process of setting up Angular with npm: npm install @angular... Encountering an issue where the TypeScript source files are not included. I would like to have access to debug the code using the TypeScript source files (with source maps). ...

What is the best way to include query parameters in a redirect using the res.redirect function in node.js/express.js?

Trying to navigate users to a Google Authorization page within my application poses a challenge. In this scenario, utilizing any Google API modules is not an option. To achieve the redirection, I am aware that I can structure my res.redirect() function in ...

In Next.js, encountering an error when using canvas drawImage

I am attempting to upload a local image onto a canvas element, but I keep encountering an error: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLCanvasElement ...

What is the best way to choose a single expanded panel in Vuejs (vuetify) based on its index value?

I am encountering an issue with the expanded panels while using Vuetify in my Vue.js project. The problem arises when I perform a v-for loop over an array of objects and attempt to display expanded panels with external control. By external control, I mean ...

Issue with Bootstrap: unable to align columns vertically

I am currently learning how to use bootstrap, but I am facing a challenge with vertical alignment of columns. Despite trying various methods, I can't seem to get the content to align anywhere other than the top. Even starting from scratch with code fr ...

Preventing swiping on a particular div

Incorporating jQuery Mobile 1.9.1 code to display side panels upon right or left swipe by the user has been a useful feature... $(document).on("pageinit",".ui-page",function(){ var $page=$(this); $page.on("swipeleft swiperight",function(e){ ...

Fotorama Slider experiencing display issues upon first loading

Our website features the fotorama slider which can be viewed here: However, we are experiencing an issue where upon the initial page load, the slider appears in a small area in the top left corner of the container. It only displays correctly when the brow ...

I am attempting to utilize the fetch API method to initialize the store's state, but for some reason, it is not functioning properly

Within my store.js file, I have a state called user_data, with its initial method set to fetch_user_data: export default new Vuex.Store({ state: { user_data: util.fetch_user_data('username') ... } located in the util.js file: util. ...

What are the advantages of utilizing buffer geometries in Three.js?

I have experience using both BufferGeometry and Geometry, so I feel comfortable with either. Even when I need to make frequent modifications, I tend to lean on BufferGeometry because although the code is more verbose, it's not overly complex. Can you ...

Changes in vertical position of link icon within div based on the browser and operating system

Trying to design a straightforward 3-line mobile menu dropdown, but encountering inconsistency in appearance across different devices. The vertical positioning of the icon is varying based on the operating system and browser version: Linux -desktop Fire ...