I have a clickable table row with a button inside. Desired behavior would be:
- When clicked on row, opens sidepane
- When clicked on button inside row, does button event
What happens is, since button is inside the row, both things happen, i.e. button does his thing and sidepane opens. Which is a bug, I don’t want sidepane to open when button is pressed.
What I was advised to do was adding a hook, which I did.
In app.js I have:
let Hooks = {}
Hooks.AllowButtonDefaultAndPreventLinkDefault = {
mounted() {
this.el.addEventListener("click", (e) => {
// `closest` in case we click an element inside a button, e.g. an icon.
if (e.target.closest("div > a")) {
e.preventDefault()
} else {
location.href = this.el.href
}
})
}
}
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks, params: {_csrf_token: csrfToken}})
Code:
@impl Phoenix.LiveComponent
def render(assigns) do
~H"""
<LivePatch
to={{ @path }}
class={{ "table-row #{row_classes(@is_selected)} device-row" }}
opts={{ [id: @device.id] }}
>
<div class="table-cell p-5">{{ @device.hardware_id }}</div>
<div class="table-cell p-5">
<DevicePresenceStatus status={{ presence_status(@device, @devices_presence) }} />
</div>
<div class="room-name table-cell p-5">{{ room_name(@device.room) }}</div>
<div class="department-name table-cell p-5">{{ department_name(@device.room) }}</div>
<div class="table-cell p-5">{{ @device.signaling_channel_arn }}</div>
<div class="table-cell p-5">
<button
:on-click={{ @reboot_device }}
:phx-hook="AllowButtonDefaultAndPreventLinkDefault"
phx-value-device_id={{ @device.id }}
class="hover:bg-blue-dark cursor-pointer flex rounded p-3 bg-blue text-xs justify-center font-medium text-white uppercase"
>
Reboot Device
</button>
</div>
<div class="table-cell" />
</LivePatch>
"""
end
Web tools:
The hook does load but it does nothing. I tried adding phx-ignore as said in this post but it did nothing.
Hope somebody can hook me up with an answer