Validation

Validation functionality can be enabled for all form components using the validation plugin. Once included, from CDN or as a module, you can use the form component and x-validation directive to validate inputs based on a set of rules and display validation messages to users.

Example

<div x-data="form" data-form-name="username">
  <div
    x-data="input"
    data-placeholder="Username"
    x-validation:input='{ "rules": [{ "minLength": 3 }, { "maxLength": 12 }, "required", "alphanumeric" ]}'
    class="flex flex-1 items-center rounded-sm border px-3 py-2 outline-hidden transition-shadow duration-200 focus-within:ring-3 focus:outline-hidden"
    class-default="border-gray-300 bg-white focus-within:border-gray-400 focus-within:ring-primary-200 dark:border-dark-600 dark:bg-dark-800 dark:text-text-300 dark:focus-within:ring-primary-300"
    class-valid="border-success-300 bg-white text-success-600 focus-within:ring-success-200 dark:border-success-400 dark:bg-dark-800 dark:text-success-600 dark:focus-within:ring-success-300"
    class-invalid="border-danger-300 bg-white text-danger-600 focus-within:ring-danger-200 dark:border-danger-400 dark:bg-dark-800 dark:text-danger-600 dark:focus-within:ring-danger-300"
  >
    <div data-icon class="mr-3 empty:hidden"></div>
    <div data-prepend class="mr-3 empty:hidden"></div>
    <div class="mr-3 flex flex-1 flex-wrap">
      <input
        x-bind="input"
        type="text"
        class="w-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-hidden focus:min-w-[64px] focus:outline-hidden"
      />
    </div>
    <div data-append class="mr-3 empty:hidden"></div>
    <div class="flex items-center gap-x-2">
      <div x-bind="loader">
        <svg
          viewBox="25 25 50 50"
          fill="none"
          class="h-5 w-5 animate-spinner-rotate"
        >
          <circle
            cx="50"
            cy="50"
            r="20"
            stroke="currentColor"
            stroke-width="4"
            stroke-miterlimit="10"
            stroke-linecap="round"
            class="animate-spinner-dash"
          />
        </svg>
      </div>
      <button x-bind="clearButton" @click="clear()" class="flex items-center">
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="16"
          height="16"
          fill="currentColor"
          class="h-5 w-5 opacity-70"
          viewBox="0 0 16 16"
        >
          <path
            d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z"
          />
        </svg>
      </button>
    </div>
  </div>
  <div x-data="formText" data-input="input" class="flex flex-col">
    <template x-for="m in getMessages()">
      <div
        x-bind="message"
        x-text="m"
        class="text-sm"
        class-valid="text-success-600 dark:text-success-500"
        class-invalid="text-danger-600 dark:text-danger-500"
      ></div>
    </template>
  </div>
</div>

Usage

<script defer src="https://cdn.jsdelivr.net/npm/litewind-alpine@0.x.x/plugins/validation/dist/cdn.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/litewind-alpine@0.x.x/components/form-text/dist/cdn.min.js"></script>

The main part of validation is the form component that is used to store validation data. The validation rules and other options are set seperately for each input in the form with the x-validation directive. Third part of the validation plugin is the $validation utility magic function.

The form-text is a separate, optional component that can be used to display validation messages.

Form component

Form component is a container for validated inputs that stores validation results and other validation related data. Form component has one required data-form-name prop. It also provides validateForm function that validates all inputs inside form and resetForm function that resets validation results to default state. If all inputs inside form are valid then valid property of the form component is set to true.

x-validation directive

The x-validation directive is used to set the rules and the mode of the validation for the input in the form. The value of the directive is in JSON format and has following properties:

  • rules - is an array of objects and strings. Simple rules use strings and rules that require argument use objects.
  • mode - is a string that defines when to validate input and how to update state depending on the validation results. If mode is not defined the default "blur-silent" is used.
  • messages - is an object containing validation messages. If messages are not defined the default global messages are used.

Rules

Available rules include following:

  • required
  • alpha
  • numeric
  • alphanumeric
  • minLength
  • maxLength
  • minElements
  • maxElements
  • minValue
  • maxValue
  • email
  • atLeastOneUppercase
  • atLeastOneLowercase
  • atLeastOneDigit
  • atLeastOneSpecial
  • sameAs

Mode

The mode defines when to validate input and how to update the state based on the validation results. Available modes are:

  • "blur-silent" - validates when the input loses focus; updates state only for invalid inputs.
  • "blur-eager" - validates when the input loses focus; updates state for both valid and invalid inputs.
  • "form-silent" - validates when the formValidate function is called; updates state only for invalid inputs.
  • "form-eager" - validates when the formValidate function is called; update state for both valid and invalid inputs.
  • "immediate-eager" - validate on each input update; updates state for both valid and invalid inputs.
Example
Mode: "blur-silent"

Mode: "blur-eager"

Mode: "immediate-eager"

Mode: "form-silent"

Mode: "form-eager"

<div
  x-data="form"
  data-form-name="validation-mode"
  class="flex flex-col gap-y-4"
>
  <div>
    <span class="font-mono font-semibold"> Mode: "blur-silent" </span>
    <div
      x-data="input"
      data-placeholder="Username"
      x-validation:input-blur-silent='{ "rules": [{ "minLength": 3 }, { "maxLength": 12 }, "required", "alphanumeric" ], "mode": "blur-silent"}'
      class="mt-2 flex flex-1 items-center rounded-sm border px-3 py-2 outline-hidden transition-shadow duration-200 focus-within:ring-3 focus:outline-hidden"
      class-default="border-gray-300 bg-white focus-within:border-gray-400 focus-within:ring-primary-200 dark:border-dark-600 dark:bg-dark-800 dark:text-text-300 dark:focus-within:ring-primary-300"
      class-valid="border-success-300 bg-white text-success-600 focus-within:ring-success-200 dark:border-success-400 dark:bg-dark-800 dark:text-success-600 dark:focus-within:ring-success-300"
      class-invalid="border-danger-300 bg-white text-danger-600 focus-within:ring-danger-200 dark:border-danger-400 dark:bg-dark-800 dark:text-danger-600 dark:focus-within:ring-danger-300"
    >
      <div data-icon class="mr-3 empty:hidden"></div>
      <div data-prepend class="mr-3 empty:hidden"></div>
      <div class="mr-3 flex flex-1 flex-wrap">
        <input
          x-bind="input"
          type="text"
          class="w-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-hidden focus:min-w-[64px] focus:outline-hidden"
        />
      </div>
      <div data-append class="mr-3 empty:hidden"></div>
      <div class="flex items-center gap-x-2">
        <div x-bind="loader">
          <svg
            viewBox="25 25 50 50"
            fill="none"
            class="h-5 w-5 animate-spinner-rotate"
          >
            <circle
              cx="50"
              cy="50"
              r="20"
              stroke="currentColor"
              stroke-width="4"
              stroke-miterlimit="10"
              stroke-linecap="round"
              class="animate-spinner-dash"
            />
          </svg>
        </div>
        <button x-bind="clearButton" @click="clear()" class="flex items-center">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width="16"
            height="16"
            fill="currentColor"
            class="h-5 w-5 opacity-70"
            viewBox="0 0 16 16"
          >
            <path
              d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z"
            />
          </svg>
        </button>
      </div>
    </div>
    <div x-data="formText" data-input="input-blur-silent" class="flex flex-col">
      <template x-for="m in getMessages()">
        <div
          x-bind="message"
          x-text="m"
          class="text-sm"
          class-valid="text-success-600 dark:text-success-500"
          class-invalid="text-danger-600 dark:text-danger-500"
        ></div>
      </template>
    </div>
  </div>
  <hr class="my-6" />
  <div>
    <span class="font-mono font-semibold"> Mode: "blur-eager" </span>
    <div
      x-data="input"
      data-placeholder="Username"
      x-validation:input-blur-eager='{ "rules": [{ "minLength": 3 }, { "maxLength": 12 }, "required", "alphanumeric" ], "mode": "blur-eager"}'
      class="mt-2 flex flex-1 items-center rounded-sm border px-3 py-2 outline-hidden transition-shadow duration-200 focus-within:ring-3 focus:outline-hidden"
      class-default="border-gray-300 bg-white focus-within:border-gray-400 focus-within:ring-primary-200 dark:border-dark-600 dark:bg-dark-800 dark:text-text-300 dark:focus-within:ring-primary-300"
      class-valid="border-success-300 bg-white text-success-600 focus-within:ring-success-200 dark:border-success-400 dark:bg-dark-800 dark:text-success-600 dark:focus-within:ring-success-300"
      class-invalid="border-danger-300 bg-white text-danger-600 focus-within:ring-danger-200 dark:border-danger-400 dark:bg-dark-800 dark:text-danger-600 dark:focus-within:ring-danger-300"
    >
      <div data-icon class="mr-3 empty:hidden"></div>
      <div data-prepend class="mr-3 empty:hidden"></div>
      <div class="mr-3 flex flex-1 flex-wrap">
        <input
          x-bind="input"
          type="text"
          class="w-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-hidden focus:min-w-[64px] focus:outline-hidden"
        />
      </div>
      <div data-append class="mr-3 empty:hidden"></div>
      <div class="flex items-center gap-x-2">
        <div x-bind="loader">
          <svg
            viewBox="25 25 50 50"
            fill="none"
            class="h-5 w-5 animate-spinner-rotate"
          >
            <circle
              cx="50"
              cy="50"
              r="20"
              stroke="currentColor"
              stroke-width="4"
              stroke-miterlimit="10"
              stroke-linecap="round"
              class="animate-spinner-dash"
            />
          </svg>
        </div>
        <button x-bind="clearButton" @click="clear()" class="flex items-center">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width="16"
            height="16"
            fill="currentColor"
            class="h-5 w-5 opacity-70"
            viewBox="0 0 16 16"
          >
            <path
              d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z"
            />
          </svg>
        </button>
      </div>
    </div>
    <div x-data="formText" data-input="input-blur-eager" class="flex flex-col">
      <template x-for="m in getMessages()">
        <div
          x-bind="message"
          x-text="m"
          class="text-sm"
          class-valid="text-success-600 dark:text-success-500"
          class-invalid="text-danger-600 dark:text-danger-500"
        ></div>
      </template>
    </div>
  </div>
  <hr class="my-6" />
  <div>
    <span class="font-mono font-semibold"> Mode: "immediate-eager" </span>
    <div
      x-data="input"
      data-placeholder="Username"
      x-validation:input-immediate-eager='{ "rules": [{ "minLength": 3 }, { "maxLength": 12 }, "required", "alphanumeric" ], "mode": "immediate-eager"}'
      class="mt-2 flex flex-1 items-center rounded-sm border px-3 py-2 outline-hidden transition-shadow duration-200 focus-within:ring-3 focus:outline-hidden"
      class-default="border-gray-300 bg-white focus-within:border-gray-400 focus-within:ring-primary-200 dark:border-dark-600 dark:bg-dark-800 dark:text-text-300 dark:focus-within:ring-primary-300"
      class-valid="border-success-300 bg-white text-success-600 focus-within:ring-success-200 dark:border-success-400 dark:bg-dark-800 dark:text-success-600 dark:focus-within:ring-success-300"
      class-invalid="border-danger-300 bg-white text-danger-600 focus-within:ring-danger-200 dark:border-danger-400 dark:bg-dark-800 dark:text-danger-600 dark:focus-within:ring-danger-300"
    >
      <div data-icon class="mr-3 empty:hidden"></div>
      <div data-prepend class="mr-3 empty:hidden"></div>
      <div class="mr-3 flex flex-1 flex-wrap">
        <input
          x-bind="input"
          type="text"
          class="w-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-hidden focus:min-w-[64px] focus:outline-hidden"
        />
      </div>
      <div data-append class="mr-3 empty:hidden"></div>
      <div class="flex items-center gap-x-2">
        <div x-bind="loader">
          <svg
            viewBox="25 25 50 50"
            fill="none"
            class="h-5 w-5 animate-spinner-rotate"
          >
            <circle
              cx="50"
              cy="50"
              r="20"
              stroke="currentColor"
              stroke-width="4"
              stroke-miterlimit="10"
              stroke-linecap="round"
              class="animate-spinner-dash"
            />
          </svg>
        </div>
        <button x-bind="clearButton" @click="clear()" class="flex items-center">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width="16"
            height="16"
            fill="currentColor"
            class="h-5 w-5 opacity-70"
            viewBox="0 0 16 16"
          >
            <path
              d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z"
            />
          </svg>
        </button>
      </div>
    </div>
    <div
      x-data="formText"
      data-input="input-immediate-eager"
      class="flex flex-col"
    >
      <template x-for="m in getMessages()">
        <div
          x-bind="message"
          x-text="m"
          class="text-sm"
          class-valid="text-success-600 dark:text-success-500"
          class-invalid="text-danger-600 dark:text-danger-500"
        ></div>
      </template>
    </div>
  </div>
  <hr class="my-6" />
  <div>
    <span class="font-mono font-semibold"> Mode: "form-silent" </span>
    <div
      x-data="input"
      data-placeholder="Username"
      x-validation:input-form-silent='{ "rules": [{ "minLength": 3 }, { "maxLength": 12 }, "required", "alphanumeric" ], "mode": "form-silent"}'
      class="mt-2 flex flex-1 items-center rounded-sm border px-3 py-2 outline-hidden transition-shadow duration-200 focus-within:ring-3 focus:outline-hidden"
      class-default="border-gray-300 bg-white focus-within:border-gray-400 focus-within:ring-primary-200 dark:border-dark-600 dark:bg-dark-800 dark:text-text-300 dark:focus-within:ring-primary-300"
      class-valid="border-success-300 bg-white text-success-600 focus-within:ring-success-200 dark:border-success-400 dark:bg-dark-800 dark:text-success-600 dark:focus-within:ring-success-300"
      class-invalid="border-danger-300 bg-white text-danger-600 focus-within:ring-danger-200 dark:border-danger-400 dark:bg-dark-800 dark:text-danger-600 dark:focus-within:ring-danger-300"
    >
      <div data-icon class="mr-3 empty:hidden"></div>
      <div data-prepend class="mr-3 empty:hidden"></div>
      <div class="mr-3 flex flex-1 flex-wrap">
        <input
          x-bind="input"
          type="text"
          class="w-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-hidden focus:min-w-[64px] focus:outline-hidden"
        />
      </div>
      <div data-append class="mr-3 empty:hidden"></div>
      <div class="flex items-center gap-x-2">
        <div x-bind="loader">
          <svg
            viewBox="25 25 50 50"
            fill="none"
            class="h-5 w-5 animate-spinner-rotate"
          >
            <circle
              cx="50"
              cy="50"
              r="20"
              stroke="currentColor"
              stroke-width="4"
              stroke-miterlimit="10"
              stroke-linecap="round"
              class="animate-spinner-dash"
            />
          </svg>
        </div>
        <button x-bind="clearButton" @click="clear()" class="flex items-center">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width="16"
            height="16"
            fill="currentColor"
            class="h-5 w-5 opacity-70"
            viewBox="0 0 16 16"
          >
            <path
              d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z"
            />
          </svg>
        </button>
      </div>
    </div>
    <div x-data="formText" data-input="input-form-silent" class="flex flex-col">
      <template x-for="m in getMessages()">
        <div
          x-bind="message"
          x-text="m"
          class="text-sm"
          class-valid="text-success-600 dark:text-success-500"
          class-invalid="text-danger-600 dark:text-danger-500"
        ></div>
      </template>
    </div>
    <button
      @click="$validation('input-form-silent').formValidate()"
      class="mt-4 ml-auto block flex items-center rounded-md border-violet-700 bg-violet-500 px-4 py-2 font-medium text-gray-100 hover:bg-violet-600 focus:ring-violet-200 dark:bg-violet-500 dark:hover:bg-violet-600"
    >
      Validate
    </button>
  </div>
  <hr class="my-6" />
  <div>
    <span class="font-mono font-semibold"> Mode: "form-eager" </span>
    <div
      x-data="input"
      data-placeholder="Username"
      x-validation:input-form-eager='{ "rules": [{ "minLength": 3 }, { "maxLength": 12 }, "required", "alphanumeric" ], "mode": "form-eager"}'
      class="mt-2 flex flex-1 items-center rounded-sm border px-3 py-2 outline-hidden transition-shadow duration-200 focus-within:ring-3 focus:outline-hidden"
      class-default="border-gray-300 bg-white focus-within:border-gray-400 focus-within:ring-primary-200 dark:border-dark-600 dark:bg-dark-800 dark:text-text-300 dark:focus-within:ring-primary-300"
      class-valid="border-success-300 bg-white text-success-600 focus-within:ring-success-200 dark:border-success-400 dark:bg-dark-800 dark:text-success-600 dark:focus-within:ring-success-300"
      class-invalid="border-danger-300 bg-white text-danger-600 focus-within:ring-danger-200 dark:border-danger-400 dark:bg-dark-800 dark:text-danger-600 dark:focus-within:ring-danger-300"
    >
      <div data-icon class="mr-3 empty:hidden"></div>
      <div data-prepend class="mr-3 empty:hidden"></div>
      <div class="mr-3 flex flex-1 flex-wrap">
        <input
          x-bind="input"
          type="text"
          class="w-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-hidden focus:min-w-[64px] focus:outline-hidden"
        />
      </div>
      <div data-append class="mr-3 empty:hidden"></div>
      <div class="flex items-center gap-x-2">
        <div x-bind="loader">
          <svg
            viewBox="25 25 50 50"
            fill="none"
            class="h-5 w-5 animate-spinner-rotate"
          >
            <circle
              cx="50"
              cy="50"
              r="20"
              stroke="currentColor"
              stroke-width="4"
              stroke-miterlimit="10"
              stroke-linecap="round"
              class="animate-spinner-dash"
            />
          </svg>
        </div>
        <button x-bind="clearButton" @click="clear()" class="flex items-center">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width="16"
            height="16"
            fill="currentColor"
            class="h-5 w-5 opacity-70"
            viewBox="0 0 16 16"
          >
            <path
              d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z"
            />
          </svg>
        </button>
      </div>
    </div>
    <div x-data="formText" data-input="input-form-eager" class="flex flex-col">
      <template x-for="m in getMessages()">
        <div
          x-bind="message"
          x-text="m"
          class="text-sm"
          class-valid="text-success-600 dark:text-success-500"
          class-invalid="text-danger-600 dark:text-danger-500"
        ></div>
      </template>
    </div>
    <button
      @click="$validation('input-form-eager').formValidate()"
      class="mt-4 ml-auto block flex items-center rounded-md border-violet-700 bg-violet-500 px-4 py-2 font-medium text-gray-100 hover:bg-violet-600 focus:ring-violet-200 dark:bg-violet-500 dark:hover:bg-violet-600"
    >
      Validate
    </button>
  </div>
</div>

Messages

Each rule has default generic validation message for the invalid value. You can customize these messages for the input by adding them to the messages property. The key is a rule name and the value is the new message. The message can contain special %d characters that are replaced with a rule value.

Validation results

Validation results for each input are stored in the form component. This data is automatically used by inputs and other components to set validation related styles and validation messages. Validation results can also be accessed with the $validation magic function that takes input name as and argument and returns validation results object.

The validation result is an object with following propreties:

  • status - object containg the results of validation and the current state of the input (for example touched, dirty etc). It is updated once initially and then after each value change.
  • state - final validation state of input. This state is based on the current status and is updated only when conditions for the mode are fulfilled (for example input lost focus etc). By default it is empty string for initial state of input, "valid" for valid input and "invalid" for invalid input.
  • messages - object containing validation messages.

See how these properties are updated depending on the input value in the next example.

Example

    

    

  

<div x-data="form" data-form-name="username" class="flex items-start gap-x-10">
  <div
    x-data="input"
    data-placeholder="Username"
    x-validation:input='{ "rules": [{ "minLength": 3 }, { "maxLength": 12 }, "required", "alphanumeric" ]}'
    class="flex flex-1 items-center rounded-sm border px-3 py-2 outline-hidden transition-shadow duration-200 focus-within:ring-3 focus:outline-hidden"
    class-default="border-gray-300 bg-white focus-within:border-gray-400 focus-within:ring-primary-200 dark:border-dark-600 dark:bg-dark-800 dark:text-text-300 dark:focus-within:ring-primary-300"
    class-valid="border-success-300 bg-white text-success-600 focus-within:ring-success-200 dark:border-success-400 dark:bg-dark-800 dark:text-success-600 dark:focus-within:ring-success-300"
    class-invalid="border-danger-300 bg-white text-danger-600 focus-within:ring-danger-200 dark:border-danger-400 dark:bg-dark-800 dark:text-danger-600 dark:focus-within:ring-danger-300"
  >
    <div data-icon class="mr-3 empty:hidden"></div>
    <div data-prepend class="mr-3 empty:hidden"></div>
    <div class="mr-3 flex flex-1 flex-wrap">
      <input
        x-bind="input"
        type="text"
        class="w-full min-w-0 flex-1 border-0 bg-transparent p-0 outline-hidden focus:min-w-[64px] focus:outline-hidden"
      />
    </div>
    <div data-append class="mr-3 empty:hidden"></div>
    <div class="flex items-center gap-x-2">
      <div x-bind="loader">
        <svg
          viewBox="25 25 50 50"
          fill="none"
          class="h-5 w-5 animate-spinner-rotate"
        >
          <circle
            cx="50"
            cy="50"
            r="20"
            stroke="currentColor"
            stroke-width="4"
            stroke-miterlimit="10"
            stroke-linecap="round"
            class="animate-spinner-dash"
          />
        </svg>
      </div>
      <button x-bind="clearButton" @click="clear()" class="flex items-center">
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="16"
          height="16"
          fill="currentColor"
          class="h-5 w-5 opacity-70"
          viewBox="0 0 16 16"
        >
          <path
            d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z"
          />
        </svg>
      </button>
    </div>
  </div>
  <div class="flex w-1/2 flex-col gap-y-4 text-sm">
    <pre
      x-text="'status: ' + JSON.stringify($validation('input').status, null, 2)"
    ></pre>
    <pre
      x-text="'messages: ' + JSON.stringify($validation('input').messages, null, 2)"
    ></pre>
    <pre x-text="'state: ' + $validation('input').state"></pre>
  </div>
</div>

Adding rules

For the CDN build of the plugin you can add new rules to the window.Litewind.globalValidators object. A rule is simply a function that takes tested value as an argument and returns true or a message.

For a module build of the plugin import globalValidators object from the plugin file.

Customizing messages

For the CDN build of the plugin you can modify default messages for the rules in the window.Litewind.validationMessages object.

For a module build of the plugin import validationMessages object from the plugin file.

A message can contain %d charecters that are replaced with a rule value.

Litewind-alpine 0.1.0