Update form fields on select change with HTMX
Asked Answered
C

2

1

In one of my pages I have a select element and a form. What I want to achieve is to update the field values ​​in the form when the select changes, which happens successfully. I did many tests and read the documentation on htmx.org several times until I got this, but even now I don't understand why my configuration works. Is it a bug? It is correct? I'm not sure at all, especially when I get the same good result with both hx-target="#title,#slug,#shortcode" and hx-target="#shortcode", the main one being at least one of the three target ids to be included in the hx-target, otherwise the select is removed when the form fields are replaced. What do you think?

    <select id="select-settings" name="select-settings" 
        hx-get="/get-settings" hx-target="#title,#slug,#shortcode">

        <option value="">-- Select Settings --</option>
        <option value="super-opt10ns">Dolor qui voluptatem</option>
    </select>

    <!-- The form here is very simplified to reduce the space, but in 
    reality the fields are included in a table inside the form, with a 
    few small paragraphs of text in between, that I wouldn't want to 
    repeat in the responce from the end-point. -->

    <form id="field-form" action="options.php" method="post">
        <input type="text" id="title" name="title" value="">
        <input type="text" id="slug" name="slug" value="">
        <input type="text" id="shortcode" name="shortcode" value="">
    </form>

Response from the /get-settings endpoint:

    <input type="text" hx-swap-oob="outerHTML:#title" id="title" 
        name="title" value="Dolor qui voluptatem">

    <input type="text" hx-swap-oob="outerHTML:#slug" id="slug" 
        name="slug" value="super-opt10ns">

    <input type="text" hx-swap-oob="outerHTML:#shortcode" id="shortcode" 
        name="shortcode" value="[form slug='test']">
Chartism answered 8/7 at 22:36 Comment(0)
C
1

A cleaner solution was to add the hx-get="/get-settings" hx-trigger="change from:#select-settings" to the one of the target input fields in the form. The hx-swap-oob from the end-point response does the rest of the work. The htmx attributes from the select element I removed fully. As I understand it, the hx-target was only needed there to redirect the end-point response to the correct targets. In the modified input field it is not necessary.

It is worth mentioning that adding the hx-get="/get-settings" hx-trigger="change from:#select-settings" to the form tag in my case did not produced any response from the end-point, even with the hx-target added as for the select.

    <select id="select-settings" name="select-settings">
        <option value="">-- Select Settings --</option>
        <option value="super-opt10ns">Dolor qui voluptatem</option>
    </select>

    <!-- The form here is very simplified to reduce the space, but in 
    reality the fields are included in a table inside the form, with a 
    few small paragraphs of text in between, that I wouldn't want to 
    repeat in the responce from the end-point. -->

    <form id="field-form" action="options.php" method="post">
        <input 
            hx-get="/get-settings" 
            hx-trigger="change from:#select-settings"
            type="text" id="title" name="title" value="">
        <input type="text" id="slug" name="slug" value="">
        <input type="text" id="shortcode" name="shortcode" value="">
    </form>

Response from the /get-settings endpoint:

    <input type="text" hx-swap-oob="outerHTML:#title" id="title" 
        name="title" value="Dolor qui voluptatem">

    <input type="text" hx-swap-oob="outerHTML:#slug" id="slug" 
        name="slug" value="super-opt10ns">

    <input type="text" hx-swap-oob="outerHTML:#shortcode" id="shortcode" 
        name="shortcode" value="[form slug='test']">

P.S. In the end, however, I opted for another solution.

Chartism answered 9/7 at 11:5 Comment(3)
Nice solution, I haven't used the change from: trigger, yet. Good work!Americaamerican
Kind of odd that it did not work when put on the form tag, it seems the ideal place for this use case. I wonder if that would be worth a bug report.Sylvan
@Sylvan It seemed strange to me too. However, further testing is needed before making a bug report.Chartism
A
2

The reason why both hx-target values work is that the response defines an out-of-band swap for each input. Remember, an out-of-band swap replaces an element in the DOM found by the id attribute.

You should get the same result with this simpler approach:

<select id="select-settings" name="select-settings" hx-get="/get-settings" hx-target="#field-form">
    <option value="">-- Select Settings --</option>
    <option value="super-opt10ns">Dolor qui voluptatem</option>
</select>

<form id="field-form" action="options.php" method="post">
    <input type="text" id="title" name="title" value="">
    <input type="text" id="slug" name="slug" value="">
    <input type="text" id="shortcode" name="shortcode" value="">
</form>

The response could also be simplified:

<input type="text" id="title" name="title" value="Dolor qui voluptatem">
<input type="text" id="slug" name="slug" value="super-opt10ns">
<input type="text" id="shortcode" name="shortcode" value="[form slug='test']">

Just because you asked: There is no single correct way of doing things with HTMX. There can be many ways. But this definitely works if you intended to update the form values from an HTTP response.

Americaamerican answered 8/7 at 22:58 Comment(3)
Thank you! I know that the response could be simplified. But, sorry that I do not mentioned that, the form in my question is very simplified to reduce the space, but in reality the fields are included in a table inside the form, with a few small paragraphs of text in between. And I wouldn't want to repeat all this in the responce from the end-point, that's why I just focused on input fields. Anyway, I appreciate your effort to help me. Thanks again!Chartism
Yup, then out-of-band swaps make sense. Good luck!Americaamerican
Thank you! If you are interested, I have added my own answer.Chartism
C
1

A cleaner solution was to add the hx-get="/get-settings" hx-trigger="change from:#select-settings" to the one of the target input fields in the form. The hx-swap-oob from the end-point response does the rest of the work. The htmx attributes from the select element I removed fully. As I understand it, the hx-target was only needed there to redirect the end-point response to the correct targets. In the modified input field it is not necessary.

It is worth mentioning that adding the hx-get="/get-settings" hx-trigger="change from:#select-settings" to the form tag in my case did not produced any response from the end-point, even with the hx-target added as for the select.

    <select id="select-settings" name="select-settings">
        <option value="">-- Select Settings --</option>
        <option value="super-opt10ns">Dolor qui voluptatem</option>
    </select>

    <!-- The form here is very simplified to reduce the space, but in 
    reality the fields are included in a table inside the form, with a 
    few small paragraphs of text in between, that I wouldn't want to 
    repeat in the responce from the end-point. -->

    <form id="field-form" action="options.php" method="post">
        <input 
            hx-get="/get-settings" 
            hx-trigger="change from:#select-settings"
            type="text" id="title" name="title" value="">
        <input type="text" id="slug" name="slug" value="">
        <input type="text" id="shortcode" name="shortcode" value="">
    </form>

Response from the /get-settings endpoint:

    <input type="text" hx-swap-oob="outerHTML:#title" id="title" 
        name="title" value="Dolor qui voluptatem">

    <input type="text" hx-swap-oob="outerHTML:#slug" id="slug" 
        name="slug" value="super-opt10ns">

    <input type="text" hx-swap-oob="outerHTML:#shortcode" id="shortcode" 
        name="shortcode" value="[form slug='test']">

P.S. In the end, however, I opted for another solution.

Chartism answered 9/7 at 11:5 Comment(3)
Nice solution, I haven't used the change from: trigger, yet. Good work!Americaamerican
Kind of odd that it did not work when put on the form tag, it seems the ideal place for this use case. I wonder if that would be worth a bug report.Sylvan
@Sylvan It seemed strange to me too. However, further testing is needed before making a bug report.Chartism

© 2022 - 2024 — McMap. All rights reserved.