Migrating from Rails UJS to Hotwire: Data Method, Confirm, and Disable With Discussion
Small comment about those delete links (I really dislike using links for delete requests): when you need to put a delete button inside form, consider moving the submit button outside of the form instead by using the form-attribute on the submit button (not supported in IE, but who cares)
Thanks for the video Chris ! Really cool to see those new features in action.
For those who are wondering, the possibility to override the confirm modal has also been ported to Turbo. To use a custom dialog, simply set it like that, on your application.js
for instance:
const newConfirmMethod = (message, formElement) => confirm("overriden method")
Turbo.setConfirmMethod(newConfirmMethod)
I'm really confused about what turbo is... I haven't used it myself yet, but I didn't know it included these features you are highlighting here like data-turbo-method
and data-turbo-confirm
... I'm STILL having trouble finding those in the Turbo documentation. Where do I see these features in Turbo docs, and see what other features like this, ujs-like features, Turbo has?
I agree Turbo docs lack some new features that have been implemented recently. The usage section in the turbo-rails
docs even invite people to read the code directly.
The Turbo releases page could be a good start to keep track of all the new additions to the libray IMO
Great video Chris.
I tried replicating this on a rails app that I'm working on, however, I can't quite get the same behaviour. When I hit on the Submit button nested within a form_with tag, the submit doesn't seem to get disabled after the first click. This means that the form can be submitted twice creating some funny errors.
Any idea why this may be happening?
Hi everyone. I would like to have SWAL2 triggered instead of normal JS confirm popup and I have managed to do that with a link_to and stimulus controller + Request.js - but only if i return turbo_stream with destroy.turbo_stream.erb and remove/replace something on the same page.
Now i am struggling in achieving basically exactly the same thing - but redirecting to a different page.
I am comparing logs of normal delete as Chris has shown in the video and my approach and there is no differences at all. But In my case, with SWAL, nothing changes on the page and it basically renders to i don't know what. Page just stays the same and although in the log i can clearly see redirect and 303 and get, it doesn't do that. I don't even have turbo_stream respond (just like Chris doesn't) and there is absolutely no turbo-frames in the page. But to me it seems it's like it just logs 303, but in reality just tries to render to the same page and as there is no turbo-frame it basically renders to /dev/null :)
Can somebody maybe explain how i could have delete, SWAL and redirects?
Maybe i am over complicating with Request.js, but i don't know how to do it differently.
Thank you
Reply to myself: i figured out i am doing remote request, so it is normal that it does not work :), stupid me. But i would still like to know how to do it properly with SWAL. It's a tough one for me.
Reply 2 :) - i've been able to make it work with button_to which wraps it in the form, and then in stimulus controller i prevent default, find closest "form" and after swal is confirmed send request with form.submit. That's the only way i see how. As soon as i fiddle around with turbo etc, it's chaos. But it works and it's fine.
Thanks for this I was mostly interesting in the disable_with: 'blah' replacement, but your example tackled the button only approach. Without any additional changes to trigger the button to be disabled so I assume that Turbo always disables the button. However, it's not going to do that to just any link. Unless it does of course by default if it is has a turbo-method attribute. or a data-turbo-confirm.
I implemented Chris' approach with below code. However it only considers "Create" (whereas with a f.submit button the text becomes flexible "Create" or "Update"). How would you accommodate this for edit scenario?
<%= form.button class: 'btn btn-primary' do %>
<span class="show-when-enabled">Create Post</span>
<span class="show-when-disabled">Processing...</span>
<% end %>
<span class="show-when-enabled"><%= f.object.new_record? ? "Create Post" : "Update Post" %></span>
will get you there.
Using tailwindcss in the new rails 7, turbo and stimulus world. I was able to achieve this like:
Note the use of group
on the parent object (the submit button) and then the hidden
, group-disabled:hidden
and group-disabled:flex
on the child spans.
<%= f.button class: "btn-primary group" do %>
<span class="group-disabled:hidden h-4">Go!</span>
<span class="hidden group-disabled:flex">
<svg aria-hidden="true" class="mr-2 w-4 h-4 text-yellow-500 animate-spin fill-white" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/>
<path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/>
</svg>
Processing...
</span>
<% end %>
I grabbed the spinner svg from this example at https://flowbite.com/docs/components/spinner/
I exactly followed the example, but it doesn't work for me. The form is submitted but the button is not disabled and the text is not changing. Do I miss some JS magic? Any ideas?
My pragmatic solution for right is this:
<%= f.submit :class => "btn btn-primary brndc",
:value => t('general.btn_update'),
:onclick => "this.form.submit(); this.disabled=true; this.value='Sending…';" %>