Switch between icons when using FontAwesome 5.0 SVG Framework

24.3k views Asked by At

I'm looking to be able to switch between icons in Javascript while using the new FontAwesome SVG framework.

Previously in the old WebFont method, this was achieved by toggling or changing the class on the tag, however as these are now rendered as SVG's in the source code this no longer works.

Is there a way to do this without needing to render both SVG icons in source code and using additional classes/CSS to toggle display?

9

There are 9 answers

1
Pascal On BEST ANSWER

Font Awesome 5.0.0 has just been released and the migration from 4.7 to 5.0 wrecked up my javascript/jquery to change a "fa-star-o" icon to "fa-star" when the user clicks on it.

I managed to fix it so I wanted to share with you these two tips:

The icon in HTML:

<i class="foo fas fa-star"></i>

1) Change icon with jQuery (from "star" to "alarm-clock" and vice versa):

var icon = $('.foo');
var icon_fa_icon = icon.attr('data-icon');

if (icon_fa_icon === "alarm-clock") {
    icon.attr('data-icon', 'star');
} else {
    icon.attr('data-icon', 'alarm-clock');
}

2) Change icon-style with jQuery (from 'fas' to 'far'):

var icon = $('.foo');
var icon_fa_prefix = icon.attr('data-prefix');

if (icon_fa_prefix === 'fas') {
    icon.attr('data-prefix', 'far');

} else {
    icon.attr('data-prefix', 'fas');
}

Hope that helps anyone with the same issue.

0
Mario Lurig On

Verified with FA 5.0.0 using the recommended JS method for loading icons

HTML

<div id='icon'><i class='far fa-eye-slash'></i></div>

This is what the HTML code looks like once the page is rendered, prior to a click:

<div id="icon"><svg class="svg-inline--fa fa-eye-slash fa-w-18" aria-hidden="true" data-fa-processed="" data-prefix="far" data-icon="eye-slash" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M272.702 359.139c-80.483-9.011-136.212-86.886-116.93-167.042l116.93 167.042zM288 392c-102.556 0-192.092-54.701-240-136 21.755-36.917 52.1-68.342 88.344-91.658l-27.541-39.343C67.001 152.234 31.921 188.741 6.646 231.631a47.999 47.999 0 0 0 0 48.739C63.004 376.006 168.14 440 288 440a332.89 332.89 0 0 0 39.648-2.367l-32.021-45.744A284.16 284.16 0 0 1 288 392zm281.354-111.631c-33.232 56.394-83.421 101.742-143.554 129.492l48.116 68.74c3.801 5.429 2.48 12.912-2.949 16.712L450.23 509.83c-5.429 3.801-12.912 2.48-16.712-2.949L102.084 33.399c-3.801-5.429-2.48-12.912 2.949-16.712L125.77 2.17c5.429-3.801 12.912-2.48 16.712 2.949l55.526 79.325C226.612 76.343 256.808 72 288 72c119.86 0 224.996 63.994 281.354 159.631a48.002 48.002 0 0 1 0 48.738zM528 256c-44.157-74.933-123.677-127.27-216.162-135.007C302.042 131.078 296 144.83 296 160c0 30.928 25.072 56 56 56s56-25.072 56-56l-.001-.042c30.632 57.277 16.739 130.26-36.928 171.719l26.695 38.135C452.626 346.551 498.308 306.386 528 256z"></path></svg><!-- <i class="far fa-eye-slash"></i> --></div>

JQUERY (on click used)

$("#icon").click(function() {
  // Change the child svg attribute data-icon to the new icon (remove fa-)
  $("#icon > svg").attr('data-icon','eye');
});

This will change the icon from eye-slash to eye.

Edit: Dec 20, 2017
As of Font Awesome 5.0.1, when using the Javascript version you can now add/remove classes as before, it just needs to be on the svg element rather than the original element (assuming i).

Updated code:

$("#icon").click(function() {
  // Change the child svg attribute data-icon to the new icon (remove fa-)
  $("#icon > svg").addClass('fa-eye').removeClass('fa-eye-slash');
});

Also note that any applied ids or classes to the font awesome element will be brought over to the svg. Thus if you have <i id='eyecon' class='eyecon fa fa-eye'> then it will render the <svg id='eyecon' class='eyecon'>.

0
Eonasdan On

For a plain JS example (password reveal)

//event = mouse click
const passwordInput = event.currentTarget
    .closest('.input-group')
    .querySelector('input');
let icon = 'eye-slash';
let newType = 'text';

// type is text, set to password and change icon to eye
if (passwordInput.getAttribute('type') === 'text') {
    icon = 'eye';
    newType = 'password';
}
passwordInput.setAttribute('type', newType);
event.currentTarget
    .querySelector('svg')
    .setAttribute('data-icon', icon);
0
Steven On

Verified with FA 5.0.2

I modified the original documentation found on Font-Awesome's website here. The selector on their website wasn't selecting the proper element, so we need to modify the attribute.

HTML

<div class='icon'><i class='far fa-minus-square'></i></div>

The class of the div doesn't really matter so much as we can change it. Looking at the javascript, we are using the element to find the svg and specifically, we are looking for the data-icon attribute. Once we know the data attribute, we can change it every time it is clicked.

So in this case, it starts off with the minus-square. If the icon is the minus-square, it changes it to the plus-square. If it is not the plus-square, it will change it to the minus-square.

JQuery

  document.addEventListener('DOMContentLoaded', function () {
    $('.icon').on('click', function () {
      if ($(this).find('svg').attr('data-icon') == 'minus-square' ) {
        $(this).find('svg').attr('data-icon', 'plus-square');
      } else {
        $(this).find('svg').attr('data-icon', 'minus-square');
      };
    });
  });

0
Harry On

HTML

<button class="btn btn-primary" id="menu-toggle">
            <span id="menu-arrow-left" class='fa fa-fast-backward' aria-hidden="true"></span>
            <span id="menu-arrow-right" class='fa fa-fast-forward' style="display: none;" aria-hidden="true"></span>
        </button>

Jquery

$("#menu-toggle").click(function(e) {
      e.preventDefault();
      $("#wrapper").toggleClass("toggled");
      $('#menu-arrow-left').toggle();
      $('#menu-arrow-right').toggle();
    });

I feel this to be the most basic and aptful solution.

1
csb On

I had the same problem as well, and I found (after scrolling right to the very end) that the FontAwesome website states the following:

Nest <svg> tags instead of replacing

There may be some cases where the replacement of the <i> tag is just not working out like you need it to.

You can configure Font Awesome to nest the within the tag.

To do so, just the FontAwesomeConfig object and set autoReplaceSvg: 'nest'.

<script>
    FontAwesomeConfig = { autoReplaceSvg: 'nest' }
</script>
1
Blitzlord On

Didn't find any documentation about this. As it's not offically released yet, you can use this workaround (jQuery):

$('svg.fa-toggle-off').replaceWith('<i class="fas fa-toggle-on"></i>');
0
Pawel On

This is what I found worked best for me. I was using self-hosted Fontawesome v5.7.1

HTML (note two icons, one with .hidden class)

<a id="delete_btn" href="#">
  <i class="icon fas fa-trash"></i>
  <i class="spinner fas fa-spinner fa-spin hidden"></i>
  <div class="caption">Delete</div>
</a>

CSS

.hidden {
  display: none;
}

jQuery

$('#delete_btn').click( function() {
  var fa_icon = $('#delete_btn .icon');
  var fa_spin = $('#delete_btn .spinner');
  fa_icon.addClass('hidden');
  fa_spin.removeClass('hidden');

  //do something

  fa_spin.addClass('hidden');
  fa_icon.removeClass('hidden');
});
3
nicozica On

Assuming you are using the recommended method with the fontawesome.js sheet, I found this on the official documentation:

Changing icons by changing class:

<button>Open up <i class="fa fa-angle-right"></i></button>

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