PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.22.2
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.22.2
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / square / js / frontend.js

frontend.js in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.22.2, at square/js/frontend.js

288 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function() {
2 if ( ! window.frmSquareVars ) {
3 return;
4 }
5
6 const appId = frmSquareVars.appId;
7 const locationId = frmSquareVars.locationId;
8
9 // Track the state of the Square card element
10 let squareCardElementIsComplete = false;
11 let thisForm = null;
12 let running = 0;
13
14 let cardGlobal;
15
16 // Track the state of each field in the card form
17 const cardFields = {
18 cardNumber: false,
19 expirationDate: false,
20 cvv: false,
21 postalCode: false
22 };
23
24 async function initializeCard( payments ) {
25 const cardElement = document.querySelector( '.frm-card-element' );
26 if ( ! cardElement ) {
27 return;
28 }
29
30 const card = await payments.card();
31 const cardStyle = frmSquareVars.style;
32 await card.attach( '.frm-card-element' );
33
34 card.configure( { style: cardStyle } );
35
36 // Add event listener to track when the card form is valid
37 card.addEventListener( 'focusClassRemoved', ( e ) => {
38 const field = e.detail.field;
39 const value = e.detail.currentState.isCompletelyValid;
40 cardFields[field] = value;
41
42 // Check if all fields are valid
43 squareCardElementIsComplete = Object.values( cardFields ).every( item => item === true );
44
45 // Update form submit button based on form validity
46 if ( thisForm ) {
47 if ( squareCardElementIsComplete ) {
48 enableSubmit();
49 } else {
50 disableSubmit( thisForm );
51 }
52 }
53 } );
54
55 return card;
56 }
57
58 /**
59 * Enable the submit button for the form.
60 */
61 function enableSubmit() {
62 if ( running > 0 ) {
63 return;
64 }
65
66 thisForm.classList.add( 'frm_loading_form' );
67 frmFrontForm.removeSubmitLoading( jQuery( thisForm ), 'enable', 0 );
68
69 // Trigger custom event for other scripts to hook into
70 const event = new CustomEvent( 'frmSquareLiteEnableSubmit', {
71 detail: { form: thisForm }
72 });
73 document.dispatchEvent(event);
74 }
75
76 /**
77 * Disable submit button for a target form.
78 *
79 * @param {Element} form
80 * @return {void}
81 */
82 function disableSubmit( form ) {
83 jQuery( form ).find( 'input[type="submit"],input[type="button"],button[type="submit"]' ).not( '.frm_prev_page' ).attr( 'disabled', 'disabled' );
84
85 // Trigger custom event for other scripts to hook into
86 const event = new CustomEvent( 'frmSquareLiteDisableSubmit', {
87 detail: { form: form }
88 });
89 document.dispatchEvent( event );
90 }
91
92 async function createPayment( event, token, verificationToken ) {
93 const tokenInput = document.createElement('input');
94 tokenInput.type = 'hidden';
95 tokenInput.value = token;
96 tokenInput.setAttribute('name', 'square-token');
97
98 const verificationInput = document.createElement('input');
99 verificationInput.type = 'hidden';
100 verificationInput.value = verificationToken;
101 verificationInput.setAttribute( 'name', 'square-verification-token' );
102
103 // Use the thisForm variable that we set earlier
104 if ( thisForm ) {
105 thisForm.appendChild( tokenInput );
106 thisForm.appendChild( verificationInput );
107
108 if ( typeof frmFrontForm.submitFormManual === 'function' ) {
109 frmFrontForm.submitFormManual( event, thisForm );
110 } else {
111 // Fallback if submitFormManual is not available
112 thisForm.submit();
113 }
114 }
115 }
116
117 async function tokenize( paymentMethod ) {
118 const tokenResult = await paymentMethod.tokenize();
119
120 if ( tokenResult.status === 'OK' ) {
121 return tokenResult.token;
122 }
123
124 let errorMessage = `Tokenization failed with status: ${tokenResult.status}`;
125 if ( tokenResult.errors ) {
126 errorMessage += ` and errors: ${JSON.stringify( tokenResult.errors )}`;
127 }
128
129 throw new Error( errorMessage );
130 }
131
132 // Required in SCA Mandated Regions: Learn more at https://developer.squareup.com/docs/sca-overview
133 async function verifyBuyer( payments, token ) {
134 const formData = new FormData( thisForm );
135 formData.append( 'action', 'frm_verify_buyer' );
136 formData.append( 'nonce', frmSquareVars.nonce );
137 const response = await fetch( frmSquareVars.ajax, {
138 method: 'POST',
139 body: formData
140 } );
141
142 if ( ! response.ok ) {
143 throw new Error( 'Failed to verify buyer' );
144 }
145
146 const verificationData = await response.json();
147 if ( ! verificationData.success ) {
148 throw new Error( verificationData.data );
149 }
150
151 const verificationDetails = verificationData.data.verificationDetails;
152 const verificationResults = await payments.verifyBuyer( token, verificationDetails );
153 return verificationResults.token;
154 }
155
156 /**
157 * Display an error message in the payment form.
158 *
159 * @param {string} errorMessage
160 * @return {void}
161 */
162 function displayPaymentFailure( errorMessage ) {
163 if ( ! thisForm ) {
164 return;
165 }
166
167 const statusContainer = thisForm.querySelector( '.frm-card-errors' );
168 if ( statusContainer ) {
169 statusContainer.textContent = errorMessage;
170 }
171 }
172
173 async function squareInit() {
174 // Find the form containing the Square payment element
175 const cardContainer = document.querySelector( '.frm-card-element' );
176 if ( cardContainer ) {
177 thisForm = cardContainer.closest( 'form' );
178 if ( thisForm ) {
179 // Initially disable the submit button until card is valid
180 disableSubmit( thisForm );
181
182 // Add event listener for form submission
183 thisForm.addEventListener( 'submit', function( event ) {
184 event.preventDefault();
185 event.stopPropagation();
186
187 if ( ! squareCardElementIsComplete ) {
188 const statusContainer = thisForm.querySelector( '.frm-card-errors' );
189 if ( statusContainer ) {
190 statusContainer.textContent = 'Please complete all card details before submitting.';
191 }
192 } else {
193 handlePaymentMethodSubmission( event, cardGlobal );
194 }
195
196 return false;
197 });
198 }
199 }
200
201 let payments;
202 try {
203 // Square requires HTTPS to work.
204 payments = window.Square.payments( appId, locationId );
205 } catch ( e ) {
206 const statusContainer = document.querySelector( '.frm-card-errors' );
207 statusContainer.classList.add( 'missing-credentials', 'frm_error' );
208 statusContainer.style.visibility = 'visible';
209 statusContainer.textContent = e.message;
210 return;
211 }
212
213 let card;
214 try {
215 card = await initializeCard( payments );
216 } catch ( e ) {
217 console.error( 'Initializing Card failed', e );
218 return;
219 }
220
221 cardGlobal = card;
222
223 /**
224 * @param {Object} $form
225 * @return {Boolean} false if there are errors.
226 */
227 function validateFormSubmit( $form ) {
228 var errors, keys;
229
230 errors = frmFrontForm.validateFormSubmit( $form );
231 keys = Object.keys( errors );
232
233 if ( 1 === keys.length && errors[ keys[0] ] === '' ) {
234 // Pop the empty error that gets added by invisible recaptcha.
235 keys.pop();
236 }
237
238 return 0 === keys.length;
239 }
240
241 async function handlePaymentMethodSubmission( event, card ) {
242 try {
243 if ( ! validateFormSubmit( thisForm ) ) {
244 return;
245 }
246
247 event.preventDefault();
248
249 // Increment running counter and disable the submit button
250 running++;
251 if ( thisForm ) {
252 disableSubmit( thisForm );
253 }
254
255 const token = await tokenize( card );
256 const verificationToken = await verifyBuyer( payments, token );
257 await createPayment( event, token, verificationToken );
258
259 // Decrement running counter after successful payment
260 running--;
261 if ( running === 0 && thisForm ) {
262 enableSubmit();
263 }
264 } catch ( e ) {
265 // Decrement running counter and re-enable submit if appropriate
266 running--;
267 if ( running === 0 && thisForm && squareCardElementIsComplete ) {
268 enableSubmit();
269 }
270 displayPaymentFailure( e.message );
271 }
272 }
273 }
274
275 document.addEventListener( 'DOMContentLoaded', async function () {
276 if ( ! window.Square ) {
277 console.error( 'Square.js failed to load properly' );
278 return;
279 }
280
281 squareInit();
282
283 jQuery( document ).on( 'frmPageChanged', function() {
284 squareInit();
285 } );
286 });
287 }() );
288