-
Couldn't load subscription status.
- Fork 6
feat: Stimulus controller to show a confirm modal before link or form… #213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Reviewer's GuideAdds a new Stimulus confirm controller to intercept form submissions and link clicks, rendering a configurable Bootstrap confirmation modal before continuing, and includes updated documentation with usage examples. Sequence diagram for confirm modal controller intercepting form submit or link clicksequenceDiagram
actor User
participant "Stimulus Confirm Controller"
participant "Bootstrap Modal"
participant "Form or Link"
User->>"Form or Link": Click (submit or link)
"Form or Link"->>"Stimulus Confirm Controller": Event (submit/click)
"Stimulus Confirm Controller"->>"Bootstrap Modal": Show confirmation modal
User->>"Bootstrap Modal": Click Confirm
"Bootstrap Modal"->>"Stimulus Confirm Controller": Confirm event
"Stimulus Confirm Controller"->>"Form or Link": Proceed (submit or follow link)
Class diagram for ConfirmController structureclassDiagram
class ConfirmController {
+modalTitleValue: String
+confirmationMessageValue: String
+cancelButtonTextValue: String
+confirmButtonTextValue: String
+closeButtonTextValue: String
+elementTarget
+connect()
+isForm()
+isLink()
+createModal()
+showModal()
+handleConfirm()
+disconnect()
}
ConfirmController --|> Controller
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes - here's some feedback:
- In createModal, avoid using global document.querySelector for selecting the confirm button and modal—scope your queries to the modal element you just created to prevent collisions when multiple instances are present.
- Ensure you remove or namespace the event listeners added in connect (on the elementTarget and confirm button) in disconnect so that handlers aren’t leaked or duplicated on re-initialization.
- Consider splitting the documentation whitespace/formatting changes into a separate commit to keep the feature-specific diff focused and easier to review.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In createModal, avoid using global document.querySelector for selecting the confirm button and modal—scope your queries to the modal element you just created to prevent collisions when multiple instances are present.
- Ensure you remove or namespace the event listeners added in connect (on the elementTarget and confirm button) in disconnect so that handlers aren’t leaked or duplicated on re-initialization.
- Consider splitting the documentation whitespace/formatting changes into a separate commit to keep the feature-specific diff focused and easier to review.
## Individual Comments
### Comment 1
<location> `assets-public/controllers/confirm_controller.js:23-26` </location>
<code_context>
+ if (this.isForm()) eventName = 'submit'
+ if (this.isLink()) eventName = 'click'
+
+ this.elementTarget.addEventListener(eventName, (e) => {
+ e.preventDefault()
+ e.stopPropagation()
+ this.showModal()
+ })
+ }
</code_context>
<issue_to_address>
**issue (bug_risk):** Event listener is added on every connect, risking duplicate listeners.
Reconnecting the controller may attach multiple listeners to the same element, leading to unintended effects. To prevent this, ensure only one listener is active by removing it in disconnect or using `{ once: true }` if suitable.
</issue_to_address>
### Comment 2
<location> `assets-public/controllers/confirm_controller.js:104-109` </location>
<code_context>
+ })
+
+ // bind on confirm button click
+ const confirmBtn = document.querySelector('[data-role="confirm-button"]')
+ confirmBtn.addEventListener('click', () => {
+ this.handleConfirm()
+ bootstrapModal.hide()
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Querying for confirm button may select wrong element if multiple modals exist.
Scope the button query to the newly created modal to ensure the correct element is selected, e.g., use `modal.querySelector('[data-role="confirm-button"]')`.
```suggestion
// bind on confirm button click
const confirmBtn = modal.querySelector('[data-role="confirm-button"]')
confirmBtn.addEventListener('click', () => {
this.handleConfirm()
bootstrapModal.hide()
})
```
</issue_to_address>
### Comment 3
<location> `assets-public/controllers/confirm_controller.js:123-130` </location>
<code_context>
+ return
+ }
+
+ if (this.isLink()) {
+ if (this.elementTarget.target) {
+ window.open(this.elementTarget.href, this.elementTarget.target)
+ return
+ }
+
+ window.location = this.elementTarget.href
+ }
+ }
</code_context>
<issue_to_address>
**suggestion:** Directly setting window.location may not preserve link attributes like rel or download.
Please review if important link attributes like rel or download need to be preserved when redirecting, and handle them as needed.
```suggestion
if (this.isLink()) {
if (this.elementTarget.target) {
window.open(this.elementTarget.href, this.elementTarget.target)
return
}
// Handle important link attributes
if (this.elementTarget.hasAttribute('download')) {
// Simulate click to trigger download
this.elementTarget.click()
return
}
if (this.elementTarget.hasAttribute('rel')) {
// Create a temporary anchor to preserve rel attribute
const tempLink = document.createElement('a')
tempLink.href = this.elementTarget.href
tempLink.rel = this.elementTarget.getAttribute('rel')
// Copy other relevant attributes if needed
if (this.elementTarget.hasAttribute('type')) {
tempLink.type = this.elementTarget.getAttribute('type')
}
document.body.appendChild(tempLink)
tempLink.click()
document.body.removeChild(tempLink)
return
}
window.location = this.elementTarget.href
}
```
</issue_to_address>
### Comment 4
<location> `docs/frontend/stimulus.md:30` </location>
<code_context>
The only differnce is that you add the event `data-action="click->clipboard#copy"` directly on the text.
```html
</code_context>
<issue_to_address>
**issue (typo):** Typo: 'differnce' should be 'difference'.
Please update the spelling to 'difference'.
</issue_to_address>
### Comment 5
<location> `docs/frontend/stimulus.md:208` </location>
<code_context>
+
+## Confirm modal
+
+This controller allows to show a confirmation modal before submitting form or clicking a link.
+
+For example when you have a form to delete an entity:
</code_context>
<issue_to_address>
**suggestion (typo):** Grammatical improvement: 'allows to show' should be 'allows you to show'.
Change the sentence to: 'This controller allows you to show a confirmation modal before submitting a form or clicking a link.'
```suggestion
This controller allows you to show a confirmation modal before submitting a form or clicking a link.
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces a new Stimulus controller that displays a Bootstrap confirmation modal before form submissions or link navigation, allowing users to confirm or cancel destructive actions.
Key changes:
- Added a new
confirm_controller.jsthat intercepts form submissions and link clicks to show a customizable confirmation modal - Updated Stimulus documentation with comprehensive usage examples for both forms and links
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| assets-public/controllers/confirm_controller.js | New Stimulus controller implementing confirmation modal functionality with form and link support |
| docs/frontend/stimulus.md | Added documentation section for the confirm modal controller with usage examples and formatting improvements |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This controller allows to show a confirmation modal before submitting form or clicking a link.
For example when you have a form to delete an entity:
This will result in:

Or an example with a link:
Will result in:

See https://next-app.activecollab.com/108877/my-work?modal=Task-235217-533
Summary by Sourcery
Add a new Stimulus Confirm controller to prompt users with a Bootstrap modal before executing form submissions or link navigations and update the Stimulus docs with its usage examples.
New Features:
Documentation: