Combining AJAX and default browser behavior: how to do form submit AND something first?

In our app, we need to take two actions upon form submission. First, we perform a registration ajax event that is internal to our own app. Then, if that succeeds with a 200, we want the button they clicked to do the regular form submit thing – method=POST action=a-third-party-url.com . How can we have the button do both a our special thing and THEN a client browser visit of the action URL (with the form payload)? We are using Clojurescript, built on React and so with a virtual DOM, and want to combine the some ajax with the default behavior, as if there were a default-submit-behavior function. How can this be done?

Store the result of that AJAX request somewhere - nil initially. Let’s call that state x.
Intercept the form’s submit event and check the value of x.
If it’s nil, prevent the default action of submitting the form and make the AJAX request that’ll store some non-nil value in that x and submit the form via JS.
And if x is not nil, just let the form be submitted regularly.

Alternatively to the state x, you can override the submit event listener. The default one is the one that does the AJAX request. The other one is nil to allow the default form submission process to work.

Part of the default behavior is to send the client browser to url WITH the payload of the form. The payload alone could be pure ajax, but it’s the user-session part that is tough. We still need their browser and payload to go there, and this is the part I don’t know how to do via CLJS or JS. The AJAX portion is old-hat bread-and-butter for us; it’s just how to do the default thing (is there a JS function for that, or is it really just perform a click on a button?)

If I understood you correctly, you can just attach the payload that you just retrieved via AJAX to the form’s submission’s payload by using a hidden input field.

If that’s not it, perhaps you can create a minimal project with mocked out backend and the relevant UI parts already there, up to the point where you don’t know how to proceed - then I can just alter that project and make a PR or send you a diff or whatever.

1 Like

Ah! I see. That hidden field idea is tried and true.

We also found a solution to my original question with an answer so obvious that everyone probably thought we knew it already. (.submit (.getElementById js/document my-form-id)) does the trick of performing the same action as clicking a submit button. So, with some careful handling of the form-id to pass it around appropriately, we can perform the submit at the time we want to, after the other thing.

That’s exactly what I initially meant by “submit the form via JS”. :smiley:

Just in case - note that if you’re using some React-based UI library, you shouldn’t rely on IDs. Instead, that form should be given a ref and you should access the form via that ref when it gets populated.

1 Like

I want to know more about the ids thing you mention. I’ve often used IDs as a way of grabbing things in Reagent, sometimes in form-3 components. I’ve seen the suggestion to include :key on them, but have understood that as a “to please the react library” rather than something that actually does something. But if I understand your comment, you are warning about using getElementById in case the virtual dom has not actually instantiated that thing yet, correct?

:key is completely orthogonal here.

getElementById can still be used with React, but shouldn’t. It makes reuse much harder, you have to name one extra thing and put it in the global context (all HTML elements’ IDs are global and must not be reused). There might be other issues that I can’t immediately recall.

Refs are a replacement mechanism for IDs in the React world.

1 Like

how do you set and search those? :ref on an item, and some getElementByRef function?

You don’t search them. It’s like a variable - React sets it, and then you use it:

1 Like

Perfect! Thank you for sharing!