@@ -85,3 +85,123 @@ mc4wp.forms = forms
8585
8686// expose mc4wp object globally
8787window . mc4wp = mc4wp
88+
89+ // Initialize AJAX form submission if configured
90+ // The mc4wp_ajax_vars global is localized by PHP only when AJAX is enabled
91+ // and the premium AJAX module is not active.
92+ const ajaxConfig = window . mc4wp_ajax_vars
93+ if ( typeof ajaxConfig !== 'undefined' && ! ajaxConfig . inited ) {
94+ const Loader = require ( './forms/ajax-form-loader.js' )
95+ let busy = false
96+
97+ /**
98+ * Handle AJAX response data and update the form accordingly.
99+ *
100+ * @param {object } form The mc4wp Form object
101+ * @param {object } response Parsed JSON response from REST API
102+ */
103+ function handleResponseData ( form , response ) {
104+ forms . trigger ( 'submitted' , [ form , null ] )
105+
106+ if ( response . error ) {
107+ form . setResponse ( response . error . message )
108+ forms . trigger ( 'error' , [ form , response . error . errors ] )
109+ } else if ( response . code && response . message ) {
110+ form . setResponse ( `<div class="mc4wp-alert mc4wp-error"><p>${ response . message } </p></div>` )
111+ forms . trigger ( 'error' , [ form , [ response . code ] ] )
112+ } else {
113+ const data = form . getData ( )
114+
115+ forms . trigger ( 'success' , [ form , data ] )
116+ forms . trigger ( response . data . event , [ form , data ] )
117+
118+ // for BC: always trigger "subscribed" event when firing "updated_subscriber" event
119+ if ( response . data . event === 'updated_subscriber' ) {
120+ forms . trigger ( 'subscribed' , [ form , data , true ] )
121+ }
122+
123+ if ( response . data . hide_fields ) {
124+ form . element . querySelector ( '.mc4wp-form-fields' ) . style . display = 'none'
125+ }
126+
127+ form . setResponse ( response . data . message )
128+ form . element . reset ( )
129+
130+ if ( response . data . redirect_to ) {
131+ window . location . href = response . data . redirect_to
132+ }
133+ }
134+ }
135+
136+ /**
137+ * Submits the given form over AJAX using the REST API endpoint.
138+ *
139+ * @param {object } form The mc4wp Form object
140+ */
141+ function ajaxSubmit ( form ) {
142+ if ( busy ) {
143+ return
144+ }
145+
146+ const loader = new Loader ( form . element , ajaxConfig . loading_character )
147+ loader . start ( )
148+
149+ form . setResponse ( '' )
150+ busy = true
151+
152+ const request = new XMLHttpRequest ( )
153+ request . onreadystatechange = function ( ) {
154+ if ( request . readyState >= XMLHttpRequest . DONE ) {
155+ loader . stop ( )
156+ busy = false
157+
158+ if ( request . status >= 200 && request . status < 500 ) {
159+ try {
160+ const data = JSON . parse ( request . responseText )
161+ handleResponseData ( form , data )
162+ } catch ( e ) {
163+ // eslint-disable-next-line no-console
164+ console . error ( `Mailchimp for WordPress: failed to parse response: "${ e } "` )
165+ form . setResponse ( `<div class="mc4wp-alert mc4wp-error"><p>${ ajaxConfig . error_text } </p></div>` )
166+ }
167+ } else {
168+ // eslint-disable-next-line no-console
169+ console . error ( `Mailchimp for WordPress: request error: "${ request . responseText } "` )
170+ }
171+ }
172+ }
173+ request . open ( 'POST' , ajaxConfig . ajax_url , true )
174+ request . setRequestHeader ( 'Content-Type' , 'application/x-www-form-urlencoded' )
175+ request . setRequestHeader ( 'Accept' , 'application/json' )
176+ request . send ( form . getSerializedData ( ) )
177+ }
178+
179+ /**
180+ * Intercepts form submissions for AJAX-enabled forms.
181+ *
182+ * @param {object } form The mc4wp Form object
183+ * @param {Event } evt The original submit event
184+ */
185+ function maybeSubmitOverAjax ( form , evt ) {
186+ if ( form . element . getAttribute ( 'class' ) . indexOf ( 'mc4wp-ajax' ) < 0 ) {
187+ return
188+ }
189+
190+ if ( document . activeElement && document . activeElement . tagName === 'INPUT' ) {
191+ document . activeElement . blur ( )
192+ }
193+
194+ try {
195+ ajaxSubmit ( form )
196+ } catch ( e ) {
197+ // eslint-disable-next-line no-console
198+ console . error ( e )
199+ return
200+ }
201+
202+ evt . preventDefault ( )
203+ }
204+
205+ forms . on ( 'submit' , maybeSubmitOverAjax )
206+ ajaxConfig . inited = true
207+ }
0 commit comments