Does Turbo listen to JS created form elements? (phoenix_html interfereing with turbo?)

Elixir Phoenix provides a very simple way to turn normal links into DELETE/POST requests via this tiny JS file. Basically it intercepts some link clicks and turns them into form submissions.

It does so like this:

  function buildHiddenInput(name, value) {
    var input = document.createElement("input");
    input.type = "hidden";
    input.name = name;
    input.value = value;
    return input;
  }

  function handleClick(element, targetModifierKey) {
    var to = element.getAttribute("data-to"),
        method = buildHiddenInput("_method", element.getAttribute("data-method")),
        csrf = buildHiddenInput("_csrf_token", element.getAttribute("data-csrf")),
        form = document.createElement("form"),
        target = element.getAttribute("target");

    form.method = (element.getAttribute("data-method") === "get") ? "get" : "post";
    form.action = to;
    form.style.display = "hidden";

    if (target) form.target = target;
    else if (targetModifierKey) form.target = "_blank";

    form.appendChild(csrf);
    form.appendChild(method);
    document.body.appendChild(form);
    form.submit();
  }

As far as I can tell this interferes with Turbo listening to the response and doing proper turbo streams behavior for instance. It seems like my application started behaving much better after I removed it.

The problem with removing import "phoenix_html" from my app.js it is now I have to do a lot of manual csrf handling and the generated HTML from phoenix will be silently broken.

There is a way to listen to the form events that Phoenix creates by doing something like the docs suggest:

document.body.addEventListener('phoenix.link.click', function (e) {
  // Prevent default implementation
  e.stopPropagation();

  // Trigger Turbo?
}, false);

I just wasn’t sure how to trigger Turbo to listen to this properly. A Turbo.visit seemed like it would only be good for page changes and not DELETE requests where you want to respond with a <turbo-stream>

1 Like

I’m interested in a solution here too. For now, I use forms instead of Phoenix links for delete/post requests.

1 Like

Yeah, that’s what I think I’m going to do. I’ve even thought about shadowing the “link” function on the phoenix side to see if I can make it generate a form instead of a link with data attributes. Haven’t tried it yet.

Overall, it’s good to know that I’m not crazy :innocent:.