如何在 Rails 和 Turbo 中使用 button_to 调用确认提示

mec*_*cov 12 ruby-on-rails turbo ruby-on-rails-7

以前在 Rails 中使用button_to标签时,可以使用这样的确认对话框

<%= button_to 'Destroy', @post, method: :delete, data: { confirm: 'Are you sure?' } %>
Run Code Online (Sandbox Code Playgroud)

data: { confirm: 'Are you sure?' }是 @rails/ujs 库在幕后使用的 Rails 魔法数据属性

在 Rails 7 之后,默认情况下该库不再打开。使用 Turbo 库代替 Rails

现在这段代码不起作用

Rails 官方文档Turbo 手册中没有任何信息

我尝试过的

<%= button_to 'Destroy', @post, method: :delete, data: { turbo_confirm: 'Are you sure?' } %>
<%= button_to 'Destroy', @post, method: :delete, data: { 'turbo-confirm': 'Are you sure?' } %>
Run Code Online (Sandbox Code Playgroud)

但没有结果

我没有找到任何解决方案,但在 Hotwire论坛上找到了。此解决方案具有刺激作用。我只是稍微改进一下

<%= form_with model: @post, method: :delete, data: { controller:  'confirmation', message: 'Are you sure?', action: 'submit->confirmation#confirm' } do |f| %>
  <%= f.submit 'Destroy' %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
// app/javascript/confirmation_controller.js
import { Controller } from '@hotwired/stimulus'

export default class extends Controller {
  confirm(event) {
    if (!(window.confirm(this.element.dataset.message))) {
      event.preventDefault()
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

它可以工作,但是相当困难并且看起来很丑,而且我们已经习惯了 Rails 的酷

mec*_*cov 22

在没有rails-ujs的带有Turbo的Rails中,button_to我们需要使用这样的代码来调用确认弹出窗口

<%= button_to 'Destroy', @post, method: :delete, form: { data: { turbo_confirm: 'Are you sure?' } } %>
Run Code Online (Sandbox Code Playgroud)

或者

<%= button_to 'Destroy', @post, method: :delete, form: { data: { 'turbo-confirm': 'Are you sure?' } } %>
Run Code Online (Sandbox Code Playgroud)

两者都生成data-turbo-confirm属性

所以我们需要添加这个属性,而不是提交按钮(就像在rails-ujs中),而是直接添加到包含这个按钮的表单(让我提醒你这个标签生成一个带有按钮的表单)

  • @YakobUbaidi如果你的“destroy”操作以“redirect_to”结束(我怀疑这是你的情况),一些浏览器将使用“DELETE”方法重定向到一个新位置,所以请确保添加“status: :see_other”参数`redirect_to`,就像指南[建议](https://guides.rubyonrails.org/getting_started.html#deleting-an-article) (3认同)

wai*_*ver 9

这在 7.0.3 中有点复杂,如果是使用 Turbo 的页面,它看起来像这样:

  <%= button_to "Delete",
                  user_path(user),
                  method: :delete,
                  class: "button tight danger",
                  form: { 
                   data: { 
                     turbo_confirm: "Are you sure you want delete?"
                   }
                  } %>
Run Code Online (Sandbox Code Playgroud)

这形成了一个小形式。现在,如果您使用 Turbo,但不在该特定页面上,您将不再comfirm: 'message'从旧的 Rails ujs 中获得简单的信息。相反,你必须使用刺激控制器。

# app/javascript/controllers/confirmation_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static values = { message: String };

  confirm(event) {
    if (!(window.confirm(this.messageValue))) {
      event.preventDefault();
      event.stopImmediatePropagation();
    };
  };
}
Run Code Online (Sandbox Code Playgroud)

然后

# app/javascript/controllers/index.js
import ConfirmationController from "./confirmation_controller"
application.register("confirmation", ConfirmationController)
Run Code Online (Sandbox Code Playgroud)

然后

    <%= button_to "Delete",
                  user_path(user),
                  method: :delete,
                  class: "button danger",
                  form: {
                    data: {
                      turbo: false,
                      controller: "confirmation",
                      action: 'submit->confirmation#confirm',
                      confirmation_message_value: "Are you sure you want to delete?",
                    }
                  } %>
Run Code Online (Sandbox Code Playgroud)

Rails 删除了功能,这真是令人遗憾,但如果您想使用 Hotwire,您需要承诺完全支持整个生态系统。

  • 这涵盖了所有基础!带/不带涡轮! (2认同)