I’m trying to solve a problem where I’ve got a UI card, which is just a div, and I want the user to be able to click anywhere on the card and have a modal open up.
My modals are wired up as a turbo-frame. I’ve got the code to a point where, anywhere in my app, I can have a link open in the modal.
The challenge is, because the users are clicking on a card, they’re not clicking on a link! So I need to write a small Stimulus controller to catch the click, and do the right thing. Here’s what I’ve got so far:
import ApplicationController from './application_controller'
import { Turbo } from '@hotwired/turbo-rails'
export default class extends ApplicationController {
openModal (event) {
const destination = this.element.dataset.href
const clickedElement = event.target
// Treat clicks to links as normal clicks, but other clicks should open the modal
if(clickedElement.localName != 'a' && clickedElement.parentElement.localName != 'a') {
event.preventDefault()
event.stopPropagation()
Turbo.visit(destination)
}
}
}
In my markup, I’ve got the card like this:
<div class="card" data-controller="card-controller" data-action="click->card-controller#openModal" data-href="/card/destination">
<!-- a bunch of junk in here, including some links -->
</div>
I’ve verified that, when the card is clicked, the openModal()
is correctly called, and that openModal()
is differentiating between normal links and other clicks correctly.
Here’s my trouble. I need that controller’s Turbo.visit()
call to target the modal
frame. Is there any way to do that? I’d rather not have a hidden secret link if I can… it seems like this should be possible without a hidden link, but I can’t see a way to make it happen.
Thanks for the help!