********************* foundation-validation ********************* Field validation in Granite UI is designed to replicate `HTML Forms Constraint Validation API `_. See also :doc:`../../vocabulary/field` for standardized field vocabulary. Selector ======== :-foundation-submittable ------------------------ Selects elements indicating the *logical* field. Only elements selectable by this selector are validated. This pseudo selector is extensible by registering ``foundation.validation.selector``. Note that since this selector is a custom jQuery selector, it can only be used using jQuery. Markup ====== [data-foundation-validation-ui] ------------------------------- Indicates the configuration related to the UI of the validation. The supported value is ``none``, which means the UI is not shown. Selector Rule:: [data-foundation-validation-ui]:-foundation-submittable AdaptTo Interface ================= type ``foundation-validation`` condition ``:-foundation-submittable`` returned type ``FoundationValidation`` .. code-block:: ts interface FoundationValidation { /** * Returns true if the element will be validated when the form is submitted * (i.e. The element that is satisfying FoundationValidationSelector#candidate selector); false otherwise. * * @see {@link http://www.w3.org/TR/html5/forms.html#dom-cva-willvalidate} */ willValidate: () => boolean; /** * Returns the error message that would be shown to the user if the element was to be checked for validity. * * @return The error message or an empty string * @see {@link http://www.w3.org/TR/html5/forms.html#dom-cva-validationmessage} */ validationMessage: () => string; /** * Returns the validity state of the element. */ getValidity: () => FoundationValidationValidity; /** * Returns true if the element's value has no validity problems; false otherwise. * Fires foundation-validation-invalid or foundation-validation-valid event at the element when it is invalid or valid respectively. * * @return The validity * @see {@link http://www.w3.org/TR/html5/forms.html#dom-cva-checkvalidity} */ checkValidity: () => boolean; /** * Sets a custom error, so that the element would fail to validate. * The given message is the message to be shown to the user when reporting the problem to the user. * If the argument is the empty string, clears the custom error. * * @param message The error message or empty string * @see {@link http://www.w3.org/TR/html5/forms.html#dom-cva-setcustomvalidity} */ setCustomValidity: (message: string) => void; /** * Shows error UI if the element is invalid; hide the UI otherwise. */ updateUI: () => void; } interface FoundationValidationValidity { /** * Returns the custom error message. */ getCustomError: () => string; /** * Returns true if the element's value has no validity problems; false otherwise. * The value is only accurate when #isValidated() is true. */ isValid: () => boolean; /** * Returns true if the element has been validated; false otherwise. * For performance, to check if an element is valid is better done by checking this method first and then call #isValid() or FoundationValidation#checkValidity. * * Example *

      * // Returns true if the container is valid; false otherwise.
      * function isValid(container) {
      *   return Array.prototype.every.call(container.find(":-foundation-submittable"), function(v) {
      *     var api = $(v).adaptTo("foundation-validation");
      *     var state = api.getValidity();
      *
      *     if (state.isValidated()) {
      *       return state.isValid(); // Calling this is much faster than `api.checkValidity()`.
      *     } else {
      *       return api.checkValidity();
      *     }
      *   });
      * }
      * 
*/ isValidated: () => boolean; } Form Submission =============== ``foundation-validation`` will `capture `_ the form ``submit`` event to cancel and stop propagating the event when the form is invalid. If there is `novalidate `_ attribute, the validation process is skipped. During that event, it will perform the validation described by the following pseudo-code: .. code-block:: javascript function validateForm(form, submitEvent) { var fields = $(form).find(":-foundation-submittable").toArray(); var invalids = []; var unhandleds = []; fields.forEach(function(field) { if (!validateField(field)) { invalids.push(field); } }); if (invalids.length === 0) { // The form is valid return; } invalids.forEach(function(field) { var e = createEvent("foundation-validation-invalid"); field.trigger(e); if (!e.isDefaultPrevented()) { unhandleds.push(field); } }); if (unhandleds.length === 0) { return; } unhandleds.forEach(function(field) { showErrorUI(field); }); submitEvent.stopPropagation(); submitEvent.preventDefault(); } Validator ========= ``foundation-validation`` itself is not performing the actual validation. Rather a validator can be registered to the :doc:`registry <../registry/index>` using ``foundation.validation.validator`` as the name and the config satisfying the following interface: .. code-block:: ts interface FoundationValidationValidator { /** * Only the element satisfying the selector will be validated using this validator. It will be passed to jQuery.fn.is. */ selector: string; /** * Only the element satisfying the selector will be validated using this validator. It will be passed to jQuery.fn.is. */ selector: (index: number, element: Element) => boolean; /** * The actual validation function. It must return a string of error message if the element fails. */ validate: (element: Element) => string; /** * The function to show the error. */ show: (element: Element, message: string, ctx: FoundationValidationValidatorContext) => void; /** * The function to clear the error. */ clear: (element: Element, ctx: FoundationValidationValidatorContext) => void; } interface FoundationValidationValidatorContext { /** * Indicates that the validation process should continue to the next validator. * If this method is not called, then the process stops. */ next: () => void; } The validators are evaluated based on LIFO (last in, first out) algorithm. Example ------- We need a validator to check the max length of a textfield (e.g. ````, ``