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

11
以前在Rails中使用button_to标签时,可以像这样使用确认对话框。
<%= button_to 'Destroy', @post, method: :delete, data: { confirm: 'Are you sure?' } %>

data: { confirm: '你确定吗?' } 是Rails的神奇数据属性,它在底层被@rails/ujs库使用。

从Rails 7开始,默认情况下不再使用这个库。取而代之的是Rails使用Turbo库。

现在这段代码不起作用了。

在官方的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?' } %>

但是没有结果
我在SO上没有找到任何解决方案,但在Hotwire上找到了论坛。这个解决方案使用了Stimulus动作。我只是稍微改进了一下。
<%= form_with model: @post, method: :delete, data: { controller:  'confirmation', message: 'Are you sure?', action: 'submit->confirmation#confirm' } do |f| %>
  <%= f.submit 'Destroy' %>
<% end %>

// 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()
    }
  }
}

它能用,但是相当困难且看起来不美观,而我们习惯了Rails的酷炫。
5个回答

21

在没有使用rails-ujs的情况下,使用Turbo框架在Rails中调用确认弹出窗口需要使用以下代码:

<%= button_to 'Destroy', @post, method: :delete, form: { data: { turbo_confirm: 'Are you sure?' } } %>
或者
<%= button_to 'Destroy', @post, method: :delete, form: { data: { 'turbo-confirm': 'Are you sure?' } } %>

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

因此,我们需要将此属性添加到包含此按钮的表单中(而不是像在rails-ujs中一样添加到提交按钮),直接添加到该按钮所在的表单(请注意,此标记会生成一个带有按钮的表单)


我在使用 link_tomethod: :delete 时遇到了奇怪的问题。它会删除当前记录,但也会删除其父记录,这让我感到很困惑。 - Yakob Ubaidi
3
如果您的“destroy”操作以“redirect_to”结束(我怀疑这是不可能的),某些浏览器将使用“DELETE”方法重定向到新位置,因此请确保添加status: :see_other参数到redirect_to中,就像指南建议的那样。 - mechnicov

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?"
                   }
                  } %>

这创建了一个小表单。现在如果您正在使用 Turbo,但不是在那个特定页面上,您将不再从旧的 Rails UJS 中获得简单的 comfirm: 'message',而是需要使用 stimulus controllers。

# 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();
    };
  };
}

那么
# app/javascript/controllers/index.js
import ConfirmationController from "./confirmation_controller"
application.register("confirmation", ConfirmationController)

那么。
    <%= 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?",
                    }
                  } %>

很遗憾,Rails移除了一些功能,但如果你想使用Hotwire,就需要全情投入到整个生态系统中。

2
这包含了所有的基础!有/没有涡轮! - Kulbir Saini
无法工作 - Rails 7.0.4 - Wordica
对我来说,在Rails 7.0.4.2上运行正常。 - undefined

1

这不是原问题,但在 Rails 7.0.4 版本中,它将以相同的方式工作(无需 Stimulus):

<%= link_to("Del",
            del_path,
            data: { turbo_method: :delete, turbo_confirm: "Sure?" }) %>

1
无法在Rails 7.0.4中工作 - 整天寻找解决方法。 - Wordica
你正在运行一个全新的应用程序吗? - Ben

0
我不完全理解这个,但以下内容对我有用: <%= button_to post_path(post), method: :delete, form: { data: { turbo_confirm: 'Are you sure?' } } do %> 一个显示垃圾桶的 SVG <% end %>
我也没有看到 OP 的 confirmation_controller。

这与 https://dev59.com/AVEG5IYBdhLWcg3wMGIK#70994323 相同 :) - mechnicov
@mechnicov 是的,但我有点困惑;那个链接返回到了这个页面。但无论如何,我并不是要为这个想法获得荣誉。 - Greg
这适用于表单中的按钮,而不适用于link_to。 - Wordica

0

在进行 Ruby on Rails 指南这里时,我遇到了同样的问题。

使用 button_tomethod: :delete 进行操作可以使删除有效,但确认仍然无法正常工作。


在我尝试过程中,我偶然发现了turbo-rails宝石的提及。我使用以下代码找到了可行的解决方案:

  1. application.html.erb文件中添加以下内容:
    <%= javascript_include_tag "turbo", type: "module" %>
    
  2. 在Gemfile中添加gem "turbo-rails", "~> 1.0"
  3. 运行bundle install
  4. 运行bin/rails turbo:install
    注意:不确定是否需要执行此最后一步,但我是按照这里的说明操作的。
使用这些步骤,Rails指南中的代码可以正常工作,并且包括确认对话框。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接