_hyperscript icon indicating copy to clipboard operation
_hyperscript copied to clipboard

Act upon the result of an event

Open BoPeng opened this issue 4 years ago • 10 comments

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?

BoPeng avatar Mar 02 '21 16:03 BoPeng

how are you validating the form?

1cg avatar Mar 02 '21 17:03 1cg

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()

BoPeng avatar Mar 02 '21 17:03 BoPeng

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?

1cg avatar Mar 02 '21 17:03 1cg

Ok, this is becoming confusing.

  1. If I remove the hx-post part from the <a>, _="on click send submit to #myform" does send the submit event to form but validation does not happen.

  2. If I remove the hx-post part and use your script _="on click call #myform.submit()", the form is submitted but without form validation. This is a documented behavior (calling form.submit directly will bypass validation).

Now I am wondering how I can manually trigger form validation.

BoPeng avatar Mar 02 '21 17:03 BoPeng

@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.

BoPeng avatar Mar 02 '21 17:03 BoPeng

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.

1cg avatar Mar 02 '21 17:03 1cg

ok, validate is set to false in processInputValue, let me check what is going on.

BoPeng avatar Mar 02 '21 17:03 BoPeng

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>

BoPeng avatar Mar 02 '21 17:03 BoPeng

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.

BoPeng avatar Mar 02 '21 18:03 BoPeng

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.

BoPeng avatar Mar 02 '21 18:03 BoPeng