Search code examples
ruby-on-railsruby-on-rails-7

Rails 7.0.4 and data confirm for link_to doesn't work


My last chance is some last living developer in RoR

Nothing in the darkest corners of the internet works for:

<%= link_to 'some-link', '#', data: { confirm:'Are You Sure?') %>;

it generate this:

<a data-confirm="Are you sure?" href="#">some link</a>

but there is no confirm dialog box.

I try everything - turbo_confirm, try to add controller with class for stimulus ... and still nothing.

Right now I remove turbo-rails, stimulus etc. - but still nothing.


Solution

  • data-turbo-confirm presents a confirm dialog with the given value. Can be used on form elements or links with data-turbo-method.

    https://turbo.hotwired.dev/reference/attributes

    Examples that work

    <%= link_to "GET turbo link", "/",
      data: {
        turbo_method: :get,
        turbo_confirm: "Sure?"
      }
    %>
    
    <%= link_to "POST turbo link", "/",
      data: {
        turbo_method: :post,
        turbo_confirm: "Sure?"
      }
    %>
    
    <%= button_to "Button", "/",
      data: { turbo_confirm: "Sure?" }
    %>
    
    <%= form_with url: "/",
      data: { turbo_confirm: "Sure?" } do |f| %>
    
      <%= f.submit "Submit" %>
    <% end %>
    

    Doesn't work

    <%= link_to "GET link", "/",
      data: { turbo_confirm: "Sure?" }
    %>
    

    Fix by adding turbo_method: :get.


    @hirowatari edit:

    <%= link_to "GET external link", "http://example.com",
      data: {
        turbo_method: :get,
        turbo_confirm: "Sure?"
      }
    %>
    

    External links or links with extensions (other than .html or .php) will be ignored by Turbo. I think this is one of the reasons data-turbo-confirm and similar Rails UJS features were not initially implemented in Turbo. You'll be better off implementing your own data-confirm feature if you're migrating from Rails UJS, it is very simple, you won't have to change attributes to data-turbo-confirm, and it will just work on any click. See example below.

    Really doesn't work

    <%= link_to "UJS link", "/",
      data: { confirm: "Sure?" }
    %>
    

    But easy to fix:

    // app/javascript/application.js
    
    // this is now my preferred way of dealing with confirmation dialog
    // it is just much simpler than Turbo way
    document.addEventListener("click", event => {
      const element = event.target.closest("[data-confirm]")
    
      if (element && !confirm(element.dataset.confirm)) {
        event.preventDefault()
      }
    })
    

    data-disable-with

    Update Use data-turbo-submits-with to handle this.

    This one is a bit more involved, but it's all the same pattern, listen for event, check for data attribute, if else, do something.

    // app/javascript/application.js
    
    // on form submit
    // set `value` if `input`
    // set `innerHTML` if `button`
    document.addEventListener("turbo:submit-start", event => {
      const element = event.detail.formSubmission.submitter
      if (element.hasAttribute("data-disable-with")) {
        // element.disabled = true // this is done by turbo by default
        if (element instanceof HTMLInputElement) {
          element.value = element.dataset.disableWith
        } else {
          element.innerHTML = element.dataset.disableWith
        }
      }
    })
    
    <%= form_with url: "/" do |f| %>
      # <button>
      <%= f.button "Submit", data: { disable_with: "..." } %>
      # <input>
      <%= f.submit "Submit", data: { disable_with: "..." } %>
    <% end %>