PageSourceSearch

https://www.quote.com/wp-content/plugins/leads-master/assets/newtab.js?ver=1.1.4

js quote.com collected 2026-10-02 06:58:41 UTC 22,402 bytes, 604 lines download raw bytes

1function generateRequestId() {
2   return Math.random().toString(36).substr(2, 9) + Math.random().toString(36).substr(2, 9);
3}
4
5jQuery(document).ready(function($) {
6  var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
7
8  // OEC-1086: the one client-side ZIP pattern. 5 digits only -- every MDA zip input is
9  // maxlength=5, so ZIP+4 (which the server accepts) can never be entered here.
10  var ZIP_PATTERN = /^[0-9]{5}$/;
11  function isValidZip(value) {
12    return ZIP_PATTERN.test(value || '');
13  }
14
15  $('body').on('click', '.mda-submit', function(e) {
16    var form = $(this).closest('form');
17    // OEC-1086: prevent rapid repeat submissions while a request is already in flight.
18    if (form.attr('data-mda-submitting') === 'true') {
19      return;
20    }
21    form.attr('btnClicked', true);
22    form.submit();
23  });
24
25  $('body').on('focus', '[name=zipcode]', function(e) {
26    quote_hide_tooltips();
27  });
28
29  $('body').on('keydown', '[name=zipcode]', function(e) {
30    quote_hide_tooltips();
31  });
32
33  $('body').on('blur', 'form', function(e) {
34    quote_hide_tooltips();
35  });
36
37  $(window).on('resize', function(e) {
38    quote_hide_tooltips();
39  });
40
41  function quote_hide_tooltips() {
42    $('.field-holder').each(function(i,z) {
43      tlite.hide(z);
44    })
45  }
46
47  $('body').on('submit', 'form', function(e) {
48    var form = $(this);
49
50    // OEC-1086: authoritative duplicate-submission lock. Every submission path funnels
51    // through this event -- button click, Enter key in the zip field (the MDA has no
52    // submit button, so the zip input implicitly submits), and programmatic .submit().
53    // Checking only in the click handler let those other paths re-enter submitForm() and
54    // fire extra zip submit events / window.open calls.
55    if (form.attr('data-mda-submitting') === 'true') {
56      e.preventDefault();
57      return false;
58    }
59
60    var zip = $(this).find("[name=zipcode]");
61    var typeSelect = $(this).find("select[name=type]");
62    var fieldType = form.find('[name="type"]').prop('tagName');
63    var isMultiVertical = fieldType === 'SELECT' ? true : false;
64    var popper = null;
65    var request = form.find("[name=requestId]");
66    var is_quote_life_rates_page = form.find('[name="is_quote_life_rates_page"]').val() === '1';
67
68    /*
69     Preventing the form from being submitted for life insurance modal only when enabled.
70     See insurance-quotes.php, phoenix_config method
71    */
72    if (window.phoenix.config.lifeModalFormEnabled === 'true' && // life modal enabled in quote settings
73        form[0].id !== 'life' && // making sure its not when the modal is submitted
74        getInsuranceType(form) === 'Life' && // Only when you click on the life drop down or type === 'Life'
75        !isMultiVertical && // Only opening modal if its not a multi-vertical
76        zip.is(':hidden') === true
77    ) {
78      openLifeModal(false)
79      e.preventDefault();
80      return false;
81    }
82
83    /**
84     * If Life rates page is enabled validate the age and income fields
85     */
86    if (
87      window.phoenix.config.quoteLifeRatesPageEnabled === "true" &&
88      is_quote_life_rates_page
89    ) {
90      var age = form.find('[name="age"]');
91      var income = form.find('[name="income"]');
92      var ageHasValue = age.is(":checked");
93      var incomeHasValue = income.is(":checked");
94
95      if (!ageHasValue) {
96        e.preventDefault();
97        setTimeout(function () {
98          var ageTooltipTarget = age.first().closest(".field-holder")[0];
99          if (ageTooltipTarget) {
100            tlite.show(ageTooltipTarget, { grav: "s" });
101          }
102        }, 100);
103        return false;
104      }
105      if (!incomeHasValue) {
106        e.preventDefault();
107        setTimeout(function () {
108          var incomeTooltipTarget = income.first().closest(".field-holder")[0];
109          if (incomeTooltipTarget) {
110            tlite.show(incomeTooltipTarget, { grav: "s" });
111          }
112        }, 100);
113        return false;
114      }
115    }
116
117    if (getVisitorId()) {
118      request.val(getVisitorId() + "|" + generateSubmitId());
119    }
120
121    if (zip.length > 0) {
122      // OEC-1086: Only skip validation for a genuinely hidden zip *input* (single-field
123      // flows where the zip is an <input type="hidden">). A real, interactive zip field
124      // that merely has zero layout because an ancestor is display:none (e.g. the sticky
125      // header before scroll or on mobile) must STILL be validated. Using jQuery ":hidden"
126      // here previously let the sticky header submit empty/invalid ZIPs and fire the zip
127      // submit event without any validation.
128      var zipIsHiddenInput = (zip.attr("type") || "").toLowerCase() === "hidden";
129      if (zipIsHiddenInput) {
130        submitForm(form, e);
131        return true;
132      }
133
134      if (typeSelect.length > 0 && !typeSelect.val()) {
135        e.preventDefault();
136        setTimeout(function() {
137          tlite.show(typeSelect.closest('.field-holder')[0], { grav: 's' })
138        }, 100);
139        return false;
140      }
141      if(!zip.val() || zip.val().length < 1) {
142        e.preventDefault();
143        setTimeout(function() {
144          tlite.show(zip.closest('.field-holder')[0], { grav: 's' })
145        }, 100);
146        return false;
147      } else if (!isValidZip(zip.val())) {
148        e.preventDefault();
149        setTimeout(function() {
150          zip_error = zip.closest('.field-holder');
151          zip_error.attr("title","Please enter a valid Zip Code!");
152          tlite.show(zip_error[0], { grav: 's' });
153          //reset filed holder value
154          zip_error.attr("title","ZIP Code must be filled out!");
155        }, 100);
156        return false;
157      } else {
158        if (!iOS || form.attr('btnClicked')) {
159            if (window.phoenix.config.lifeModalFormEnabled === 'true' && // life modal enabled in quote settings
160                form[0].id !== 'life' && // making sure its not when the modal is submitted
161                getInsuranceType(form) === 'Life' && // Only when you click on the life drop down or type === 'Life'
162                zip.is(':hidden') === true // Only when zipcode is hidden in the MDA
163            ) {
164                openLifeModal(true, zip.val());
165                e.preventDefault();
166                return false;
167            } else {
168                submitForm(form, e);
169            }
170        } else {
171          e.preventDefault();
172          var button = form.find('.mda-submit').closest('.field-holder')[0];
173          zip.blur();
174          tlite.show(button, { grav: 's' })
175          form.find('.mda-submit').addClass('needs-submit');
176          setTimeout(function() {
177            form.find('.mda-submit').removeClass('needs-submit');
178          }, 1000);
179          return false;
180        }
181      }
182    } else if (zip.is(":hidden")) {
183      submitForm(form, e);
184    }
185  });
186
187  function openLifeModal(prepop = false, zip = '') {
188    //Hidding MDA background to prevent double black backgrounds
189    jQuery('.mda-background').fadeOut(200);
190      jQuery('#lifeModal').modal();
191      if (prepop) { /* Prepopping zip field from previous input */
192          var lifeForm = $('form.life');
193          var lifeFormZip = $(lifeForm).find("[name=zipcode]");
194          lifeFormZip.val(zip);
195      }
196  }
197
198  // OEC-1086: lock a form once a valid submission is underway so duplicate rapid
199  // submissions from the same interaction cannot fire multiple zip submit events.
200  function lockMdaSubmission(form) {
201    form.attr('data-mda-submitting', 'true');
202    var btn = form.find('.mda-submit');
203    btn.prop('disabled', true).addClass('mda-submit-processing');
204    // Safety valve: re-enable so the user isn't permanently locked out when the
205    // request stays on-page (popup flow) or fails to navigate away.
206    setTimeout(function() {
207      form.removeAttr('data-mda-submitting');
208      btn.prop('disabled', false).removeClass('mda-submit-processing');
209    }, 3000);
210  }
211
212  function submitForm(form, e) {
213    if (form.has('[name="zipcode"],[name="zip"]').length) {
214        var zipField = form.find('[name="zipcode"],[name="zip"]').first();
215
216        // OEC-1086: last-line defense — never open a tab or allow native POST without a valid ZIP.
217        var zipVal = (zipField.val() || "").trim();
218        if (!isValidZip(zipVal)) {
219          e.preventDefault();
220          return false;
221        }
222
223        lockMdaSubmission(form);
224        var type = getInsuranceType(form);
225        var is_quote_life_rates_page = form.find('[name="is_quote_life_rates_page"]').val() === '1';
226
227        var _showQuoteLifeRatesPage =
228          type === "Life" &&
229          window.phoenix.config.quoteLifeRatesPageEnabled === "true" &&
230          !is_quote_life_rates_page;
231
232        var _showPopup = showPopup(form) && !_showQuoteLifeRatesPage;
233        var _showNative = showNative(form) || _showQuoteLifeRatesPage;
234
235        if(_showQuoteLifeRatesPage){
236          form.attr('action', window.phoenix.config.quoteLifeRatesPageUrl || "/quote-life-rates");
237        }
238
239      if (_showPopup) {
240        /* Trigger GA tracking if only a newtab */
241        if (!_showNative) {
242          window.dataLayer = window.dataLayer || [];
243          window.dataLayer.push({
244            event: 'zip_submit_event'
245          });
246        }
247
248         var zip = form.find('[name="zipcode"],[name="zip"]').val();
249        //  var type = getInsuranceType(form);
250         var referrer = form.find('[name="referrer"]').val();
251         var requestId = form.find('[name="requestId"]').val();
252         var tag = form.find('[name="tag"]').val();
253         var insured = form.find('[name="insured"]:checked').val();
254         var maPlacement = form.find('[name="ma_placement"]').val();
255         var qwPlacement = form.find('[name="qw_placement"]').val();
256         var paidTraffic = form.find('[name="paid_traffic"]').val();
257         var paidTrafficParams = "";
258         var utm_source = form.find('[name="utm_source"]').val();
259         var utm_medium = form.find('[name="utm_medium"]').val();
260         var utm_campaign = form.find('[name="utm_campaign"]').val();
261         var utm_term = form.find('[name="utm_term"]').val();
262         var utm_content = form.find('[name="utm_content"]').val();
263         var utm_adgroup = form.find('[name="utm_adgroup"]').val();
264         var test_mode = form.find('[name="test_mode"]').val();
265         var gclid = form.find('[name="gclid"]').val();
266         var maToken = form.find('[name="token"]').val();
267         var publisherId = form.find('[name="publisher_id"]').val();
268         var mvaParams = getMVAParams(form);
269         var experimentId = form.find('[name="experimentId"]').val();
270         var category = window.phoenix.config.pageCategory;
271         var userAgent = form.find('[name="useragent"]').val();
272
273         // adding breadcrumb text and replacing arrow symbol with comma
274         var breadCrumbText;
275         if (document.getElementsByClassName("aioseo-breadcrumbs").length === 0) {
276            breadCrumbText = undefined;
277         } else {
278            breadCrumbText = document.getElementsByClassName("aioseo-breadcrumbs")[0].innerText.replaceAll("(", "").replaceAll(")", "");
279         }
280
281        // For custom life insurance modal form
282        var coverage_amount = form.find('[name="coverage_amount"]:checked').val();
283        var smoker = form.find('[name="smoker"]:checked').val();
284        var health = form.find('[name="health"]:checked').val();
285        var age = form.find('[name="age"]:checked').val();
286        var income = form.find('[name="income"]:checked').val();
287
288         paidTrafficParams = "&paid_traffic=" + paidTraffic +
289          "&utm_source=" + utm_source + "&utm_medium=" + utm_medium +
290          "&utm_campaign=" + utm_campaign + "&utm_term=" + utm_term +
291          "&utm_content=" + utm_content + "&utm_adgroup=" +
292          utm_adgroup + "&publisher_id=" + publisherId
293          + (test_mode ? "&test_mode=" + test_mode : "");
294
295         window.open(encodeURI(
296           '/apps?requestId=' + requestId + '&zipcode=' +
297            zip + '&type=' + type + "&referrer=" + referrer +
298            (isKrakenPost() ? "&content_type=kraken" : "") +
299            "&tag=" + tag + (insured ? "&insured=" + insured : "") +
300            paidTrafficParams +
301            (maPlacement ? "&ma_placement=" + maPlacement : "") +
302            (qwPlacement ? "&qw_placement=" + qwPlacement : "") +
303            "&gclid=" + gclid +
304            "&token=" + maToken + '&' + mvaParams +
305            "&coverage_amount=" +  coverage_amount +
306            "&smoker=" + smoker +
307            "&health=" + health +
308            "&age=" + age +
309            "&income=" + income +
310            "&category=" + category +
311            "&breadcrumb=" + breadCrumbText +
312            "&experimentId=" + experimentId +
313            "&useragent=" + userAgent
314         ));
315      }
316
317      if (!_showNative) {
318         e.preventDefault();
319         return false;
320      }
321    }
322  }
323
324   function getInsuranceType(form) {
325      var type = form.find('[name="type"]').val(), alt_type = form.find('[name="alt_type"]').val();
326      if ( type == "Other" && alt_type)
327         return alt_type;
328      else
329         return type;
330   }
331
332   function standardizeType(rawType) {
333      switch(rawType) {
334         case "Home": return "home";
335         case "Renter": return "renter";
336         case "Long Term Care": return "long term care";
337         case "Health": return "health";
338         case "Dental": return "dental";
339         case "Travel": return "travel";
340         case "Life": return "life";
341         case "Business": return "business";
342         case "Motorcycle": return "motorcycle";
343         case "Electronics": return "electronics";
344         case "Pet": return "pet";
345         case "Medicare": return "medicare";
346         case "Burial": return "burial";
347         case "Group Health": return "group health";
348         case "Commercial": return "commercial";
349         case "Child Life": return "child life";
350         case "Rental": return "rental";
351         case "Condo": return "condo";
352         case "RV": return "rv";
353         case "Boat": return "boat";
354         case "Disability": return "disability";
355         case "Personal Injury": return "personal injury";
356         case "Divorce": return "divorce";
357         case "Auto Accident Injury": return "auto accident injury";
358         case "DUI": return "dui";
359         case "Real Estate": return "real estate";
360         case "Criminal Defense": return "criminal defense";
361         case "Prenuptial": return "prenuptial";
362         case "Bankruptcy": return "bankruptcy";
363         case "Child Support": return "child support";
364         case "Immigration": return "immigration";
365         case "Family Law": return "family law";
366         case "Employment": return "employment";
367         case "Copyright": return "copyright";
368         case "Traffic": return "traffic";
369         case "Wills": return "wills";
370         case "Civil Law": return "civil law";
371         case "Elder Law": return "elder law";
372         case "Workers Comp": return "workers comp";
373         case "Social Security Disability": return "social security disability";
374         case "Auto Loan": return "auto loan";
375         case "Business Loan": return "business loan";
376         case "Mortgage Loan": return "mortgage loan";
377         case "Student Loan": return "student loan";
378         case "Payday Loan": return "payday loan";
379         case "Personal Loan": return "personal loan";
380         case "Debt": return "debt";
381      }
382      return "auto";
383   }
384
385   function showPopup(form) {
386      var type = getInsuranceType(form);
387      type = standardizeType(type);
388      return QUOTE_POPUP_TYPES[type];
389   }
390
391   function showNative(form) {
392      var type = getInsuranceType(form);
393      type = standardizeType(type);
394      return QUOTE_NATIVE_TYPES[type];
395   }
396   var paidParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'utm_adgroup', 'token', 'gclid', 'publisher_id'];
397
398   var legalMVAParams = [
399     'email',
400     'first_name',
401     'last_name',
402     'phone',
403     'dob',
404     'have_attorney',
405     'comments',
406     'degree_of_interest',
407     'type_of_legal_problem',
408     'tcpa',
409     'is_incident_date',
410     'incident_date',
411     'incident_date_option_b',
412     'injured',
413     'mva_type',
414     'doctor_treatment',
415     'were_you_at_fault',
416     'police_report',
417     'completed',
418     'original_referrer',
419     'submission_id',
420   ];
421
422   function getMVAParams(form) {
423     var params = [];
424     legalMVAParams.forEach(function(fieldName) {
425       var fieldValue = form.find('[name="' + fieldName + '"]').val();
426       if(fieldValue && fieldValue != ''){
427         params.push(fieldName + '=' + fieldValue);
428       }
429     });
430     return params.join('&');
431   }
432
433   function checkPaidUrlParams() {
434     for (i = 0; i < paidParams.length; i++) {
435       var param = paidParams[i];
436       var cur = getUrlParam(param);
437       if(cur) {  Cookies ? Cookies.set(param, cur, { expires: 1/24 }) : null }
438     }
439   }
440
441   function getVisitorId() {
442     if(!Cookies.get('visitorId')) Cookies.set('visitorId', generateRequestId(), { expires: 1/24 });
443     return Cookies.get('visitorId');
444   }
445
446   function loadPaidUrlParams() {
447     $('.mda-submit').each(function() {
448       var form = $(this).closest('form');
449       for (i = 0; i < paidParams.length; i++) {
450         var param = paidParams[i];
451         cookie = Cookies.get(param);
452         input =  form.find('[name="' + param + '"]');
453         if(cookie && !input.val()) { input.val(cookie); }
454       }
455
456       $("<input />").attr("type", "hidden")
457         .attr("name", "requestId")
458         .attr("value", Cookies.get('visitorId'))
459         .appendTo(form);
460       if( isKrakenPost() ) {
461          $("<input />").attr("type", "hidden")
462            .attr("name", "content_type")
463            .attr("value", 'kraken')
464            .appendTo(form);
465       }
466
467     });
468   }
469
470   // Get zip value from cookies
471   function getSavedZipCode() {
472     var zipVal;
473
474     var contactCookie = Cookies.get('contact');
475     if(contactCookie){
476       contactCookie = JSON.parse(contactCookie);
477       zipVal = contactCookie["contact"]["zip"];
478     }
479     return zipVal;
480   }
481
482   function preFillForms() {
483     $('.mda-submit').each(function() {
484       var form = $(this).closest('form');
485       var zipInput = form.find('[name="zipcode"]');
486
487       if(zipInput && !zipInput.val()){
488         var zipVal = getSavedZipCode();
489         zipInput.val(zipVal);
490       }
491
492     });
493   }
494
495   function getUrlVars() {
496     var vars = {};
497     var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
498       vars[key] = value;
499     });
500     return vars;
501   }
502
503   function getUrlParam(parameter, defaultvalue) {
504     var urlparameter = defaultvalue;
505     if(window.location.href.indexOf(parameter) > -1){
506       urlparameter = getUrlVars()[parameter];
507     }
508     return urlparameter;
509   }
510
511
512   function generateSubmitId() {
513     return Math.random().toString(36).substr(2, 3);
514   }
515
516   // Handles setting hidden fields for paid traffic data from a cookie or
517   //  saving the data in a cookie
518   function loadPaidTrafficParams() {
519     $('.mda-submit').each(function() {
520       var categories = ["internal", "tracking", "contact", "current_insurance", "requested_coverage", "vehicles", "incidents", "individuals", "claims"];
521       var arrayCategories = ["vehicles", "incidents", "individuals", "claims"];
522       var form = $(this).closest('form');
523
524       var inputs = form.find('input[type="hidden"]');
525
526       var paramObject = {};
527
528       // Converts hidden inputs into a js object
529       for (var i = 0; i < inputs.length; i++) {
530         // ex: contact[email]
531         // ex: vehicles[0][submodel]
532         var input = inputs[i];
533         var field = input.name.replace(/\]/g, "");
534         var fieldCat = field.split("[")[0];
535         if(input.value && categories.includes(fieldCat)){
536           if(arrayCategories.includes(fieldCat)){
537             // ex: [ "vehicles", 0, "year" ]
538             var [category, index, param] = field.split("[");
539             if(!paramObject.hasOwnProperty(category)){
540               paramObject[category] = [];
541             }
542             if(!paramObject[category][index]){
543               paramObject[category][index] = {};
544             }
545             paramObject[category][index][param] = input.value;
546           } else {
547             // ex: ["contact", "email"]
548             var [category, param] = field.split("[");
549             if(!paramObject.hasOwnProperty(fieldCat)){
550               paramObject[fieldCat] = {};
551             }
552             paramObject[fieldCat][param] = input.value;
553           }
554         }
555       }
556
557       for (var catIndex = 0; catIndex < categories.length; catIndex++) {
558         var cat = categories[catIndex];
559         try{
560           if(paramObject[cat]) {
561             // Set new cookie for params that are set
562             var newCookie = {};
563             newCookie[cat] = paramObject[cat];
564             var jsonCookie = JSON.stringify(newCookie);
565             Cookies.remove(cat);
566             Cookies.set(cat, jsonCookie, { expires: 1/24 });
567           } else {
568             var cookie = Cookies.get(cat);
569             // if the cookie is set for the category and the fields for the
570             //  category aren't filled then set them to data in the cookie
571             // NOTE: we are filling based on all of the params inside a
572             //  category otherwise we may add incorrect data.
573             if(cookie){
574               // Convert the params to url parameters & use that for input name
575               var urlParams = decodeURI($.param(JSON.parse(cookie)));
576               var cookieParams = urlParams.split("&");
577               // console.log(cookieParams);
578               // add a hidden field for each parameter
579               for (var i = 0; i < cookieParams.length; i++) {
580                 var nameVal = cookieParams[i].split("=");
581                 if(nameVal.length == 2){
582                   var [name, value] = nameVal;
583                   $("<input />").attr("type", "hidden")
584                   .attr("name", name)
585                   .attr("value", value)
586                   .appendTo(form);
587                 }
588               }
589             }
590           }
591         } catch (e) {
592           console.error(e);
593         }
594       }
595     });
596   }
597
598
599   checkPaidUrlParams();
600   getVisitorId();
601   loadPaidUrlParams();
602   loadPaidTrafficParams();
603   preFillForms();
604});

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.