Form Validation

by kyllle

HTML

<div>
  <div class="info_message asterisk long form_text_input">
    <label for="phone_number">Phone Number*</label>
    <div class="form-input-container has-error">
      <input type="text" name="phone_number" id="phone_number" class="owner-info-modal-form__field">
    </div>
  </div>
  <div class="info_message asterisk long form_text_input">
    <label for="state">State</label>
    <div class="form-input-container has-error">
      <select name="state" id="state" class="owner-info-modal-form__drop-down">
        <option value="">Select State</option>
        <option value="AL">AL</option>
        <option value="AK">AK</option>
        <option value="AZ">AZ</option>
        <option value="AR">AR</option>
        <option value="CA">CA</option>
        <option value="CO">CO</option>
        <option value="CT">CT</option>
        <option value="DE">DE</option>
        <option value="DC">DC</option>
        <option value="FL">FL</option>
        <option value="GA">GA</option>
        <option value="GU">GU</option>
        <option value="HI">HI</option>
        <option value="ID">ID</option>
        <option value="IL">IL</option>
        <option value="IN">IN</option>
        <option value="IA">IA</option>
        <option value="KS">KS</option>
        <option value="KY">KY</option>
        <option value="LA">LA</option>
        <option value="ME">ME</option>
        <option value="MD">MD</option>
        <option value="MA">MA</option>
        <option value="MI">MI</option>
        <option value="MN">MN</option>
        <option value="MS">MS</option>
        <option value="MO">MO</option>
        <option value="MT">MT</option>
        <option value="NE">NE</option>
        <option value="NV">NV</option>
        <option value="NH">NH</option>
        <option value="NJ">NJ</option>
        <option value="NM">NM</option>
        <option value="NY">NY</option>
        <option value="NC">NC</option>
        <option value="ND">ND</option>
        <option...

CSS

.has-error {
  border-color: red;
}

JavaScript

console.clear()


const validationSchema = {
  phone_number: [{
  		required: true,
  		message: 'Custom message for empty input'
  	}, {
      validate: (el) => allNumeric(el.value),
      message: 'Please enter your phone number with numbers only.'
    },
    {
      validate: ({ value }, comp) => gte(value.length, comp),
      params: 10,
      message: 'Should be greater than 10 characters'
    }
  ],
  email: [{
    validate: ({ value }) => isFormatted(value),
    message: 'Should have an @ and a .'
  }],
  social_security_input: [{
    validate: ({ value }) => equals(value),
    params: 9,
    message: 'Should be exactly 9 characters'
  }, {
  	validate: (el) => allNumeric(el.value),
    message: 'Please enter your SSN with numbers only.'
	}],
  user_dob_1i: [{
    validate: (el) => gte(difference(getCurrentYear(), toNumber(el.value)), 18),
    message: 'Should be at least 18 years old'
  }]
}

// Validator functions
const isEmpty = (value) => value === 0
const allNumeric = (value) => !isNaN(value)
const isFormatted = (str, matcher = /\S+@\S+\.\S+/) => matcher.test(str)
const gte = (num, comparator) => num >= comparator
const equals = (num, comparator) => num === comparator
const difference = (num, comparator) => num - comparator
const toNumber = (value) => Number(value)
const getCurrentYear = () => new Date().getFullYear()

const createErrorTemplate = message => `<p class="validation-error">${message}</p>`
const createElement = type => document.createElement(type)

function validateInput(el, schema) {
  resetInvalidElement(el)

  let errors = []

  const validationEntry = validationSchema[el.id]


  if (validationEntry) {
    validationEntry.some(rule => {
      if(
				rule.required && isEmpty(el.value.length) ||
        rule.validate && !rule.validate(el, rule.params)
       ) {
				errors = [rule.message, ...errors]
        return true
      }
    })
  }

  return errors.length ? markElementInvalid(el, errors) : true
}

function markElementInvalid(el,...