Custom field interacts with JS
I want to add Braintree Payment field to my form.
This is their simplest example.
What would be the "filament" way of adding
payload.nonce
to the form.10 Replies
to clarify my question, I need custom field to:
- execute JS call when submitting the form (I would call
instance.requestPaymentMethod
)
- populate the value of field from JS (I would set payload.nonce
as the value for the field)
There wouldn't actually be a field, it's a drop-in so fields are in iFrame.Not sure if I'm getting the full picture... do you need to make a request to Braintree and get some kind of token inside of a
Hidden
field as part of the Filament form submission?Yes. My question is regarding the async nature of JS here.
The payment field is last in my form. When the user submits the form I need to call
instance.requestPaymentMethod
in JS, wait for the response, put that value in hidden field and only then send all fields for validation/saving to the server.Makes sense. I'm not sure what the best solution is but I'm thinking that you may need to break down the submit action. Maybe this can be done with a "fake" submit button:
- First, validate the form (call
$this->validate()
in Livewire)
- Then, send the request to Braintree and show some kind of loading indicator
- When you get the response, fill your Hidden field with the Braintree token
- Finally, call the real submit()
action
I've never really done anything like this in the context of Filament. I'll be watching for suggestions from others.Does the call to Braintree have to happen on the front end? Using a hidden field to pass a token to the backend could have security implications if it's an authorization token.
Totally agree
Does the call to Braintree have to happen on the front end? Using a hidden field to pass a token to the backend could have security implications if it's an authorization token.Yes, it's the tokenization call. All payment providers (Stripe, etc) fallows this flow. There's client and server key. Client key is passed to browser, Braintree JS api is used to send card data to their server and return a token representing the payment method (card in this case) . I have to pass that to the backend and then perform the actual charge using server key. If someone intercepts the token, it's useless without server key. Given I have full control here and I need it in only specific place, I won't try to make it completely "right" by creating custom field. I'm thinking of handling the form fields separately and having 2 methods handling the submission. So I would have something like Then I could add some JS to the button to both tokenize the card and hit
validate
method for form. On successful tokenization I trigger submit
method in backend which calls the validate
again (to be sure) and combines the form state with my hidden field.Maybe just use js to listen for the submit event then run a async await to get the token and set the hidden value then continue the default form submission.
As a user if I hit enter I expect the form to submit. So you’d need a type=submit. Just my opinion though.
Hm, that sounds exactly what I need.
Could be my lack of experience with LW that I fail to understand the technical aspects of how to achieve this.
If I look at the simple example in Filament docs
here the
submit
method in PHP will be executed. Now from your last message
use js to listen for the submitI understand something like this But now there is still that PHP method being called, isn't it? Should I remove
submit
from form definition?
does that work?Hard to explain, but you can use alpine to handle the submit click and since alpine has access to the livewire instance after you’ve done your stuff you can call the livewire submit from there.