![Portrait of Andy Leverenz](/assets/andy-leverenz-05eeaa58cdbdf4b6c041a71b4373d47a2cc0badd643644f1d17b1ab76d3bf6c6.jpg)
July 2, 2024
•Last updated July 2, 2024
Building Turbo Loading Buttons in Rails: A Step-by-Step Guide
Using Turbo from the Hotwire framework, we can create a nifty feature I'm dubbing "loading buttons." These buttons enhance the user experience by providing real-time feedback and making your Rails app look sleek and professional. Let's walk through how to implement this in your Rails application step by step.
Why Turbo Loading Buttons?
Before getting into the nitty-gritty, let's understand why Turbo-enabled loading buttons are valuable. Imagine filling out a form on a website and hitting the submit button.
If the process takes a few seconds, you might wonder if anything is happening. This uncertainty can lead to repeated clicks, resulting in duplicate submissions or user frustration.
Turbo-enabled loading buttons solve this problem by providing immediate visual feedback that the process is underway. This improves the user experience, making your application more responsive and polished.
Getting Started with Rails and Turbo Loading Buttons
First things first, let's set up a new Rails application. Open your terminal and run the following command to create a new Rails app:
rails new turbo_loading_button
Once your new Rails application is created, navigate into the project directory:
cd turbo_loading_button
To make our life easier, we’ll include the railsui
gem. This gem will help us streamline the UI components so we don't have to reinvent the wheel. Add it to your Gemfile
:
gem 'railsui', github: 'getrailsui/railsui', branch: 'main'
Now, run bundle install
to install the gem:
bundle install
After the gem is installed, set it up in your project. Run the following command:
rails railsui:install
Finally, start the server using:
bin/dev
Our environment is set up, and we’re ready to scaffold a new resource.
Scaffolding a Post Resource
For this example, we’ll create a simple Post
resource. Run the following command to generate it:
rails g scaffold Post title:string content:text
This command will generate all the files for our Post resource, including the model, views, and controller.
Don’t forget to set the root route to the posts index page by editing your config/routes.rb
file:
root 'posts#index'
Next, we’ll add a delay to the create
action in the PostsController
to simulate a slow process. This will help us test the loading button. Open app/controllers/posts_controller.rb
and modify the create
method as follows:
def create
@post = Post.new(post_params)
sleep 6
respond_to do |format|
if @post.save
format.html { redirect_to post_url(@post), notice: "Post was successfully created." }
format.json { render :show, status: :created, location: @post }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
end
end
The sleep 6
line will introduce a 6-second delay, simulating a slow network or processing time. This will help us see the loading buttons in action.
Implementing a Simple Turbo Loading Button
Our first approach will be straightforward. We’ll add a loading message to the submit button using the data-turbo-submits-with
attribute. Open app/views/posts/_form.html.erb
and modify the submit button like so:
<%= form.submit class:"btn btn-primary", data: { turbo_submits_with: "Saving..." } %>
With this setup, when you submit the form, the button text will change to "Saving..." while the form is being processed. Simple, yet effective! Unfortunately, outside of text, you can't do much here to change the UI itself, like button style or displaying something else in place of the button. We'll address this coming up.
What Just Happened?
The data-turbo-submits-with
attribute tells Turbo to change the button text to "Saving..." when the form is submitted. This provides immediate feedback to the user that their action is being processed. Once the form submission is completed, the original button text is restored.
Creating a Custom Turbo Loading Button with SVG Loader
If you want to go a step further and add a custom SVG loader, follow this approach. First, add the group
class to your form. We'll need this to pair the form's aria-busy attribute to elements within it.
<%= form_with(model: post, class: "group") do |form| %>
<%= render "shared/error_messages", resource: form.object %>
Next, extend the submit button to include an SVG loader. You can find a variety of free loaders at SVG Loaders. You can integrate one using the built-in Rails UI icon helper or render an SVG inline.
<%= button_tag class: "btn btn-primary group-aria-busy:bg-black" do %>
<span class="group-aria-busy:hidden block">Create post</span>
<div class="group-aria-busy:block hidden">
<%= icon "loader", path: "icons/loader.svg", classes: "size-6 fill-white" %>
</div>
<% end %>
Breaking Down the Code
Let's break down what's happening here:
- Button Tag: We use a
button_tag
instead of asubmit
tag to control the button's content more. - Class Attributes: The
group-aria-busy:bg-black
class will change the button's background to black when the form is busy (i.e., submitting). - Hidden and Visible Elements: When the form is busy, the
span
element with the text "Create post" is hidden, and thediv
containing the SVG loader is shown.
The TL;DR; This code will replace the button text with an SVG loader when the form is being submitted, giving your users a clear indication that something is happening behind the scenes.
Implementing the Custom SVG Loader
To add a bit more context, let's focus on the SVG loader itself. SVG loaders are lightweight and scalable, making them perfect for modern web applications. You can find a variety of free loaders at SVG Loaders. Once you download a loader, save it to your project's app/assets/images/icons
directory.
In our example, we used a loader named loader.svg
. You can reference it in your Rails views using Rails UI. For more information on this icon helper, check out the design patterns section of any template you install using the gem.
<%= icon "loader", path: "icons/loader.svg", classes: "size-6 fill-white" %>
Testing Your Turbo Loading Buttons
To see your Turbo loading buttons in action, start your Rails server if it's not already running:
bin/dev
Navigate to http://localhost:3000/posts/new
and try creating a new post. You should see the loading indicator or text change when you submit the form. If everything is set up correctly, even with the simulated delay, the user experience should be smooth and informative.
Debugging Tips
If you encounter any issues while setting up the Turbo loading buttons, here are a few debugging tips:
- Check the Console: Open your browser's developer console to check for JavaScript errors. Turbo relies on JavaScript, so any errors in your scripts might affect the loading buttons.
- Inspect Network Requests: Use the network tab in your browser's developer tools to inspect the form submission request. Ensure the request is being sent correctly and the server responds as expected.
- Verify Asset Paths: Ensure the path to your SVG loader is correct. If the path is incorrect, the loader won't be displayed.
Conclusion
And there you have it! With just a few lines of code, you’ve implemented turbo-loading buttons in your Rails application. This feature improves the user experience and adds a professional touch to your app. By providing immediate feedback, you reduce user uncertainty and enhance the overall feel of your application.
Experiment with both the simple and custom approaches to see which one best suits your project. Whether you choose a straightforward text change or a more sophisticated SVG loader, your users will appreciate the feedback during form submissions.
Other articles you might like
Categories
Collection
Part of the Hotwire and Rails collection
Products and courses
-
Hello Hotwire
A course on Hotwire + Ruby on Rails.
-
Hello Rails
A course for newcomers to Ruby on Rails.
-
Rails UI
UI templates and components for Rails.