Skip to content

Form Validation Architecture

Overview

Cavai's form system har en todelt valideringsarkitektur som separerer per-input validering fra submit-validering.

User types → FormPhoneInput prosesserer input → formStore.updateField User submits → formStore.validateAllFields → sjekker minLength → viser feil

Arkitektur

1. Per-Input Validering (useInputValidation)

Lokasjon: /src/composables/useInputValidation.ts

Ansvar:

  • Konfigurasjon av input-felter (validation, isRequired, minLength, maxLength, placeholder, pattern)
  • Brukes av alle form input-komponenter for konsistent oppførsel
  • Håndterer ikke faktisk validering - kun konfigurasjon

Brukes av:

  • FormTextInput.vue
  • FormEmailInput.vue
  • FormPhoneInput.vue
  • FormNumberInput.vue
  • FormDateInput.vue
  • FormTextAreaInput.vue
  • FormDropdownInput.vue
typescript
// Eksempel bruk i komponent
setup(props) {
  const {
    validation,
    isRequired,
    minLength,
    maxLength,
    placeholder,
    pattern
  } = useInputValidation(props.input)

  return { validation, isRequired, minLength, maxLength, placeholder, pattern }
}

2. Submit-Validering (formStore)

Lokasjon: /src/stores/formStore.ts

Ansvar:

  • Global form-state management
  • Submit-time validering av alle felter
  • Håndtering av validation errors som vises til bruker
  • Form submission logikk

Nøkkelmetoder:

  • addValidationError(index, error) - Legger til feilmelding for spesifikt felt
  • clearValidationErrors(index) - Fjerner feilmeldinger for spesifikt felt
  • validateAllFields() - Validerer alle felter ved submit
  • isFormValid - Computed property som sjekker om form er gyldig

3. Hvordan de samarbeider

mermaid
graph TD
    A[User types in input] --> B[Component uses useInputValidation for config]
    B --> C[Component handles own input processing]
    C --> D[formStore.updateField updates global state]

    E[User clicks submit] --> F[formStore.validateAllFields runs]
    F --> G[Checks all required fields]
    G --> H{All valid?}
    H -->|Yes| I[Submit form]
    H -->|No| J[Show validation errors via addValidationError]

    J --> K[CreativeFormBlock displays errors]

Praktisk Eksempel

Input-komponent (FormEmailInput.vue)

vue
<script>
setup(props) {
  // Per-input konfigurasjon
  const { validation, isRequired, pattern } = useInputValidation(props.input)

  return { validation, isRequired, pattern }
}

methods: {
  handleInput(value) {
    // Komponent-spesifikk logikk (f.eks. maxLength)
    let processedValue = value
    if (this.maxLength && processedValue.length > this.maxLength) {
      processedValue = processedValue.substring(0, this.maxLength)
    }

    this.$emit('input', processedValue)
  }
}
</script>

CreativeFormBlock.vue

vue
<script>
methods: {
  // Brukes når individuelle komponenter trenger å rapportere feil
  handleValidationError({ index, error }) {
    this.formStore.addValidationError(index, error)
  },

  handleValidationCleared({ index }) {
    this.formStore.clearValidationErrors(index)
  },

  // Submit-validering
  async handleSubmit() {
    const isValid = this.formStore.validateAllFields()
    if (isValid) {
      await this.formStore.submitForm()
    }
    // Feil vises automatisk via formStore.validationErrors
  }
}
</script>

Fordeler med denne arkitekturen

  1. Separation of Concerns:

    • Input-komponenter fokuserer på UX og input-prosessering
    • formStore fokuserer på global validering og submission
  2. Fleksibilitet:

    • Hver input-type kan ha spesialisert logikk (phone = kun tall, email = pattern)
    • Submit-validering er konsistent på tvers av alle inputs
  3. Gjenbruk:

    • useInputValidation gir konsistent konfigurasjon
    • formStore håndterer all global form-logikk
  4. Brukeropplevelse:

    • Real-time feedback via per-input validering
    • Comprehensive validation ved submit

Validering Flow

  1. Real-time (per-input):

    • Bruker skriver → komponent prosesserer → updateField i formStore
    • Ingen validation errors vist (med mindre spesifikt implementert)
  2. Submit-time (global):

    • Bruker klikker submit → validateAllFields() → addValidationError for ugyldige felter
    • Feilmeldinger vises i UI via formStore.validationErrors

Konklusjon

Ja, du har forstått det riktig:

  • Per-input validering = useInputValidation composable (konfigurasjon)
  • Submit validering = formStore metoder (addValidationError, clearValidationErrors, validateAllFields)

Denne todelte tilnærmingen gir optimal brukeropplevelse med både real-time feedback og comprehensive submit-validering.

Internal documentation