How to Show a Delete Confirmation Dialog in Rails Using Stimulus
Tags: rails, stimulus, javascript, hotwire
Published: 2022-01-09 04:16:56

If you've switched to the latest version of Rails that uses Turbo, you might have noticed that it doesn't show the confirmation dialog when you delete an item. This post explains how to display a delete confirmation dialog using Stimulus. 

### Stimulus

If you haven't worked with [Stimulus](https://stimulus.hotwired.dev/) before, it's a JavaScript framework from Basecamp that is part of the Hotwire (_HTML over the wire_) front-end framework stack. The primary aim of Stimulus is **to enhance the static HTML rendered by the server**, using [convention-over-configuration](https://rubyonrails.org/doctrine#convention-over-configuration).

Stimulus connects the DOM elements to JavaScript objects using _**controllers**_ and hooks the DOM events to JavaScript methods using _**actions**_. It does this using simple attributes on the HTML elements. 

**Controllers** 

Controllers connect DOM elements to  JavaScript objects using a `data-controller` attribute. The JavaScript object contains the behavior and logic you want to add to that DOM element. 

Stimulus continuously monitors the page, waiting for HTML `data-controller` attributes to appear. Once it finds an element with a `data-controller` attribute, it checks the value to find a corresponding controller class. Then it creates a new instance of that class and connects it to the element. 

For example, let's assume your HTML contains this `div` element with the `data-controller` attribute.

```html
<div data-controller="books">
   <p>Book</p>
</div>
```
Once Stimulus finds this DOM element, it will try to find a controller class in the `books_controller.js` file. 

```javascript
// src/controllers/books_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
}
```
You can learn more about this process of mapping filenames to attributes on the [Stimulus installation guide](https://stimulus.hotwired.dev/handbook/installing). 

**Actions** 

Actions connect DOM events to controller methods using a `data-action` attribute.

Let's add a button to our DOM element with a `data-controller` attribute. 

```html
<div data-controller="books">
   <p>Book</p>
   <button data-action="click->books#read">Start Reading</button>
</div>
```

The `data-action` value `click->books#read` is called an *action descriptor*. 

- `click` is the event name
- `books` is the controller name
- `read` is the method to call

The `data-action="click->books#read"` tells Stimulus: **when the user clicks this button, call the `read` method on the `books_controller`.**

```javascript
// src/controllers/books_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
    read() {
         // start reading the book
    }
}
```

The [Stimulus handbook](https://stimulus.hotwired.dev/handbook/introduction) compares this approach to HTML classes connecting to CSS styles. 

> Just like the class attribute is a bridge connecting HTML to CSS, Stimulus’s data-controller attribute is a bridge connecting HTML to JavaScript. 
>
> Data attributes help separate content from behavior in the same way CSS separates content from presentation.

---

With that basic introduction of Stimulus out of the way, let's see how we will solve our problem of showing a confirmation dialog when the user clicks the delete button.

Here's the example code that displays the books with a delete button for each book. 

![Displaying Books](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t4c07hb2ya1ug0uhdxok.png)

**Step 1: Add a `data-controller` attribute to a parent HTML tag**

![data-controller](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/odu8xmeb6dycqjn5jsmd.png)

**Step 2: Add a `data-action` attribute to the button**

![data-action](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p86tr9k8pvtqr5lnxl4v.png)

**Step 3: Add a Stimulus controller**

![Stimulus controller](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akwea0finyu4vfdjna5i.png)

That's it. When you click the `delete` button, Stimulus will first call the `delete` method in the `books_controller.js` file. This method shows the confirmation prompt and does nothing if the user selects the `cancel` option. 

And that's how you can show the confirmation prompt using Stimulus in Rails. 

---

***Note:*** There's a simple way to add the confirmation dialog using the `turbo-method` and `turbo-confirm` data attributes, like this:

```erb
<%= link_to "delete", book, data: { turbo_method: :delete, turbo_confirm: "Are you sure?" } %>
```

However, this solution runs into a problem where Rails tries to redirect you to the same page with an HTTP `delete` method, causing an error. Chris Oliver from GoRails recently did a [video](https://www.youtube.com/watch?v=J1GAYLQvtBU) that explains this in detail, and also shows the workaround.

I hope that helped. Let me know in the comments if you find any mistakes or have any feedback.