1

I'm trying to make a list row that is clickable, but have a delete button inside of it.

When I click Delete, the confirmation alert shows up correctly, but then it just redirects to the page that the row is linked to, without deleting the record.

enter image description here

<li>
  <%= link_to project_path(@project) do %>
    ...truncated
    <%= @project.name %>
    ...truncated
    <%= button_to @project, method: :delete, data: { confirm: @confirm } do %>
      <%= 'Delete' %>
    <% end %>
  <% end %>
</li>

I have tried adding onclick: "event.stopPropagation();", which deletes the record, but now it doesn't show the confirmation dialog anymore.

Is it possible to do this without doing anything too custom outside UJS/turbo/hotwire?

Frexuz
  • 4,732
  • 2
  • 37
  • 54

1 Answers1

0

Permitted content
Transparent, except that no descendant may be interactive content or an a element, and no descendant may have a specified tabindex attribute.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#technical_summary


I'm not sure how it will work with UJS, but I've always done it with a data attribute:

<table>
  <tbody>
    <% @items.each do |item| %>
      <tr data-clickable="<%= url_for item %>">
        <td>
          <%= item.name %>
        </td>
        <td>
          <%= button_to "delete", item, method: :delete, data: { turbo_confirm: "Sure?" } %>
        </td>
      </tr>
    <% end %>
  </tbody>
</table>
// app/javascript/application.js

function navigateClickableElement(event) {
  const { target } = event;
  const element = target.closest("[data-clickable]");
  // don't navigate, if...
  if (!element)                         return; // not within data-clickable element
  if (window.getSelection().toString()) return; // there is text selected
  if (target.closest("a"))              return; // clicked a link
  if (target.closest("button"))         return; // clicked a button
  // good to go
  event.preventDefault();
  Turbo.visit(element.dataset.clickable);
}

document.addEventListener("click", navigateClickableElement);
Alex
  • 16,409
  • 6
  • 40
  • 56
  • Thanks, that's quite helpful. The `interactive content` is a good point, and `window.getSelection().toString()` is clever! :) But I ended up doing my own custom Stimulus modal component. Then the delete/form can be outside the clickable row. – Frexuz Apr 02 '23 at 12:46