0

I have a grid of cards on an index page. I want to be able to click on a card link called "Details" to expand that card to a larger size and unhide some additional text. This all works pretty good, except I tend to have to click on the "Details" link 2-3 times for the click event to fire. It seems I have to click on it exactly 3 times for it fire!

This application is built on Ruby on Rails 5.2 and the file is show.js.erb in the view directory.

This is the file:

$(document).ready(function() {
  $('.show').bind('ajax:success', function() {
    $('.card').click(function(e) {
      e.preventDefault();
      clickToExpandCards($(this));
    });
  });

  function clickToExpandCards($obj){
    let clickedElement = $obj;
    if (clickedElement.hasClass('card-expand')) { 
      clickedElement.find('.card-hidden-text').hide();
      clickedElement.removeClass('card-expand'); 
    } else {
      clickedElement.find('.card-hidden-text').show();
      clickedElement.addClass('card-expand');
    }
  };
});

This is the erb link I'm clicking on to fire it.

  <div class='card-buttons'>
    <%= link_to 'Details', cocktail, :class => 'card-link', remote: true, class: 'show' %>
    <%= link_to 'Edit', edit_cocktail_path(cocktail), :class => 'card-link' %>
    <%= link_to 'Remove', cocktail, :class => 'card-link', method: :delete, data: { confirm: 'Are you sure?', remote: true }, class: 'delete' %>
  </div>

As you can see, once it is expanded, a new click on the "Details" link will return it to its normal size. Frustratingly, that often happens with a single click.

I suspect I've implemented this in a way that is slow to process.

What is a better approach?

Phil
  • 157,677
  • 23
  • 242
  • 245
  • 1
    Every time the `ajax:success` event fires, you're adding a duplicate click handler to your `.card` elements. I suggest you use event delegation instead – Phil Sep 23 '21 at 00:50
  • 1
    Does this answer your question? [Event binding on dynamically created elements?](https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – Phil Sep 23 '21 at 00:51
  • 2
    Why do you do `let clickedElement = $obj;` Why not just name the function parameter `clickedElement`? – Barmar Sep 23 '21 at 00:59
  • Thank you all! Phil, that article does look like what I needed. Barmar, thank you I changed it to use the parameter. The '$' part of the parameter isn't something I've worked with and I was just being overly cautious with it while I worked the problem. This post got closed as duplicate, so I'm sorry I can't do more than up vote your responses. But I really needed the help, thank you both again! – Drew Peterson 7671 Sep 23 '21 at 16:37

0 Answers0