font awesomeのトグルボタンを作る


font awesomeでtoggleButtonを作るのに苦労した

苦労した点

  1. appendでHTMLを差し替えるとfont awesomeの大きさと色がおかしくなりました。
  2. toggleClassで"far"と"fas"のみをtoggleするとclass名が末尾に追加され、値が適切に取得できませんでした。
    ex)"far fa-3x fa-bookmark"が"fa-3x fa-bookmark far"になりclassList[0]がfa-3xに変化します。

解決策

  1. toggleClassでクラス名だけを変更する
    appendでHTMLをまるごと差し替えるのではなく、toggleClassでクラス名だけを変更すると適切にCSSが適応され、解決できました。
  2. toggleClassで複数のclassを同時に指定する
    toggleClassは複数のclassを同時に指定できました!
    "far fa-3x fa-bookmark"とまるごと指定することでclass名の順序を変えることトグルできました。
    その結果classList[0]でfarを所得することに成功しました!

実際のコード

以下はjavascriptの非同期通信を用いたお気に入り機能の実装

_wordbook.html.haml
- if defined? fav
  - fav_id = fav.wordbook.id
- id = wordbook.id
- if user_signed_in?
    .wordbook__fav{"data-fav": fav_id}
      = button_tag do
        - if fav_id == id
          = icon("fas fa-3x", "bookmark")
        - else
          = icon('far fa-3x', 'bookmark')
fav.js
$(function(){
  // いいねの生成
  function like (id, status, button){
    var wordbook_id = id;
    var url = `api/wordbooks/${wordbook_id}`;
    var method = status == "far" ? "PATCH" : "DELETE";
    $.ajax({
      url: url,
      type: method
    })
    .done(function(){
      button.toggleClass("far fa-3x fa-bookmark");
      button.toggleClass("fas fa-3x fa-bookmark");
    })
    .fail(function(){
      window.alert("error");
    });
  }

  $(".wordbook__fav").on("click",function(){
    var id = $(this).parent()[0].dataset.id;
    var button = $(this).find("i");
    var status = button[0].classList[0];
    like(id, status, button);
  });
});
api/wordbooks_controller.rb
class Api::WordbooksController < ApplicationController
  def update
    @fav = Favorite.create(user_id: current_user.id,wordbook_id: params[:id])
  end
  def destroy
    @fav = Favorite.where(wordbook_id: params[:id]).find_by(user_id: current_user.id)
    @fav.destroy
  end
end

環境

Ruby 2.5.1
Ruby on Rails 5.2.3
gem "jquery-rails"
gem "font-awesome-sass"