Skip to content

useValidation ​

Композабл для валідації форм з обробкою помилок і автопрокручуванням до першого некоректного поля.

Живе демо ​

Базове використання ​

vue
<script setup>
import { ref } from "vue";
import { useValidation, isFilled } from "orio-ui";

const name = ref("");

// Validation happens bottom to top, place your validations accordingly
const { checkValidity, errors, clearError } = useValidation([
  { model: name, id: "name", validator: isFilled, message: "Name is required" },
]);

function handleSubmit() {
  if (checkValidity()) {
    // Form is valid, submit data
  }
}
</script>

<template>
  <orio-input
    id="name"
    v-model="name"
    label="Name"
    :error="errors['name']"
    @input="clearError('name')"
  />

  <orio-button @click="handleSubmit">Submit</orio-button>
</template>

Кілька полів ​

vue
<script setup>
import { ref } from "vue";
import { useValidation, isFilled } from "orio-ui";

const name = ref("");
const email = ref("");
const message = ref("");

const { checkValidity, errors, clearError, clearAllErrors } = useValidation([
  { model: name, id: "name", validator: isFilled, message: "Name is required" },
  {
    model: email,
    id: "email",
    validator: isFilled,
    message: "Email is required",
  },
  {
    model: message,
    id: "message",
    validator: isFilled,
    message: "Message is required",
  },
]);

function handleSubmit() {
  if (checkValidity()) {
    // All fields valid
  }
}

function handleReset() {
  name.value = "";
  email.value = "";
  message.value = "";
  clearAllErrors();
}
</script>

<template>
  <orio-input
    id="name"
    v-model="name"
    label="Name"
    :error="errors['name']"
    @input="clearError('name')"
  />

  <orio-input
    id="email"
    v-model="email"
    label="Email"
    :error="errors['email']"
    @input="clearError('email')"
  />

  <orio-textarea
    id="message"
    v-model="message"
    label="Message"
    :error="errors['message']"
    @input="clearError('message')"
  />

  <orio-button @click="handleSubmit">Submit</orio-button>
  <orio-button variant="secondary" @click="handleReset">Reset</orio-button>
</template>

Власні валідатори ​

vue
<script setup>
import { ref } from "vue";
import { useValidation, isFilled } from "orio-ui";

const email = ref("");
const age = ref("");
const password = ref("");

// The composable unwraps refs automatically — validators always receive a plain value
function isValidEmail(value) {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(value);
}

function isAdult(value) {
  return parseInt(value) >= 18;
}

function isStrongPassword(value) {
  return value.length >= 8 && /[A-Z]/.test(value) && /[0-9]/.test(value);
}

const { checkValidity, errors, clearError } = useValidation([
  {
    model: email,
    id: "email",
    validator: isFilled,
    message: "Email is required",
  },
  {
    model: email,
    id: "email",
    validator: isValidEmail,
    message: "Invalid email format",
  },
  { model: age, id: "age", validator: isFilled, message: "Age is required" },
  {
    model: age,
    id: "age",
    validator: isAdult,
    message: "You must be 18 or older",
  },
  {
    model: password,
    id: "password",
    validator: isFilled,
    message: "Password is required",
  },
  {
    model: password,
    id: "password",
    validator: isStrongPassword,
    message: "Password must be 8+ chars with uppercase and number",
  },
]);
</script>

<template>
  <orio-input
    id="email"
    v-model="email"
    label="Email"
    type="email"
    :error="errors['email']"
    @input="clearError('email')"
  />

  <orio-input
    id="age"
    v-model="age"
    label="Age"
    type="number"
    :error="errors['age']"
    @input="clearError('age')"
  />

  <orio-input
    id="password"
    v-model="password"
    label="Password"
    type="password"
    :error="errors['password']"
    @input="clearError('password')"
  />
</template>

API ​

useValidation ​

typescript
function useValidation(rules: ValidationRule[]): {
  checkValidity: () => boolean;
  errors: Record<string, string | null>;
  clearError: (id: string) => void;
  clearAllErrors: () => void;
};

ValidationRule ​

typescript
interface ValidationRule {
  model: MaybeRef<any>; // The reactive value to validate
  id: string; // Element ID (used for error mapping and scroll)
  validator: (value: any) => boolean; // Validation function — receives unwrapped value
  message?: string; // Error message (default: "This field is required")
}

isFilled ​

Вбудований валідатор, що перевіряє, чи має рядок або масив вміст:

typescript
function isFilled(value: string | []): boolean;

Параметри ​

ПараметрТипОпис
rulesValidationRule[]Масив правил валідації

Значення, що повертається ​

ВластивістьТипОпис
checkValidity() => booleanПеревіряє всі правила, повертає true, якщо всі пройдено
errorsRecord<string, string | null>Реактивний об'єкт з повідомленнями про помилки за ID
clearError(id: string) => voidОчищає помилку конкретного поля
clearAllErrors() => voidОчищає всі помилки

Можливості ​

  • Автоматично прокручує до першого некоректного поля, якщо валідація не пройшла
  • Реактивний стан помилок
  • Підтримка власних валідаторів
  • Кілька валідаторів на одне поле
  • Вбудований валідатор isFilled
  • Працює з будь-яким компонентом поля