Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FontAwesome 5 on click event?

What I'm trying to do

I just switched over from Font Awesome 4.7 to Font Awesome 5 and everything is working great except one thing: In part of my site, I use a font awesome icon as a toggle-esk button. On click, I want to change the "open" heart to a "closed" heart icon (fas fa-heart <-> far fa-heart). I can do this by changing the data-prefix in the SVG element in the browser's inspector.

Problem

My problem comes to binding the click listener as the element that was there is removed and replaced with an SVG. I dynamically add elements onto the page that have these heart icons and after generating the HTML with JS handlebars, I use jquerys .on("click") method to get when the button is clicked and toggle the classes. This was fine when the element didn't get replaced, but with the change to SVG's whats the new way of doing this?

Possible Solutions

I read through Font Awesome's "How To" guide and they don't cover topics like this yet. This is a common thing people will want to do so it would be nice to get a list of solutions people can use. Below are two ideas I've thought of but and one that FontAwesome would have to provide but I'm curious if there's a better way:

  1. Use a short timeout before adding listener - seems hacky at best however.
  2. Use a wrapper element's on click and then search for the SVG element on every click.
  3. FontAwesome could provide a callback for when an icon has been replaced.

Example Fiddle

Here is a simplified example where a button is dynamically appended to the document (this works fine if using $(document).ready() but I am doing an API request and then generating html dynamically). Clicking the button does not call the listener as the element hasn't finished replacing the element to an SVG.

https://jsfiddle.net/L748ownw/

<div id='container'></div>

$("#container").append("<i id='heart' class='far fa-heart'></i>");
$(".far").on("click", function() {
  console.log("clicked");
});

This example works fine with FontAwesome 4.7 as the element isn't being replaced.

like image 985
Joe Jankowiak Avatar asked Dec 17 '17 06:12

Joe Jankowiak


2 Answers

In best situation pointer-events: none; will fix the svg click listener issue. but in this case this solution not work. I have a better solution for you, set onclick attribute on <i> tag and handle a jquery function with javascript.

$("#heart").attr('onClick', 'callFunction(this)');

But as i said in comment toggleClass or anything for changing class not solve your problem, because it convert <i> tag to svg so you can't change shape of heart by toggling class name. the only solution is change it before convert to svg like this:

 var click = false;
  function callFunction(el) {
    if (!click) {
      $("#container").empty().append("<i id='heart' class='fas fa-heart'></i>");
      $("#heart").attr('onClick', 'callFunction(this)');
      click = true;
    } else {
      $("#container").empty().append("<i id='heart' class='far fa-heart'></i>");
      $("#heart").attr('onClick', 'callFunction(this)');
      click = false;
    }
  }

Working Demo

like image 168
Pedram Avatar answered Nov 09 '22 05:11

Pedram


Fontawsome has a great example of how to handle click events on their site.

This method worked great for me as I was looking to "toggleClass" onClick. Seems a bit simpler than the previous answer. I have tested this and it's working well.

document.addEventListener('DOMContentLoaded', function () {
$('button').on('click', function () {
  $(this)
    .find('[data-fa-i2svg]')
    .toggleClass('fa-angle-down')
    .toggleClass('fa-angle-right');
  });
});

Examples Here

I decided to add my own example for anyone struggling with this:

document.addEventListener('DOMContentLoaded', function () {
  jQuery('.ppolicy-link').on('click', function () {
            var collapsed=jQuery(this).find('[data-fa-i2svg]').hasClass('fa-plus-square');
            jQuery('.btn-link').find('[data-fa-i2svg]').removeClass('fa-minus-square');
            jQuery('.btn-link').find('[data-fa-i2svg]').addClass('fa-plus-square');
            if(collapsed)
                jQuery(this).find('[data-fa-i2svg]').toggleClass('fa-plus-square fa-minus-square')
        });
    });

I'm using jQuery no-conflict and Bootstrap 4 accordion, WordPress. This is working great for me.

like image 34
ben.kaminski Avatar answered Nov 09 '22 04:11

ben.kaminski