htmx icon indicating copy to clipboard operation
htmx copied to clipboard

Same form using htmx and "classic submit" throws different fields using webcomponents

Open FJLendinez opened this issue 1 year ago • 13 comments

Hi all,

I am testing the nordhealth webcomponents in forms and I found this. When I send the form via HTMX, the webcomponents are ignored

<div hx-boost="true">
    <form method="post" hx-target="#data">
        {% csrf_token %}

        <nord-date-picker name="date" aria-invalid="true" id="id_date" size="m"></nord-date-picker>

        <button type="submit">Submit</button>
    </form>
</div> 

image

But, if I send without HTMX, it works properly

<div>
    <form method="post" hx-target="#data">
        {% csrf_token %}

        <nord-date-picker name="date" aria-invalid="true" id="id_date" size="m"></nord-date-picker>

        <button type="submit">Submit</button>
    </form>
</div> 

image

FJLendinez avatar Nov 23 '23 12:11 FJLendinez

More info: Using hx-post instead hx-boost had the same behaviour

FJLendinez avatar Nov 23 '23 12:11 FJLendinez

Hey, I think that's something you will have to tweak in your component. What does it do exactly? Because by default, non-standard elements won't be included in a form payload, no matter whether they define a name/value attributes pair or not. See this JSFiddle for example, where you can see that without any library (or whatever you're using) included, only the standard input's value is in the form.

So to get it to work, I think you would have to intercept event such as htmx:configRequest and manually add the value in the payload from here

Hope this helps!

Telroshan avatar Nov 23 '23 20:11 Telroshan

Thanks for your response.

IMHO webcomponents is a standard and each day its use probably increment. This components extends of standard nodes and browsers detects them correctly.

I let you here a JSFiddle that demostrate the use of them

Using FormData we can obtain the formdata using the browser as a middleware. It could be an easy way to manage the submit trigger.

FJLendinez avatar Nov 24 '23 07:11 FJLendinez

The problem is here

Using elt.elements doesn't detect webcomponents. As I said before, we could use FormData in this point to manage directly the form submission. This could improve the performance for selections and checkboxes because we obtain the values directly avoiding validations that are not required having a cleaned form and not checking which is the active one

FJLendinez avatar Nov 24 '23 08:11 FJLendinez

Oh I see, so it works through FormData, I didn't know that there was support for that now! #1686 and #1323 seem related, htmx does not use FormData internally for now but manually retrieves form element values, for which web components don't work

Telroshan avatar Nov 24 '23 08:11 Telroshan

Changing:

            if (matches(elt, 'form')) {
                var inputs = elt.elements;
                forEach(inputs, function(input) {
                    processInputValue(processed, values, errors, input, validate);
                });

For:

            if (matches(elt, 'form')) {
                var form = new FormData(elt);
                for (var [entry_name, entry_value] of form.entries()){
                    addValueToValues(entry_name, entry_value, values);
                }
            }

Works fine. Can someone make the proper validations and give me feedback?

FJLendinez avatar Nov 24 '23 13:11 FJLendinez

This will change the returned data for (some) existing setups, doesn’t it?

andryyy avatar Nov 24 '23 14:11 andryyy

Please note that a FormData rework would, if accepted, only occur in htmx 2 (breaking release) as it's not fully IE11 compatible, and htmx 1 strives for IE11 compatibility

Telroshan avatar Nov 24 '23 15:11 Telroshan

More info, using hx-vals we can pass the content of FormData and add it to the request.

 <div id="form">
        <form hx-post="." hx-target="#data" hx-vals="js:{...getFormValues(event)}">
            <nord-date-picker name="date"></nord-date-picker>
            <button type="submit">submit</button>
        </form>
    </div>

    <div id="data">{{ data }}</div>
    <script>
        function getFormValues(event) {
            var form = new FormData(event.target)
            return Object.fromEntries(form.entries())
        }

    </script>

FJLendinez avatar Nov 28 '23 16:11 FJLendinez

@Telroshan I guess browser switches like in the "good" old days are out of the question? Something like var form = "FormData" in window ? new FormData(elt) : elt.elements?

Really looking forward to htmx 2 as I think these kinds of issues are what's keeping HTMX from being an actually usable solution instead of a nice POC.

hesxenon avatar Jan 07 '24 15:01 hesxenon

Yeah as they have many differences in their behavior, I don't think it'd be reasonable to support & maintain both in the same codebase Htmx 2 is coming soon and the switch to FormData is being worked on btw 😄 as this will be a breaking release (IE11 will be dropped for htmx 2), it was the occasion to integrate this too

Telroshan avatar Jan 07 '24 15:01 Telroshan

I don't suggest you can answer what "soon" means? IIRC "soon" was the status quo for quite some time now :P

Come to think of it, is there a roadmap somewhere? :thinking:

hesxenon avatar Jan 07 '24 15:01 hesxenon

We don't have a roadmap I'm afraid About "soon": you can find the latest (afaik) official mention of htmx 2 here for the 1.9.10 release announcement https://x.com/htmx_org/status/1738012396470370611

this is (we hope) the last 1.x release before a 2.x beta release in january

So we hope to have it by the end of the month in beta, though keep in mind it's a hope and not a promise 😁

Telroshan avatar Jan 07 '24 15:01 Telroshan

Hey, we switched to FormData internally for htmx 2, which should now correctly handle webcomponents (see test added in 01b292ada48f31276642b587eb67128367349701). We also introduced a FormData proxy object for retro-compatibility reasons, and proxy objects aren't supported by IE11, which htmx 1 will always support. As htmx 2 is now available in beta and on the dev branch, I think we can close this issue now ; if you need form data along your web components, switch to htmx2 ! 😄

Telroshan avatar Jun 07 '24 07:06 Telroshan