/** * User: DatornData dataskills@gmail.com * Date: 08/01/19 * Time: 1:19 PM * */ SiForm = function (params) { this.cygnusUrl = ''; if (params.env === 'undefined') { throw 'Required env variable is missing'; } else { this.env = params.env; this.cygnusUrl = (this.env === 'dev') ? 'http://cygnus.loc' : 'https://www.studyusa.com'; } // from html content this.formAction = null; // from data fetch this.subjectMap = null; this.defaultPrompt = null; this.fieldOfStudyPrompt = null; // from script tag this.code = null; this.language = 'en'; this.containerElementId = null; this.styleData = null; this.fieldData = null; this.optionalFields = [ 'middleName', 'streetAddress', 'streetAddressLine2', 'city', 'stateProvince', 'postalCode', 'messagingAppId', 'messagingAppUsername', 'studyBeginDate', 'standardizedTestId', 'standardizedTestScore', 'tuitionRangeId', 'comment', 'optins' ]; }; // SiForm.prototype.init = function () { let _this = this; // set variable from script tag _this.setVars(); // get form html _this.fetchFormData(_this.code, _this.language); // validate init if (_this.code === null) { throw 'Required parameter "code" is null'; } }; SiForm.prototype.setVars = function () { let _this = this; let scriptElement = document.getElementById("si-form"); // container element id let containerIdSetting = scriptElement.getAttribute("data-container-id"); if (containerIdSetting === null) { _this.containerElementId = 'siform-container'; // create element for form let formContainer = document.createElement('div'); formContainer.setAttribute('id', _this.containerElementId); scriptElement.parentNode.insertBefore(formContainer, scriptElement.nextSibling); } else { _this.containerElementId = containerIdSetting; } // check to make sure form container exists if (document.getElementById(_this.containerElementId) === null) { throw 'SiForm container not found'; } // advcode or campaignCode _this.code = scriptElement.getAttribute("data-code"); // language _this.language = scriptElement.getAttribute("data-language"); // styles let styleInformation = scriptElement.getAttribute("data-style"); _this.styleData = _this.processStyleData(styleInformation); // remove fields _this.fieldData = scriptElement.getAttribute("data-xfields"); }; SiForm.prototype.registerEvents = function () { let _this = this; /* field of study and degree level select [begin] */ document.querySelectorAll("select[name='Inquiry[degreeLevelId]'], select[name='CampaignLead[degreeLevelId]']") .forEach(function (select) { select.addEventListener('change', function () { let degreeLevelId = this.value; //deselect field of study (set choose note as well) document.querySelectorAll("select[name='Inquiry[fieldOfStudyId]'] option, select[name='CampaignLead[fieldOfStudyId]'] option") .forEach(function (option) { option.parentNode.removeChild(option); }); if (degreeLevelId === '') { document.querySelectorAll("select[name='Inquiry[fieldOfStudyId]'], select[name='CampaignLead[fieldOfStudyId]']") .forEach(function (select) { let option = document.createElement('option'); option.value = ''; option.text = _this.fieldOfStudyPrompt; select.appendChild(option); }); } else if (_this.isPositiveNumber(degreeLevelId)) { document.querySelectorAll("select[name='Inquiry[fieldOfStudyId]'], select[name='CampaignLead[fieldOfStudyId]']") .forEach(function (select) { let option = document.createElement('option'); option.value = ''; option.text = '[' + _this.defaultPrompt + ']'; select.appendChild(option); }); let fieldsOfStudy = _this.subjectMap[degreeLevelId]['fieldsOfStudy']; for (let x in fieldsOfStudy) { let fos = fieldsOfStudy[x]; document.querySelectorAll("select[name='Inquiry[fieldOfStudyId]'], select[name='CampaignLead[fieldOfStudyId]']") .forEach(function (select) { let option = document.createElement('option'); option.value = fos.fieldOfStudyId; option.text = fos.fieldOfStudyName; select.appendChild(option); }); } } }); }); /* field of study and degree level select [end] */ // form submit document.getElementById('formSubmitButton') .addEventListener('click', function () { _this.runFormHandler(); }); /* date dropdowns begin */ document.querySelectorAll("select#studyBeginDate-month, select#dateOfBirth-month") .forEach(function (select) { select.addEventListener('change', function () { let month = this.value; let selectId = null; let year = null; let yearSelected = false; if (select.id === 'studyBeginDate-month') { selectId = 'studyBeginDate-day'; if (document.getElementById('studyBeginDate-year').value !== '') { year = document.getElementById('studyBeginDate-year').value; yearSelected = true; } } else if (select.id === 'dateOfBirth-month') { selectId = 'dateOfBirth-day'; if (document.getElementById('dateOfBirth-year').value !== '') { year = document.getElementById('dateOfBirth-year').value; yearSelected = true; } } if (!yearSelected) { // if no year selected use current year year = new Date().getFullYear(); } _this.populateDaySelect(month, year, selectId); }); }); document.querySelectorAll("select#studyBeginDate-year, select#dateOfBirth-year") .forEach(function (select) { select.addEventListener('change', function () { let year = this.value; let selectId = null; let month = null; let monthSelected = false; if (select.id === 'studyBeginDate-year') { selectId = 'studyBeginDate-day'; if (document.getElementById('studyBeginDate-month').value !== '') { month = document.getElementById('studyBeginDate-month').value; monthSelected = true; } } else if (select.id === 'dateOfBirth-year') { selectId = 'dateOfBirth-day'; if (document.getElementById('dateOfBirth-month').value !== '') { month = document.getElementById('dateOfBirth-month').value; monthSelected = true; } } if (!monthSelected) { // if no month selected use January month = 1; } _this.populateDaySelect(month, year, selectId); }); }); // set date fields document.querySelectorAll("select[id^='studyBeginDate'],select[id^='dateOfBirth']") .forEach(function (select) { select.addEventListener('change', function () { let type = 'dateOfBirth'; if (this.id.indexOf('studyBeginDate') > -1) { type = 'studyBeginDate'; } document.querySelectorAll("input[type='hidden'][id$='" + type.toLowerCase() + "']") .forEach(function (input) { input.value = _this.getCompositeDateValue(type); }); }); }); /* date dropdowns end */ /* phone dropdowns begin */ let phoneNumber = document.getElementById('phone-number'); let phoneCountryCode = document.getElementById('phone-country-code'); phoneCountryCode.addEventListener('change', function () { let phoneValue = ''; if (this.value !== '') { let callingCode = _this.getCallingCodeValue(); phoneValue = '+' + callingCode + phoneNumber.value; _this.setPhoneValue(phoneValue); } }); phoneNumber.addEventListener('keyup',function() { let phoneValue = ''; if (this.value !== '') { let callingCode = _this.getCallingCodeValue(); phoneValue = '+' + callingCode + phoneNumber.value; _this.setPhoneValue(phoneValue); } }); /* phone dropdowns end */ }; SiForm.prototype.getCallingCodeValue = function () { let rawValue = document.getElementById('phone-country-code').value; let callingCode = ''; if(rawValue !== '') { let parts = rawValue.split('-'); callingCode = parts[1]; } return callingCode; }; SiForm.prototype.setPhoneValue = function (phoneValue) { let _this = this; document.querySelectorAll("input[name='Inquiry[phone]'], input[name='CampaignLead[phone]']") .forEach(function (input) { input.value = phoneValue; }); }; SiForm.prototype.dateFilled = function (type) { let _this = this; if (!_this.dateTypeValid(type)) { return false; } // go through all selects, if one not filled return false otherwise true document.querySelectorAll("select[id^='" + type + "']") .forEach(function (select) { if (select.value === '') { return false; } }); return true; }; SiForm.prototype.getCompositeDateValue = function (type) { let _this = this; let dateString = ''; if (!_this.dateFilled(type)) { return dateString; } dateString += document.getElementById(type + '-year').value; dateString += '-'; dateString += document.getElementById(type + '-month').value; dateString += '-'; dateString += document.getElementById(type + '-day').value; return dateString; }; SiForm.prototype.dateTypeValid = function (type) { let _this = this; let validTypes = ['studyBeginDate', 'dateOfBirth']; return (validTypes.indexOf(type) > -1); }; SiForm.prototype.populateDaySelect = function (month, year, selectId) { var _this = this; let selectElement = document.getElementById(selectId); let daysInMonth = _this.getNumDaysInMonth(month, year); let optionElements = []; let currentlySelectedDay = selectElement.value; for (let x = 1; x < daysInMonth; x++) { let option = document.createElement('option'); let day = x; option.value = day; option.text = day.toString(); option.selected = (day === parseInt(currentlySelectedDay)); //if selected day in new options select it optionElements.push(option); } // remove existing day options selectElement.options.length = 0; for (var i in optionElements) { selectElement.appendChild(optionElements[i]); } }; SiForm.prototype.fetchFormData = function (code, language) { let _this = this; const url = _this.cygnusUrl + '/' + language + '/remote-form/data?code=' + code + '&language=' + language; fetch(url) .then(response => { return response.json() } ).then(data => { //go through data, assign _this.fieldOfStudyPrompt = data.fieldOfStudyPrompt; _this.defaultPrompt = data.defaultPrompt; _this.subjectMap = data.subjectMap; _this.language = data.language; _this.fetchFormHtml(code, language); }); }; SiForm.prototype.fetchFormHtml = function (code, language) { let _this = this; const url = _this.cygnusUrl + '/' + language + '/remote-form/markup?code=' + code + '&language=' + language; fetch(url) .then(response => { return response.text() } ).then(html => { document.getElementById(_this.containerElementId).innerHTML = html; //register events _this.registerEvents(); //set form action; get it from the form _this.formAction = document.getElementById('inquiryForm').getAttribute('action'); _this.processStyle(_this.styleData); _this.removeFields(_this.fieldData); }); }; SiForm.prototype.runFormHandler = function () { let _this = this; let xhr = new XMLHttpRequest(); let formData = new FormData(); // Push data into our formData object document.querySelectorAll('*[id^="inquiry-"],*[id^="campaignlead-"]') .forEach(function (el) { let nameAttr = el.getAttribute('name'); if (nameAttr !== null) { let from = (nameAttr.indexOf('[') + 1); let length = ((nameAttr.indexOf(']') - nameAttr.indexOf('[')) - 1); let fieldName = nameAttr.substr(from, length); formData.append(fieldName, el.value); } }); // Define what happens on successful data submission xhr.addEventListener('load', function (event) { if (xhr.status === 422) // validation issue { _this.renderValidationErrors(xhr.response); } else if (xhr.status === 200 || xhr.status === 201) { let result = {}; result.success = true; result.html = '
We have received your submission. We will be in touch with you as soon as possible.
'; _this.displayMessage(result); } else { alert(xhr.responseText); } }); // Define what happens in case of error xhr.addEventListener('error', function (event) { let result = {}; result.success = false; result.html = '
There was a problem with your submission. We apologize for any inconvenience. Please try again later.
'; _this.displayMessage(result); }); // Set up our request xhr.open('POST', _this.formAction); xhr.responseType = 'json'; // Send our FormData object; HTTP headers are set automatically xhr.send(formData); }; SiForm.prototype.displayMessage = function (result) { let _this = this; //todo: get translated message/html from cygnus? document.getElementById(_this.containerElementId).innerHTML = result.html; }; SiForm.prototype.renderValidationErrors = function (data) { let _this = this; // empty error message div let errorMessageDiv = document.getElementById('error-messages'); errorMessageDiv.style.display = ''; //show errorMessageDiv.innerHTML = ''; let html = ''; errorMessageDiv.innerHTML = html; }; SiForm.prototype.processStyleData = function (styleInformation) { let _this = this; let styleData = {}; let settingKvPairs = styleInformation.split(','); for (var i in settingKvPairs) { let kvpArray = settingKvPairs[i].split(':'); styleData[kvpArray[0]] = kvpArray[1]; } return styleData; }; SiForm.prototype.processStyle = function (styleData) { let _this = this; let formContainer = document.getElementById(_this.containerElementId); let formButton = document.getElementById('formSubmitButton'); let greetingElement = document.getElementById('greeting'); for (var item in styleData) { let setting = styleData[item]; switch (item) { case"backgroundColor": formContainer.style.setProperty('background-color',setting,'important'); break; case "fontColor": formContainer.style.setProperty('color',setting,'important'); greetingElement.style.setProperty('color',setting,'important'); break; case "formWidth": formContainer.style.setProperty('width',setting,'important'); break; case "formPadding": formContainer.style.setProperty('padding',setting,'important'); break; case "buttonColor": formButton.style.setProperty('background-color',setting,'important'); break; case "buttonTextColor": formButton.style.setProperty('color',setting,'important'); break; } } }; SiForm.prototype.removeFields = function (fieldList) { var _this = this; let fieldCollection = fieldList.split(','); for (var x in fieldCollection) { let lowercaseFieldName = fieldCollection[x].toLowerCase(); document.querySelectorAll('div[class~="field-inquiry-' + lowercaseFieldName + '"], div[class~="field-campaignlead-' + lowercaseFieldName + '"]') .forEach(function (el) { el.style.display = 'none'; }); } }; SiForm.prototype.isPositiveNumber = function (str) { let _this = this; return ((_this.isNumeric(str)) && ((parseInt(str)) > 0)); }; SiForm.prototype.isNumeric = function (str) { let pattern = /^-?\d+$/; return pattern.test(str); }; SiForm.prototype.getNumDaysInMonth = function (month, year) { return (new Date(year, month, 0).getDate() + 1); }; //_si = new SiForm({"env":"dev"}); //_si.init(); _si = new SiForm({"env":"prod"});_si.init();