1class FormatDate { 2 static getValueByFormat(value, format) { 3 const date = new Date(value) 4 const char = format.includes('/') ? '/' : (format.includes('.') ? '.' : false) 5 const parsing = format.includes('/') ? format.split('/') : (format.includes('.') ? format.split('.') : false) 6 const conformities = { 7 dd: 'getDate', 8 mm: 'getMonth', 9 yyyy: 'getFullYear' 10 } 11 return parsing.map((item, index) => { 12 const v = date[conformities[item]]().toString() 13 return v.length < 2 ? `0${v}` : v 14 }).join(char) 15 } 16} 17 18class UnisenderForm { 19 constructor(form) { 20 if (!form) return false 21 if (!unisenderValidationErrorTexts) return false 22 if (!UNISENDER_AJAX) throw new Error(`"UNISENDER_AJAX" not found`) 23 if (!unisenderDoubleOptin) return false 24 this.doubleOptin = unisenderDoubleOptin 25 this.form = form 26 this.contactList = this.form.getAttribute('data-contact-list') 27 this.fields = this.form.querySelectorAll('[data-unisender-field]') 28 this.submitButton = this.form.querySelector('.b-unisender-form__submit-button') 29 this.fieldWraps = this.form.querySelectorAll('[data-unisender-field-name]') 30 this.errorPlaces = this.form.querySelectorAll('[data-unisender-field-error]') 31 this.errorTexts = unisenderValidationErrorTexts 32 this.errors = [] 33 this.ajaxUrl = UNISENDER_AJAX.url 34 35 this.test = { 36 required: v => { 37 return !v 38 }, 39 minLength: (v, r) => { 40 return v ? !(v.length >= parseFloat(r)) : false 41 }, 42 maxLength: (v, r) => { 43 return v ? !(v.length <= parseFloat(r)) : false 44 }, 45 minNumber: (v, r) => { 46 return v ? !(parseFloat(v) >= parseFloat(r)) : false 47 }, 48 maxNumber: (v, r) => { 49 return v ? !(parseFloat(v) <= parseFloat(r)) : false 50 }, 51 regExp: (v, r) => { 52 return v ? !v : false 53 }, 54 email: (v, r) => { 55 const regExp = /\S+@\S+\.\S+/ 56 return !regExp.test(v) 57 } 58 } 59 60 this.init() 61 } 62 init() { 63 this.listeners() 64 } 65 66 listeners() { 67 this.submitButton.addEventListener('click', e => { 68 this.submitButtonHandleClick() 69 }) 70 } 71 72 submitButtonHandleClick() { 73 this.errors = [] 74 this.form.classList.remove('_show-message') 75 this.form.classList.remove('_success-text') 76 this.form.classList.remove('_validation-error-text') 77 this.form.classList.remove('_server-error-text') 78 79 for (let i = 0; i < this.fields.length; i++) { 80 const value = this.fields[i].getAttribute('type') === 'checkbox' ? this.fields[i].checked : this.fields[i].value 81 const rulesJson = this.fields[i].getAttribute('data-validation-rules') 82 const rules = rulesJson ? JSON.parse(rulesJson) : null 83 const activeRules = [] 84 if (this.fields[i].type === 'email') { 85 activeRules.push({ 86 name: 'email', 87 value: true 88 }) 89 } 90 Object.keys(rules).forEach(key => { 91 if (rules[key]) { 92 activeRules.push({ 93 name: key, 94 value: rules[key] 95 }) 96 } 97 }) 98 99 if (activeRules.length > 0) { 100 this.validationField(this.fields[i], activeRules, value) 101 } 102 } 103 104 if (this.errors.length === 0) { 105 this.request() 106 } 107 } 108 109 validationField(field, rules, value) { 110 const index = Array.prototype.indexOf.call(this.fields, field) 111 this.fieldWraps[index].classList.remove('_has-error') 112 this.errorPlaces[index].innerHTML = '' 113 114 const errors = []
115 rules.forEach(rule => { 116 if (this.test[rule.name](value, rule.value)) { 117 errors.push(rule.name) 118 } 119 }) 120 121 if (errors.length > 0) { 122 this.fieldWraps[index].classList.add('_has-error') 123 this.form.classList.add('_show-message') 124 this.form.classList.add('_validation-error-text') 125 126 errors.forEach(error => { 127 const errorKey = `${error}ErrorText` 128 console.log(errorKey) 129 this.errorPlaces[index].innerHTML = this.errorTexts[errorKey] 130 }) 131 132 this.errors.push(errors) 133 } 134 } 135 136 request() { 137 this.submitButton.parentElement.classList.add('request') 138 const formData = new FormData() 139 const data = {} 140 141 formData.set('action', 'unisender_subscribe') 142 formData.set('contact_list', this.contactList) 143 formData.set('double_optin', this.doubleOptin) 144 145 for (let i = 0; i < this.fields.length; i++) { 146 const field = this.fields[i] 147 const name = field.getAttribute('name') 148 const type = field.type 149 const value = type === 'date' ? FormatDate.getValueByFormat(field.value, field.getAttribute('data-date-type')) : field.value 150 if (name) { 151 data[name] = value 152 } 153 } 154 155 formData.set('data', JSON.stringify(data)) 156 fetch( 157 this.ajaxUrl, 158 { 159 method: 'POST', 160 body: formData 161 } 162 ) 163 .then(response => response.json()) 164 .then(response => { 165 this.submitButton.parentElement.classList.remove('request') 166 if (response.status === 'success') { 167 this.form.classList.add('_show-message') 168 this.form.classList.add('_success-text') 169 this.dropFieldsValue() 170 } else { 171 this.form.classList.add('_show-message') 172 this.form.classList.add('_server-error-text') 173 } 174 }) 175 } 176 dropFieldsValue() { 177 for (let i = 0; i < this.fields.length; i++) { 178 const field = this.fields[i] 179 if (field.type !== 'checkbox') { 180 field.value = null 181 } else { 182 field.checked = false 183 } 184 } 185 } 186} 187 188document.addEventListener('DOMContentLoaded', () => { 189 const unisenderForms = document.querySelectorAll('[data-contact-list]') 190 for (let i = 0; i < unisenderForms.length; i++) { 191 new UnisenderForm(unisenderForms[i]) 192 } 193})
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.