1/** 2 * SMS Capture two-step form: fire the "email only" capture when the visitor 3 * advances past step 1, so the email is saved even if they skip the phone step. 4 * 5 * The form is built with Ninja Forms Layout, so the multi-part 6 * `formContentData` is a rows > cells > fields layout tree, not a flat field 7 * collection. Rather than walk that tree, we track the SMS email field's value 8 * as the visitor types (identifying it by its stable field key, `smscap_email`, 9 * via the Ninja Forms `fields` radio channel) and POST it when the multi-part 10 * form advances to step 2. 11 */ 12( function () { 13 var capturedEmail = ''; 14 var fired = {}; 15 var attached = false; 16 var tries = 0; 17 18 // Resolve a Ninja Forms field key from a DOM input id (nf-field-<id>). 19 function fieldKey( el ) { 20 var match = /nf-field-(\d+)/.exec( el.id || '' ); 21 if ( ! match || 'undefined' === typeof window.nfRadio ) { 22 return null; 23 } 24 try { 25 var model = window.nfRadio.channel( 'fields' ).request( 'get:field', match[ 1 ] ); 26 return model ? model.get( 'key' ) : null; 27 } catch ( e ) { 28 return null; 29 } 30 } 31 32 // Track the SMS email as it is typed. Delegated so it survives the 33 // multi-part re-render, and keyed on smscap_email so other forms' email 34 // fields (e.g. the footer signup) are ignored. 35 document.addEventListener( 36 'input', 37 function ( e ) { 38 var el = e.target; 39 if ( ! el || 'email' !== el.type ) { 40 return; 41 } 42 // If the field rendered, Ninja Forms is booted: attach now in case 43 // the load-time polling lost the race to a slow nfRadio. 44 init(); 45 if ( 'smscap_email' === fieldKey( el ) ) { 46 capturedEmail = ( el.value || '' ).toString().trim(); 47 } 48 }, 49 true 50 ); 51 52 function postEmail() { 53 var body = new FormData(); 54 body.append( 'action', 'jed_sms_step1' ); 55 body.append( 'nonce', window.jedSms.nonce ); 56 body.append( 'email', capturedEmail ); 57 window.fetch( window.jedSms.ajaxUrl, { 58 method: 'POST', 59 body: body, 60 credentials: 'same-origin', 61 } ); 62 } 63 64 function onChangePart( collection ) { 65 try { 66 var formId = collection.formModel.get( 'id' ); 67 if ( fired[ formId ] ) { 68 return; 69 } 70 // Only when arriving at step 2 (second visible part). 71 if ( 1 !== collection.getVisibleParts().indexOf( collection.getElement() ) ) { 72 return; 73 } 74 if ( ! capturedEmail || -1 === capturedEmail.indexOf( '@' ) ) { 75 return; 76 } 77 fired[ formId ] = true; 78 postEmail(); 79 } catch ( e ) { 80 if ( window.console && window.console.debug ) { 81 window.console.debug( 'jed-sms-capture:', e ); 82 } 83 } 84 } 85 86 function init() { 87 if ( attached ) { 88 return; 89 } 90 if ( 'undefined' === typeof window.nfRadio || 'undefined' === typeof window.jedSms ) { 91 if ( tries++ < 150 ) { 92 window.setTimeout( init, 200 ); // Wait for Ninja Forms (up to ~30s). 93 } 94 return; 95 } 96 attached = true; 97 window.nfRadio.channel( 'nfMP' ).on( 'change:part', onChangePart ); 98 } 99
100 init(); 101} )();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.