RHeactorJS/web-app

View on GitHub
js/directives/bootstrap-error-states.js

Summary

Maintainability
A
35 mins
Test Coverage
const setErrorStates = (element, modelCtrl) => {
  const parent = element.parents('.form-group')
  if (modelCtrl.$valid) {
    element.addClass('form-control-success')
    element.removeClass('form-control-danger')
    if (parent) {
      parent.addClass('has-success')
      parent.removeClass('has-danger')
    }
  } else {
    element.addClass('form-control-danger')
    element.removeClass('form-control-success')
    if (parent && modelCtrl.$dirty) {
      parent.addClass('has-danger')
      parent.removeClass('has-success')
    }
  }
}

const resetErrorStates = (element) => {
  element.removeClass('form-control-danger')
  element.removeClass('form-control-success')
  const parent = element.parents('.form-group')
  if (parent) {
    parent.removeClass('has-danger')
    parent.removeClass('has-success')
  }
}

export const BootstrapErrorStatesDirective = {
  restrict: 'A',
  require: ['ngModel', '^form'],
  link: (scope, element, attrs, ctrls) => {
    const modelCtrl = ctrls[0]
    const formCtrl = ctrls[1]
    modelCtrl.$viewChangeListeners.push(() => {
      setErrorStates(element, modelCtrl)
    })
    modelCtrl.$parsers.push((viewValue) => {
      setErrorStates(element, modelCtrl)
      return viewValue
    })
    // watch for changes on the pristine state (form might get reset)
    // and reset the error states
    if (modelCtrl.$name) { // can be empty on textareas
      scope.$watch(formCtrl.$name + '.' + modelCtrl.$name + '.$pristine', (isPristine, wasPristine) => {
        if (!wasPristine && isPristine) {
          resetErrorStates(element)
        }
      })
    }
  }
}