_hyperscript
_hyperscript copied to clipboard
Act upon the result of an event
Updated with customized JS code called upon onsubmit.
Playing with an example for https://github.com/bigskysoftware/htmx/issues/398 , I am trying to trigger a submit event when hx-post is pressed.
<!DOCTYPE html>
<html lang="en">
<body>
<form action="{{ request.path }}" method='post' id="myform"
onsubmit="return validateForm()">
<label for="choose">Would you prefer a banana or cherry?</label>
<input id="choose" name="i_like" required>
<button>Submit</button>
<a href='#' _="on click send submit to #myform" hx-post="{{ request.path }}">hx-post</a>
</form>
</body>
function validateForm() {
var x = document.getElementById("choose").value;
if (x != "apple") {
return false;
}
}
</script>
<script src="https://unpkg.com/[email protected]"></script>
<script src="https://unpkg.com/[email protected]"></script>
</html>
It appears that the form element did receive the submit event but hx-post did not wait for the completion of the submit event (result of validateForm) and went ahead with AJAX post. Is there anyway to wait for the completion of submit, cancel hx-post ifvalidateForm returns false?
how are you validating the form?
The submit event to the form is supposed to trigger validation of required of <input id="choose" name="i_like" required>, as what would happen if I click the submit button. I do not know exactly how the magic happens underneath.
Here is the simple flask app that I use to test this page.
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def test():
print(request)
if request.method == 'POST':
return render_template('test1.html')
else:
return render_template('test.html')
if __name__ == '__main__':
app.run()
I bet the problem is that you are sending a custom "submit" event and that's going around the normal browser infrastucture.
Could you try this instea:
<a href='#' _="on click call #myform.submit()">Submit It</a>
instead? Also, do you mean to also have the anchor tag submit a post as well?
Ok, this is becoming confusing.
-
If I remove the
hx-postpart from the<a>,_="on click send submit to #myform"does send thesubmitevent toformbut validation does not happen. -
If I remove the
hx-postpart and use your script_="on click call #myform.submit()", the form is submitted but without form validation. This is a documented behavior (callingform.submitdirectly will bypass validation).
Now I am wondering how I can manually trigger form validation.
@1cg The whole idea of bigskysoftware/htmx#396, bigskysoftware/htmx#398 and this ticket is that the regular form POST event can trigger automatic or manual form validation (built-in HTML constraints or JS library that depends on submit events to perform client-side validation). Switching to hx-post will lose these features so I am trying to restore them. It is disappointing that dispatching submit event to the form does not appear to do the trick.
We do validation of all inputs include in an htmx request, and should halt if one of them fails:
https://github.com/bigskysoftware/htmx/blob/a66458768613ac8193ccad1570ac629a9974d927/src/htmx.js#L2048
Can you set a break point here:
https://github.com/bigskysoftware/htmx/blob/a66458768613ac8193ccad1570ac629a9974d927/src/htmx.js#L1635
And see if the input is being validated correctly?
This should "just work" without any hyperscript but, as always, there may be bugs.
ok, validate is set to false in processInputValue, let me check what is going on.
https://github.com/bigskysoftware/htmx/blob/a66458768613ac8193ccad1570ac629a9974d927/src/htmx.js#L1664
Does this line mean validate is set in the case of
<form hx-post="">
</form>
but not
<form>
<button hx-post>
</form>
Changing that line to
var validate = (matches(elt, 'form') || closest(elt, 'form')) && elt.noValidate !== true;
will perform validation, but hx-post just stopped, no error message even on the console, which can be confusing but a step forward.
OK, the form validation problem is partially solved (at least will be discussed in bigskysoftware/htmx#400, but the problem for "act upon the result of an event" remains. I have updated the original post for waiting for the result of a custom JS code.