Как правильно настроить проверку в Vuelidate, чтобы одно из двух полей было обязательным?

Как можно настроить правила валидации, чтобы проверка проходила успешно, если хотя бы одно из двух полей заполнено?
  • 29 апреля 2024 г. 7:40
Ответы на вопрос 2
Для настройки проверки в Vuelidate, чтобы одно из двух полей было обязательным, можно воспользоваться следующим примером:

```javascript
import { required } from 'vuelidate/lib/validators'

validations: {
  field1: {
    requiredField: requiredIfNotFilled('field2')
  },
  field2: {
    requiredField: requiredIfNotFilled('field1')
  }
},
```

Где функция `requiredIfNotFilled` имеет следующий вид:

```javascript
import { withParams } from 'vuelidate/lib/validators'

function requiredIfNotFilled(otherField) {
  return withParams({ type: 'requiredIfNotFilled'}, function (value, parentVm) {
    return !!parentVm[otherField] || !!value
  })
}
```

Таким образом, при использовании данных функций валидации, одно из полей будет обязательным, если другое не заполнено.

Чтобы настроить правила валидации, чтобы проверка проходила успешно, если хотя бы одно из двух полей заполнено, можно воспользоваться следующим примером:

```javascript
import { required } from 'vuelidate/lib/validators'

validations: {
  field1: {
    requiredIfNotBothFilled('field2')
  },
  field2: {
    requiredIfNotBothFilled('field1')
  }
},
```

Где функция `requiredIfNotBothFilled` имеет следующий вид:

```javascript
import { withParams } from 'vuelidate/lib/validators'

function requiredIfNotBothFilled(otherField) {
  return withParams({ type: 'requiredIfNotBothFilled'}, function (value, parentVm) {
    return !!parentVm[otherField] && !!value || !!parentVm[otherField] || !!value
  })
}
```

Таким образом, при использовании данных функций валидации, проверка будет проходить успешно, если хотя бы одно из двух полей заполнено.
Чтобы реализовать валидацию, где одно из двух полей должно быть обязательно заполнено (или оба), вы можете использовать пользовательский валидатор в Vue и Vuelidate. Назовем это условие "orRequired", где по меньшей мере одно из двух полей должно содержать ненулевое значение. 

Во-первых, добавим новый валидатор в ваш файл vuelidate_translate.js. Этот валидатор будет принимать два аргумента, которые представляют собой ссылки на два поля формы:
import { helpers } from '@vuelidate/validators';

export const orRequired = (siblingField) => {
  return helpers.withMessage(
    'По крайней мере одно из полей должно быть заполнено',
    function(value, parentVm) {
      return value || parentVm[siblingField];
    }
  );
}

Теперь внесем изменения в ваш файл с компонентом Vue, чтобы использовать этот новый валидатор. Для этого нам понадобится добавить новое правило для каждого поля, указывая другое поле как "siblingField". Например:
<script setup>
import {useForm} from '@inertiajs/vue3';
import {ref} from "vue";
import {required$, maxLength$, minLength$, orRequired} from './vuelidate_translate'

const form = useForm({
  field_1: '',
  field_2: '',
});

const rules = ref({
  field_1: { required$, orRequired$: orRequired('field_2') },
  field_2: { required$, orRequired$: orRequired('field_1') },
});

const v$ = ref(useVuelidate(rules, form));

function validateTest() {
  console.log(v$.value.$validate());
}
</script>

<template>
<div>
  <InputText input_type="text" v-model="form.field_1"/>
  <InputText input_type="text" v-model="form.field_2"/>
</div>
</template>

Здесь мы добавили новое правило orRequired$ для каждого поля, которое ссылается на другое поле формы. Этот валидатор проверяет, заполнено ли хотя бы одно из указанных полей.

В функции валидатора orRequired мы используем parentVm , который ссылается на объект формы, содержащий оба поля.
Это позволяет нам проверять значение второго поля в контексте первого.
При использовании локализации (например, trans из laravel-vue-i18n) может потребоваться адаптировать сообщения об ошибках под текущий язык пользователя, а также учесть контекст использования.
В вашем коде мы также учли возможность добавления других валидаций, таких как maxLength$ или minLength$, если это потребуется.
Теперь при вызове validateTest() будут проверены условия заполнения хотя бы одного из полей, а также прочие установленные правила валидации.
Похожие вопросы