Newer
Older
dmpopidor / lib / assets / javascripts / utils / ariatiseForm.js
import { isObject, isString, isBoolean } from './isType';
import DomManipulator from '../../utils/domManipulator';
import * as constants from '../constants';
import * as validator from './isValidInputType';

const validatableFields = (selector) => {
  const fields = new DomManipulator('.form-control [data-validation], [aria-required="true"]');
console.log(`eher we am: ${$('form').length}`);

    return $(selector).find('.form-control').filter('[data-validation], [aria-required="true"]');
  }
  return [];
};
const blockHelp = (id, msg) => {
  if (isString(id) && isString(msg)) {
    return `<span id="${id}" class="help-block" style="display:none;">${msg}</span>`;
  }
  return '';
};
const ariaDescribedBy = (value) => {
  if (isBoolean(value)) {
    return { 'aria-describedby': value };
  }
  return null;
};
const ariaInvalid = (value) => {
  if (isBoolean(value)) {
    return { 'aria-invalid': value };
  }
  return { 'aria-invalid': false };
};

const validationStates = {
  hasWarning: 'has-warning',
  hasError: 'has-error',
  hasSuccess: 'has-success' };

const getValidationTypeForElement = (el) => {
  const validation = $(el).attr('data-validation');
  // if the specified validation type is defined
  if (validation) {
    return $(el).attr('data-validation');

  // Otherwise if the element is required validate based on its type
  } else if ($(el).attr('aria-required') === 'true') {
    // TODO: Need to deal with select and radio as well!
    return ($(el).prop('tagName') === 'textarea' ? 'text' : $(el).attr('type'));
  }
  return false;
};

const isValid = (type, value) => {
  // TODO add more validation for each new type coming along by:
  // 1. defining a function at dmproadmap.utils.validate
  // 2. adding the case in the switch below

  // See if a specific data-validation was specified 
  switch (type) {
    case 'text':
      return validator.isValidText(value);
    case 'number':
      return validator.isValidNumber(value);
    case 'email':
      return validator.isValidEmail(value);
    case 'password':
      return validator.isValidPassword(value);
    default:
      return false;
  }
};

const getValidationMessage = (type) => {
  switch (type) {
    case 'text':
      return constants.VALIDATION_MESSAGE_TEXT;
    case 'number':
      return constants.VALIDATION_MESSAGE_NUMBER;
    case 'email':
      return constants.VALIDATION_MESSAGE_EMAIL;
    case 'password':
      return constants.VALIDATION_MESSAGE_PASSWORD;
    default:
      return constants.VALIDATION_MESSAGE_DEFAULT;
  }
};

const valid = (el) => {
  $(el).parent().removeClass(validationStates.hasError);
  $(el).attr(ariaInvalid(false));
  $(el).next().hide();
};
const invalid = (el) => {
  $(el).parent().addClass(validationStates.hasError);
  $(el).attr(ariaInvalid(true));
  $(el).next().show();
};

export default (el) => {
  if (el instanceof DomManipulator) {
    const validatable = validatableFields(el);

console.log(validatable.length);

    // Add validation error message sections for each validatable input element
    validatable.each((i, el) => {
      const type = getValidationTypeForElement(el);
      $(el).attr(ariaDescribedBy(`help${i}`));
      $(el).after(blockHelp(`help${i}`, getValidationMessage(type)));
    });

    // Bind validations to the form's submit button
    $(`${options.selector} [type="submit"]`).click((e) => {
      validatable.each((i, el) => {
        const type = getValidationTypeForElement(el);
        if (isValid(type)) {
          valid(el);
        } else {
          e.preventDefault();
          invalid(el, getValidationMessage(type));
        }
      });
    });
  }
};