📎

【Rails】超簡単!コピーボタンを実装する方法

2025/02/03に公開

はじめに

お疲れ様です。
おおくまです。

今回は、「【Rails】超簡単!コピーボタンを実装する方法」ということで、Ruby on Railsで、コピーボタンを実装する方法について、まとめてみました。

とても簡単に実装できるので、ぜひ実装してみてください。

少しでも皆様の参考になりますと幸いです。

対象読者

注意点

環境

前提

今回は、Postテーブルのcontentカラムの内容をコピーするボタンを実装していきたいと思います。
以下のようなPostテーブルを作成しました。

db/schema.rb
create_table "posts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
  t.bigint "user_id", null: false
  t.string "title", null: false
  t.text "content", null: false
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.index ["user_id"], name: "index_posts_on_user_id"
end

一覧画面は以下のようになっています。

app/views/posts/index.html.slim
div.p-5
  h1.mb-3 投稿一覧
  p style="color: green" = notice
  = link_to "新規追加", new_post_path, class: 'btn btn-outline-info btn-sm m-3'
  .d-flex.flex-wrap.align-items-center
    - @posts.each do |post|
      .card.border.m-3 style="width: 400px;"
        .card-header.h5 = post.title
        .card-body
          .mb-3 = post.content
          = link_to "詳細", post, class: 'btn btn-outline-secondary btn-sm mr-1'
          = link_to "編集", edit_post_path(post), class: 'btn btn btn-outline-info btn-sm mr-1'
          = link_to "削除", post, method: :delete, data: { turbo: "true", turbo_method: :delete, turbo_confirm: '削除しますか?' }, class: "btn btn-outline-danger btn-sm"

実装

JavaScriptの実装

まずは、app/javascript/controllersディレクトリにcopy.jsファイルを作成します。

app/javascript/controllers/copy.js
document.addEventListener('DOMContentLoaded', () => {
  document.querySelectorAll('.copy-button').forEach(button => {
    button.addEventListener('click', () => {
      const targetId = button.getAttribute('data-target');
      const targetElement = document.getElementById(targetId);
      const content = targetElement.innerText;
      navigator.clipboard.writeText(content)
      .then(() => {
        const originalText = button.querySelector('.copy-text');
        originalText.textContent = 'コピーしました';
        setTimeout(() => {
          originalText.textContent = 'コピー';
        }, 2000);
      })
    });
  });
});

application.jsに以下のように追記し、copy.jsを読み込みます。

app/javascript/application.js
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "controllers"
import "jquery"
import "bootstrap"
import "admin-lte"
+ import "controllers/copy";

Viewの実装

次に、Postレコード毎にコピーボタンが表示されるようにViewファイルを修正します。

app/views/posts/index.html.slim
div.p-5
  h1.mb-3 投稿一覧
  p style="color: green" = notice
  = link_to "新規追加", new_post_path, class: 'btn btn-outline-info btn-sm m-3'
  .d-flex.flex-wrap.align-items-center
    - @posts.each do |post|
      .card.border.m-3 style="width: 400px;"
        .card-header.h5 = post.title
        .card-body
+         .float-right
+           button.copy-button.btn.btn-outline-secondary.btn-sm data-target="post_#{post.id}"
+             i.far.fa-copy.mr-1
+             span.copy-text コピー
+         div id="post_#{post.id}"
            .mb-3 = post.content
          = link_to "詳細", post, class: 'btn btn-outline-secondary btn-sm mr-1'
          = link_to "編集", edit_post_path(post), class: 'btn btn btn-outline-info btn-sm mr-1'
          = link_to "削除", post, method: :delete, data: { turbo: "true", turbo_method: :delete, turbo_confirm: '削除しますか?' }, class: "btn btn-outline-danger btn-sm"

コピーボタンの実装は以上です。

動作確認

Postレコード毎に表示されているコピーボタンをクリックすると、それぞれのcontentカラムの内容がクリップボードにコピーされることが確認できました。

解説

書いたコードは、以下の流れで動作しています。

  1. document.querySelectorAll('.copy-button')で、copy-buttonクラスを持つボタンを全て取得し、それぞれにクリックイベントを設定。

  2. クリックされたボタンのdata-target属性から、コピー対象の要素のIDを取得。

  3. 取得したIDを元に、コピー対象のテキストをクリップボードにコピー。

  4. コピーが成功した場合、ボタン内のテキストを「コピーしました」に変更し、2秒後に元に戻す。


↓そもそものコピーの仕組みについては、以下の動画が分かりやすいです。
https://www.youtube.com/shorts/nePdQ9XLM4g

まとめ

今回、Ruby on Railsで、コピーボタンを実装する方法について、まとめてみました。

とても簡単に実装することができました。

あると便利な場面もあるかと思いますので、ぜひ実装してみてください。

少しでも皆様の参考になりますと幸いです。

最後まで読んでいただき、ありがとうございました。

GitHubで編集を提案
株式会社L&E Group

Discussion