2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Rails7]submitにつけるdisable_withオプションについて

Last updated at Posted at 2024-06-19

はじめに

Rails7以前までは[Rails]submitタグにつけておきたいdisable_withオプションの記事にあるように、data属性にdisable_withを付与すれば、二重送信が防止できておりました。

= form_with(model: model) do |form|
  = form.submit '登録', { data: { disable_with: '登録中・・・' }

ですが、Rails7移行では、disable_withオプションが機能しなくなっているので、どのように実現したかを残しておきます。

どう変わったのか

Rails 7.0 + Ruby 3.1でゼロからアプリを作ってみたときにハマったところあれこれ
の記事にある通り、クラスで登録登録中・・・の表示を切り替えています。

turboのPRを覗いて見てもあんまり親切じゃないです。

サンプル

では、どのように二重送信を防止するかのサンプルです。

some_form.html.slim
= form_with(model: model, data: { controller: 'form', action: 'submit->form#disableSubmitter' }) do |form|

  button.submit_button data-form-target='submitter'
    span.show-when-enabled 登録
    span.show-when-disabled 登録中・・
application.tailwind.css
@tailwind base;
@tailwind components;
@tailwind utilities;

/* 送信ボタン disabled 切り替え */
button {
  .show-when-disabled {
    @apply hidden;
  }

  .show-when-enabled {
    @apply inline;
  }
}

button:disabled {
  .show-when-disabled {
    @apply inline;
  }

  .show-when-enabled {
    @apply hidden;
  }
}
form_controller.js
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static targets = ["submitter"];

  disableSubmitter() {
    this.submitterTarget.disabled = true;
  }
}

formをsubmitするときにdisableSubmitterを呼び、submitterのdisabedをtrueにしています。

BE側のバリデーションのみの場合はこちらで機能します。

フロント側でバリデーションをする場合

FE側でもバリデーションをする場合は少し工夫が必要です。

some_form.html.slim
= form_with(model: model, data: { controller: 'form', action: 'submit->form#disableSubmitter' }) do |form|

  button.submit_button data-form-target='submitter'
    span.show-when-enabled 登録
    span.show-when-disabled 登録中・・

view側は同じです。

form_controller.js
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static targets = ["submitter"];

  disableSubmitter() {
    this.submitterTarget.disabled = true;

    if (!this.validateForm()) {
      event.preventDefault(); // フォーム送信をキャンセル
      this.submitterTarget.disabled = false;
    }
  }

  validateForm(){
    // some validations
  }
}

バリデーションがfalseの場合は、フォームの送信をキャンセルし、submitterのdisabledをfalseにし、再度submitできるようにしています。

まとめ

Rails7でFormの二重送信防止方法を紹介しました。
これまで通りdisable_withで二重送信防止ができると思っていたら、実はできていなかった...。
そんなことにならないように、一役立てれば幸いです。

参考

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?