Reputation: 4324
I am using HTML 5 required attribute for form validation. Now what I want is that if the form has passed the HTML 5 validation, it should take the user to the stripe checkout (I deliberately xxx out info in the code below for SO question).
Now if the form has not passed validation, the submit doesn't process, which is good. But after I complete the form and submit the form, it does not take me to the stripe checkout page, it just refreshes the page. What am I doing wrong?
<form id="tcform">
<p><b>Quantity:</b> 1</p>
<b class="price">Price:</b> <s>£xx</s> <span style="color: red;">£xx</span>
<button class="btn btn-default buynow" id="checkout-button-sku_xxx" role="link">
Buy Now
</button>
<p>
<i style="font-size:small">Limited time offer</i>
</p>
<p class="tcparagraph">
<input id="field_terms" type="checkbox" required name="terms"> I accept the <u><a href="Terms" id="tclink">Terms and Conditions</a></u></p>
<div id="error-message"></div>
</form>
<script>
(function() {
var stripe = Stripe('pk_test_xxx');
var checkoutButton = document.getElementById('checkout-button-sku_xxx');
checkoutButton.addEventListener('click', function() {
// When the customer clicks on the button, redirect
// them to Checkout.
const isFormValid = checkoutButton.form.checkValidity();
if(isFormValid==true) {
stripe.redirectToCheckout({
items: [{
sku: 'sku_xxx',
quantity: 1
}],
// Do not rely on the redirect to the successUrl for fulfilling
// purchases, customers may not always reach the success_url after
// a successful payment.
// Instead use one of the strategies described in
// https://stripe.com/docs/payments/checkout/fulfillment
successUrl: window.location.protocol + '//metis-online.com/courses/course-BRFAITC009-order-confirmation',
cancelUrl: window.location.protocol + '//metis-online.com/order-cancelled',
})
.then(function(result) {
if (result.error) {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer.
var displayError = document.getElementById('error-message');
displayError.textContent = result.error.message;
}
});
}
});
})();
</script>
Upvotes: 6
Views: 1264
Reputation: 2191
It happened to us as well.
We've added the novalidate
attribute (removes the HTML5 validation) to the form and validate it by javascript only.
<form id="tcform" novalidate>
...
</form>
Upvotes: 1
Reputation: 2617
As Jannes Botis said, you can use preventDefault
. You can also just return false
on the eventHandler from an submit
event, that will also cancel the form submission. For reference see: https://www.geeksforgeeks.org/when-to-use-preventdefault-vs-return-false-in-javascript/
Upvotes: 1
Reputation: 11242
You want to prevent the default behaviour of submiting the form. So do:
checkoutButton.addEventListener('click', function(event) {
...
if(isFormValid==true) {
event.preventDefault();
Upvotes: 10
Reputation: 6724
Right now your code is only attaching the click
listener if the form is valid at page load. In the absence of other form behavior, clicking a button in a form submits it back to the page it came from, which is why it looks like a page refresh.
You need to move the form check inside the button click event handler like so:
<script>
(function() {
var stripe = Stripe('pk_test_xxx');
var checkoutButton = document.getElementById('checkout-button-sku_xxx');
checkoutButton.addEventListener('click', function() {
if($('#tcform')[0].checkValidity()){
// When the customer clicks on the button, redirect
// them to Checkout.
stripe.redirectToCheckout({
items: [{
sku: 'sku_xxx',
quantity: 1
}],
// Do not rely on the redirect to the successUrl for fulfilling
// purchases, customers may not always reach the success_url after
// a successful payment.
// Instead use one of the strategies described in
// https://stripe.com/docs/payments/checkout/fulfillment
successUrl: window.location.protocol + '//www.xxx.com',
cancelUrl: window.location.protocol + '//www.xxx.com',
})
.then(function(result) {
if (result.error) {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer.
var displayError = document.getElementById('error-message');
displayError.textContent = result.error.message;
}
});
}
});
})();
But it might be even better to listen to the form's submit
event (https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit_event):
$('#tcform').on('submit', function() {
stripe.redirectToCheckout({
...
});
});
The submit
event is only emitted after the form is validated.
Upvotes: 2