htmx
htmx copied to clipboard
hx-params is ignored if included inside a form element
By the default, if the HTMX request is sent from a form element, all fields are sent and hx-params is ignored.
Maybe the documentation should be updated to mention this behaviour or change the behaviour to allow filtering parameters even if the request is sent from a form element.
<form hx-post="/" hx-params="field1">
<input type=text name="field1">
<input type=text name="field2">
<input type=text name="field3">
</form>
In the previous example, all the fields will be sent ignoring hx-params. I would have thought that only 'field1' would be sent.
Based on the testing suite (hx-params: named includes works), this shouldn't be happening. Can you post your actual code, perhaps we can find the issue somewhere else?
I have the same issue. It doesn't even have to be an field in the form. Forms in general seems to ignore the hx-params attribute.
Call "localhost/?some_fancy_param=1"
<form hx-get="/" hx-params="*" hx-trigger="submit, change delay:1s" hx-replace-url="true">
<input type=text name="field1">
<input type=text name="field2">
<input type=text name="field3">
</form>
Submit the form and you will get "localhost/?field1=&field2=&field3=", but some_fancy_param is gone for ever. It's working fine on e.g. selects
EDIT: After some further testing I also had problems on "a"-tags
A possible workaround (works only for GET requests and does not take data from any fields): (Not sure if it actually covers all cases... it was written just within some minutes)
document.addEventListener('htmx:configRequest', function (event) {
if (event.detail.elt.hasAttribute('hx-params')) {
console.debug("Please check https://github.com/bigskysoftware/htmx/issues/3199 if it's fixed, and remove this workaround.");
const hx_parmas_raw = event.detail.elt.getAttribute('hx-params');
let hx_only = []
let hx_except = []
if (hx_parmas_raw === "*") {}
else if (hx_parmas_raw === "none") {
return;
}
else if (hx_parmas_raw.startsWith("not ")) {
hx_except = hx_parmas_raw.slice(4).split(',').map(x => x.trim());
}
else {
hx_only = hx_parmas_raw.split(',').map(x => x.trim());
}
const hx_include_raw = event.detail.elt.getAttribute('hx-include');
if (hx_include_raw) {
const fields = document.querySelectorAll(hx_include_raw);
fields.forEach((field) => {
if (field.name) hx_except.push(field.name);
});
}
if (event.detail.elt.tagName === 'FORM') {
const form_fields = event.detail.elt.querySelectorAll('input, select, textarea');
form_fields.forEach((field) => {
if (field.name) hx_except.push(field.name);
});
}
const htmx_url = new URL(event.detail.path, window.location.origin);
const htmx_params = new URLSearchParams(htmx_url.search);
const window_url = new URL(window.location.href);
const window_params = new URLSearchParams(window_url.search);
// for each param in the window url that is not in the htmx url, add it
window_params.forEach((value, key) => {
if (!htmx_params.has(key)) {
if (hx_only.length > 0 && !hx_only.includes(key)) {
return;
}
if (hx_except.length > 0 && hx_except.includes(key)) {
return;
}
event.detail.parameters[key] = value;
}
});
}
});
Maybe you can reuse some of the code to fix the issue...
Based on the testing suite (hx-params: named includes works), this shouldn't be happening. Can you post your actual code, perhaps we can find the issue somewhere else?
<form id="product_form" action="{% url 'core:index' %}" method="post"
hx-post="{% url 'core:index' %}"
hx-trigger="get-price from:body, load"
hx-params="coverage_area, travelers, travel_period, oldest_insured_age, ascendant, car"
hx-target="#total_quote_div"
hx-swap="outerHTML"
>
(Fields included here)
</form>
hx-params is ignored.
My workaround was to enclose all fields inside a div and make the hx-post from the div. That way hx-params worked like intented.
Tested your pasted form code and it works as expected in this example codepen:
https://codepen.io/MichaelWest22/pen/yyLewZx
Your form only includes the specified input field names but excludes the last one I added with a different name.
I tested with multiple old versions of htmx as well and they all seemed to work for me as expected
I have the same issue. It doesn't even have to be an field in the form. Forms in general seems to ignore the hx-params attribute.
Call "localhost/?some_fancy_param=1"
<form hx-get="/" hx-params="*" hx-trigger="submit, change delay:1s" hx-replace-url="true"> <input type=text name="field1"> <input type=text name="field2"> <input type=text name="field3"> </form>Submit the form and you will get "localhost/?field1=&field2=&field3=", but some_fancy_param is gone for ever. It's working fine on e.g. selects
EDIT: After some further testing I also had problems on "a"-tags
I think this is expected behavior. The current query parameters of a site are never designed to be submitted with every future form request inside the page as this would be a major security issue if this was possible. Someone sending you to a link to the page could inject malicious parameter data into your next form submission to get you to do all sorts of dangerous things! Use this link to pay me $1 please: https://yourbank.com/make-payment?payment-amount=1000 :)
There are much better more secure patterns I think to handle this situation if you did happen to need a url query parameter to be reused by some of the forms on the page. For example when loading a page with such a parameter that you know is safe and needed for the next form submission you could create a hidden input in the form with the previous url value on page load. or in htmx if you were doing a partial page update and pushing a url with a parameter you could retain an input on the page with the value so it will be submitted next time. Also you can use the configRequest event like you have in your example above but you should only need 3 lines as you can leave htmx to generate the parameters list as normal which it does before it calls configRequest and then your event listener code can just optionally add one extra parameter into event.details.parameters if it is missing or required from the expected and knows to be safe current url query parameter.
I have the same issue. It doesn't even have to be an field in the form. Forms in general seems to ignore the hx-params attribute. Call "localhost/?some_fancy_param=1"
<form hx-get="/" hx-params="*" hx-trigger="submit, change delay:1s" hx-replace-url="true"> <input type=text name="field1"> <input type=text name="field2"> <input type=text name="field3"> </form>Submit the form and you will get "localhost/?field1=&field2=&field3=", but some_fancy_param is gone for ever. It's working fine on e.g. selects EDIT: After some further testing I also had problems on "a"-tags
I think this is expected behavior. The current query parameters of a site are never designed to be submitted with every future form request inside the page as this would be a major security issue if this was possible. Someone sending you to a link to the page could inject malicious parameter data into your next form submission to get you to do all sorts of dangerous things! Use this link to pay me $1 please: https://yourbank.com/make-payment?payment-amount=1000 :)
There are much better more secure patterns I think to handle this situation if you did happen to need a url query parameter to be reused by some of the forms on the page. For example when loading a page with such a parameter that you know is safe and needed for the next form submission you could create a hidden input in the form with the previous url value on page load. or in htmx if you were doing a partial page update and pushing a url with a parameter you could retain an input on the page with the value so it will be submitted next time. Also you can use the configRequest event like you have in your example above but you should only need 3 lines as you can leave htmx to generate the parameters list as normal which it does before it calls configRequest and then your event listener code can just optionally add one extra parameter into event.details.parameters if it is missing or required from the expected and knows to be safe current url query parameter.
Valid point, still I think this should be secured another way... In my case I just use it for some sorting and filtering. A option to disable this protection would be great. The goal should not be that dev are searching them selfs workarounds. I think it should at least be clearly pointed out in the documentation, as this information is completly missing there (Including warnings for possible vulnerabilities). At the moment the behaviour feels very random... (as it is working on some elements)
I have the same issue. It doesn't even have to be an field in the form. Forms in general seems to ignore the hx-params attribute.
Call "localhost/?some_fancy_param=1"
<form hx-get="/" hx-params="*" hx-trigger="submit, change delay:1s" hx-replace-url="true"> <input type=text name="field1"> <input type=text name="field2"> <input type=text name="field3"> </form>Submit the form and you will get "localhost/?field1=&field2=&field3=", but some_fancy_param is gone for ever. It's working fine on e.g. selects
EDIT: After some further testing I also had problems on "a"-tags
I agree with @MichaelWest22, but I think you can get your desired behavior by setting hx-get="" (slightly more context here).