PageSourceSearch

https://www.madisonssc.com/static/1.213.86/js/forms.js

js madisonssc.com collected 2026-09-28 13:19:42 UTC 14,178 bytes, 493 lines download raw bytes

1//	to do late-binding of datepicker callbacks, just define an element here with a key equal to the id of the form input
2var dateCallbacks = {};
3var ll_formValidatorsLoaded = false;
4
5$(document).ready(function(){
6	//	form validation and styling
7	$("div.formField").on ('focus', 'input,select,textarea', function () {
8		$("div.formField").removeClass("active");
9		$(this).parents("div.formField").addClass("active");
10	}).find ('div.error').each (function () {
11		$(this).parents("div.formField").addClass("error");
12	});
13
14	$("img.requiredField").each(function() {
15		$(this).parents("div.formField").find("input").not(".sms").addClass("required");
16		$(this).parents("div.formField").find("select").addClass("required");
17		$(this).parents("div.formField").find("textarea").addClass("required");
18	});
19	$("img.requiredIfVisible").each(function() {
20		$(this).parents("div.formField").find("input").not(".sms").addClass("requiredIfVisible");
21		$(this).parents("div.formField").find("select").addClass("requiredIfVisible");
22		$(this).parents("div.formField").find("textarea").addClass("requiredIfVisible");
23	});
24	$("input.causesValidation,img.causesValidation,a.causesValidation").on ('click', function () {
25		return ll_generic_form_validate ($(this).hasClass ("skipRequired"));
26	});
27
28	//	get focus on the login box
29	$("#loginBox input.username").each(function () {
30		this.focus ();
31	});
32
33	//	date pickers
34	var calendarSource = "/static/graphics/calendar.gif";
35	var transparentSource = "/static/graphics/transparent.gif";
36	if ($("img.calendarImageTemplate.hidden").size () > 0)
37	{
38		calendarSource = $("img.calendarImageTemplate.hidden").eq(0).attr("src");
39	}
40	if ($("img.transparentImageTemplate.hidden").size () > 0)
41	{
42		transparentSource = $("img.transparentImageTemplate.hidden").eq(0).attr("src");
43	}
44	var datePickerOptions = {
45		dateFormat:'m/d/y',
46		showOn:'both',
47		buttonImageOnly:true,
48		changeMonth: true,
49		changeYear: true,
50		onSelect:function(dateText)
51		{
52			datePicked(this,dateText);
53		}
54	};
55
56	$("input.datePicker").each (function () {
57		if ($(this).hasClass("noIcon"))
58		{
59
60			datePickerOptions.buttonImage = transparentSource;
61			datePickerOptions.buttonText = '';
62		}
63		else
64		{
65			datePickerOptions.buttonImage = calendarSource;
66			datePickerOptions.buttonText = "click to select a date";
67		}
68		$(this).datepicker(datePickerOptions);
69	});
70
71	//	color pickers
72	$("div.colorPicker").each(function () {
73		var controlSelect = "#" + extractID ($(this).attr("id"));
74		$(this).farbtastic(controlSelect);
75	});
76
77	//	pmt form, select stored or new
78	$("#radio_storedPayment").on ('click', function () {
79		if ($(this).is(":checked"))
80		{
81			hide($("#newPaymentInfo"));
82		}
83	});
84	$("#radio_newPayment").on ('click', function () {
85		if ($(this).is(":checked"))
86		{
87			show($("#newPaymentInfo"));
88		}
89	});
90
91	//	paypal submit button
92	$("#startExpressCheckoutButton").on ('click', function () {
93		var agreed = $("#chkAgreeToTerms").is(":checked");
94		if (!agreed && $("#chkAgreeToTerms").length)
95		{
96			alert ('You must agree to the terms before you can continue.');
97			return false;
98		}
99		$("#startExpressCheckoutAgree").val(agreed ? 1 : 0);
100		$("#startExpressCheckoutForm").submit ();
101		return false;
102	});
103
104		//	fancy pull-downs for team colors
105	$("select.teamColorSelector").not('.delay').each (function () {
106		$(this).selectmenu({
107			style:'dropdown',
108			format: teamColorFormat
109		});
110	});
111
112	if ($("#stripePublishableKey").size() > 0)
113	{
114		initializeStripePayments ();
115	}
116
117	if ($("div#customPageForm").length > 0)
118	{
119		bindTextAreaLengthCheck();
120	}
121
122	initializeButtonsWithSpinners ();
123	ll_formValidatorsLoaded = true;
124});
125
126function bindTextAreaLengthCheck()
127{
128	$("div#customPageForm form").submit(function(e){
129		var textareaInputCheck = true;
130		var errorMsg = '';
131		$("div#customPageForm form").find("textarea").each(function () {
132			var currentLen = $(this).val().length;
133
134			if (currentLen > 1900 && !$(this).attr('id').includes('captcha'))
135			{
136				var label = $(this).parents("div.formField").find("label").text().trim();
137				errorMsg += '\n- ' + label + '   ' + currentLen + ' characters';
138				textareaInputCheck = false;
139			}
140		});
141
142		if (textareaInputCheck)
143			return true;
144		else {
145			alert("Exceeded 1,900 character limit for following fields:\n" + errorMsg);
146			return false;
147		}
148	});
149}
150
151/*
152*	skipRequired is just a hack so we can have multiple forms on one page
153*	and still validate the numeric fields without one form submission getting angry about
154*	empty fields that actually belong to another form... (note that they might all be part
155*	of the same <form>, but visually presented as separate views via JS... see PaymentActions)
156*		The correct answer is 'Validation Groups'
157*/
158function ll_generic_form_validate (skipRequired)
159{
160	var emptyFields = emptyRequiredFields ();
161	var numberFields = badNumericFields ();
162	var message = "";
163
164	if (!skipRequired) {
165		message += messageForRequiredFields(emptyFields, {});
166	}
167	message += messageForNumericFields (numberFields);
168
169	if (message == "")
170	{
171		if ($("#formInputValidated").length > 0)
172		{
173			$("#formInputValidated").val(1);
174		}
175		return true;
176	}
177	else
178	{
179		alert (message);
180		return false;
181	}
182}
183
184function messageForRequiredFields (emptyFields, skipFields)
185{
186	var message = '';
187	if (emptyFields.length > 0)
188	{
189		for (var i = 0; i < emptyFields.length; i++)
190		{
191			if (!skipFields[emptyFields[i]]) {
192				message += "  > " + emptyFields[i] + "\n";
193			}
194		}
195	}
196
197	if (message != '')
198	{
199		message = "Please be sure to fill in the following required fields: \n" + message + "\n\n";
200	}
201	return message;
202}
203
204function messageForNumericFields (numberFields)
205{
206	var message = '';
207	if (numberFields.length > 0) {
208		message += "The following fields require numeric values: \n";
209		for (var i = 0; i < numberFields.length; i++)
210		{
211			message += "  > " + numberFields[i] + "\n";
212		}
213		message += "\n\n";
214	}
215	return message;
216}
217
218//	get an array of the required fields that have been left empty
219function emptyRequiredFields ()
220{
221	var badFields = [];
222	var badFieldCount = 0;
223
224	$("input.paymentTerms").each(
225		function ()
226		{
227			if (!this.checked)
228			{
229				badFields[badFieldCount++] = "You must agree to the payment terms.";
230			}
231		}
232	);
233
234	var requiredSelectors = ":input.required,:input:visible.requiredIfVisible";
235	if ($("#teamColorIDContainer").is(":visible"))
236	{
237		requiredSelectors += ",#teamColorID.requiredIfVisible";
238	}
239	if ($("#teamColorPreferenceContainer").is(":visible"))
240	{
241		requiredSelectors += ",#colorOneID.requiredIfVisible,#colorTwoID.requiredIfVisible,#colorThreeID.requiredIfVisible";
242	}
243
244	$(requiredSelectors).each(
245		function(){
246			if	((!$(this).hasClass("checkbox") && $(this).val() == "") || ($(this).hasClass("checkbox") && !this.checked))
247			{
248				var pmtFields = {"Billing Address" : 1,"Credit Card Number" : 1,"Security Code" : 1};
249				var fieldName = getFieldName(this);
250				if ($("#radio_storedPayment").is(":checked") && pmtFields[fieldName])
251				{
252					return;
253				}
254				if (multiSelectSatisfied ($(this))) {
255					return;
256				}
257				if (indexOf (fieldName,badFields) == -1)
258				{
259					badFields[badFieldCount++] = fieldName;
260				}
261			}
262		}
263	);
264
265	function multiSelectSatisfied ($input) {
266		var $container = $input.parents ('.formInputContainer');
267		return ($container.hasClass ('multiSelect') && $container.find ('input:checked').length > 0);
268	}
269
270	return badFields;
271}
272
273function badNumericFields ()
274{
275	var badFields = [];
276
277	//	fields that allow $ and .
278	validateFieldsByRegExp ("input.fee,input.amountInput,input.paymentRequest", 'money', badFields);
279
280	//	pure numeric fields
281	validateFieldsByRegExp ("input.AreaCode,input.Prefix,input.LastFour,input.numericField,#input_CardNumber,#input_SecurityCode", 'number', badFields);
282
283	return badFields;
284}
285
286/*
287*	make sure all fields matching the given selector have values that match rePattern
288*	if they don't work, append their field name to the badFields array
289*/
290function validateFieldsByRegExp (sSelector, patternName, badFields)
291{
292	var badFieldCount = badFields.length;
293	$(sSelector).each (
294		function ()
295		{
296			if (!LLUtil.match ($(this).val (), patternName))
297			{
298				var fieldName = getFieldName(this);
299				if (indexOf (fieldName,badFields) == -1)
300				{
301					badFields[badFieldCount++] = fieldName;
302				}
303			}
304		}
305	);
306	return badFields;
307}
308
309//	generic callback for datepickers. If it's a single date picker, value is the date. If a range, value is an array
310//	with 'from' in position 0 and 'to' in position 1
311function datePicked(element,value)
312{
313	var id = $(element).attr("id");
314	callback = dateCallbacks[id];
315	if (callback)
316	{
317		callback(value);
318	}
319}
320
321function getFieldName(objElement)
322{
323	var labelText = $(objElement).parents("div.formField").find("label").html();
324	if ($(objElement).attr("id") == 'couponCodeInput')
325	{
326		labelText = "Coupon Code";
327	}
328	else if (labelText)
329	{
330		var nextTag = labelText.indexOf("<");
331		if (nextTag != -1)
332		{
333			labelText = labelText.substr(0,nextTag);
334		}
335	}
336	else
337	{
338		var jqObj = $(objElement);
339		if (jqObj.hasClass("fee") || jqObj.hasClass("paymentRequest") || jqObj.hasClass ("amountInput"))
340		{
341			labelText = "All Dollar Amounts";
342		}
343	}
344	return labelText.trim ();
345}
346
347/**
348*	certain buttons should disappear and get replaced by loading graphics when they're clicked.
349*/
350function initializeButtonsWithSpinners ()
351{
352	$('.buttonWithSpinner').each (function () {
353		var jqImage = $('<img class="submitButtonSpinner hidden" alt="Processing...please wait." src="/static/graphics/loader-image-30.gif" />').insertAfter ($(this));
354		var jqForm = $(this).parents('form');
355		if (jqForm.length > 0) {
356			jqForm.on ('submit', function () {
357				$(this).find ('.buttonWithSpinner').each (function () {
358					jqButton = $(this);
359					doShowSpinner (jqButton);
360				}).end ().find ('.hideOnSubmit').hide ();
361			});
362		} else {
363			$(this).on ('click', function () {
364				doShowSpinner ($(this));
365			});
366		}
367	});
368}
369function doShowSpinner (jqButton)
370{
371	if (jqButton.is(':visible'))
372	{
373		hide (jqButton);
374		showLoadingGraphic(jqButton.next('img.submitButtonSpinner'), 250);
375	}
376}
377
378/**
379*	set up the payment form to work with Stripe
380*/
381function initializeStripePayments ()
382{
383	var jqKey = $("#stripePublishableKey");
384	var jqForm = jqKey.parents ('form');
385	jqForm.on ('submit', function () {
386		Stripe.setPublishableKey(jqKey.val ());
387		jqCardNumberInput = $("#input_CardNumber");
388		if (jqCardNumberInput.size () == 0 || !jqCardNumberInput.is (':visible'))
389		{
390			return true;	//	if the payment inputs aren't visible, we're not processing pmt so we let the form do what it will
391		}
392		var cardInfo = {
393			number: jqForm.find('#input_CardNumber').val (),
394			cvc: jqForm.find('#input_SecurityCode').val (),
395			exp_month: jqForm.find('select[name="ExpirationMonth"]').val (),
396			exp_year: jqForm.find('select[name="ExpirationYear"]').val (),
397			name: jqForm.find('input[name="FirstName"]').val () + ' ' + jqForm.find('input[name="LastName"]').val (),
398			address_line1: jqForm.find('input[name="AddressOne"]').val (),
399			address_city: jqForm.find('input[name="City"]').val (),
400			address_state: jqForm.find('input[name="State"]').val (),
401			address_zip: jqForm.find('input[name="PostalCode"]').val ()
402		};
403
404		Stripe.createToken(cardInfo, function (status, response) {
405			if (response.error)
406			{
407				$('<input name="StripeError" type="hidden" />').val (response.error.code).appendTo (jqForm);
408			}
409			else
410			{
411				$('<input name="StripeToken" type="hidden" />').val (response.id).appendTo (jqForm);
412			}
413			jqForm.get(0).submit ();
414		});
415		return false;
416	});
417}
418
419//	function to format the team color pull-downs, adding the swatch
420var teamColorFormat = function (text)
421{
422	var escaped = LLUtil.escapeTags (text);
423	return escaped.replace (/([^_]*)___([\da-fA-F]{6})___/g,'<div class="teamColorOption"><div class="teamColorSwatch" align="left" style="background-color:#$2;">&nbsp;</div>$1</div>');
424};
425
426// prevent selecting the same color more than once
427if ($("#teamColorPreferenceContainer").length > 0 || $("#nonIndyTeamInfo").length > 0)
428	{
429		var removedOptions = new Array();
430		$("[id^=color][id$=ID]").each(function(i, el) {
431			$(el).change(function() {
432				var newValue = this.value;
433				var selectedOption = $(this).children('option[selected]');
434				var currentValuesArr = new Array(this.value);
435				// if we have a valid choice, not the "Choose One" option, remove it from the other selects and add it to the removedOptions holder
436				if(newValue != '')
437				{
438					$("[id^=color][id$=ID]").not(el).each(function() {
439						currentValuesArr.push(this.value);
440						$(this).children('option[value=' + newValue + ']').each(function() { $(this).remove(); });
441						$(this).selectmenu('destroy').selectmenu({ style:'dropdown', format: teamColorFormat });
442					});
443					if(removedOptions.length == 0)
444					{
445						removedOptions.push(selectedOption);
446					}
447					else
448					{
449						var push = true;
450						for(i = 0; i < removedOptions.length; i++)
451						{
452							if(selectedOption == removedOptions[i])
453							{
454								push = false;
455							}
456						}
457						if(push) removedOptions.push(selectedOption);
458					}
459				}
460				else
461				{
462					$("[id^=color][id$=ID]").not(el).each(function() {
463						currentValuesArr.push(this.value);
464					});
465				}
466				// replace removed options as necessary
467				for(i = 0; i < removedOptions.length; i++)
468				{
469					// if any element of removedOptions is not one of the currently selected values then add it back to all selects and remove it from the array
470					if($.inArray(removedOptions[i].val(), currentValuesArr) == -1)
471					{
472						$("[id^=color][id$=ID]").each(function() {
473							if($.inArray(removedOptions[i], $(this).children('option')) == -1)
474							{
475								var currentValue = this.value;
476								$(this).append(removedOptions[i]);
477								// resort options
478								var options = $(this).children('option');
479								options.sort(function(a,b) {
480									if(a.value == '' || a.text < b.text) return -1;
481									else if(a.text > b.text) return 1;
482									else return 0;
483								});
484								$(this).empty().append(options).val(currentValue);
485								$(this).selectmenu('destroy').selectmenu({ style:'dropdown', format: teamColorFormat });
486							}
487						});
488						removedOptions.splice(i, 1);
489					}
490				}
491			});
492		});
493	}

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.