# Template Refs

Sometimes, the basic automagic validation system may not be the right one for you. Maybe you want to write the submission prevention yourself. Or maybe you want to display the error messages manually, asking Loveform to avoid rendering them for you. In those cases, you can use template refs (opens new window) to access the components and their exposed attributes.

# Using template refs

Template refs are really simple to use with Loveform. But a snippet is more effective at showing code simplicity than any combination of words.

<script setup lang="ts">
import { ref } from 'vue';
import axios from 'axios';
import { LForm, LInput } from 'loveform';

const formRef = ref<LForm | null>(null);
const data = ref('');

const dataValidations = [
  (text: string) => !!text.trim() || 'This field is required',
];

const submit = async () => {
  if (formRef.value?.valid) {
    await axios.post('https://backend.you/send-content', { content: data.value });
  }
};
</script>

<template>
  <LForm
    ref="formRef"
    @submit="() => null"
  >
    <LInput
      v-model="data"
      :validations="dataValidations"
    />
  </LForm>
  <button @click="submit">Submit!</button>
</template>

Notice how we disabled the default submit action of the LForm component and instead used a button that called a custom submit method. This method checks whether or not the contents of the LForm component are valid by calling the valid attribute of the LForm's template ref.

# Custom error rendering

To handle the error rendering yourself, you also need to use template refs. All you need to do is to pass the hide-errors prop to the component you desire 😈 to handle (or to the whole form) and then use that component's template ref to access to the error attribute. Here's an example:

<script setup lang="ts">
import { ref } from 'vue';
import axios from 'axios';
import { LForm, LInput } from 'loveform';

const inputRef = ref<LInput | null>(null);
const data = ref('');

const dataValidations = [
  (text: string) => !!text.trim() || 'This field is required',
];

const submit = async () => {
  await axios.post('https://backend.you/send-content', { content: data.value });
};
</script>

<template>
  <LForm @submit="submit">
    <LInput
      ref="inputRef"
      v-model="data"
      :validations="dataValidations"
      hide-errors
    />
    <button type="submit">Submit!</button>
  </LForm>
  <span>{{ inputRef?.error }}</span>
</template>

Notice that now the error will be displayed after the submit button instead of being directly attached to the LInput component.