Answer the question
In order to leave comments, you need to log in
How to correctly check the input value for validity and correctly build its architecture?
There is an input (in this case it is in the component), it has props - "invalid" if it is true, then the input is highlighted with a red frame. The question is what is correct and should be substituted into this prop? I do as below, but it seems to me very wrong, because for the sake of one input, a lot of code is obtained, and I can have up to 30 of these inputs.
This is how I do it, how wrong and how can I optimize?:
This is the component itself with an input:
<InputText
@input="handleNameGroup($event)"
:value="this.formGroupData.comment"
:invalid="invalidFormName && invalidName"
>
</InputText>
export default {
data(){
return{
formGroupData:{
comment: '',
group_id : '',
id: ''
},
invalidSelect: false
}
},
computed:{
invalidFormName(){
return !this.formGroupData.comment.length
},
handleSaveGroup(){
if(!this.formGroupData.comment || !this.formGroupData.group_id){
this.invalidName = !this.formGroupData.comment ? true : false
return false
}
Answer the question
In order to leave comments, you need to log in
Standard problem with custom inputs and form validation.
One solution is to create a single error array in the form with pointers pointing to a specific input. This is especially good when the backend at the form validation stage also returns errors with specific pointers.
An example of a custom input with error text displayed below it. If there is at least one error, then an "erroneous" class with its own styles is hung.
<template>
<div class="input">
<input
type="text"
class="input__field"
:class="{ 'input__field_error': errors.length > 0 }"
:placeholder="placeholder"
:value="value"
:disabled="disabled"
@input="handleInput"
>
<div class="input__errors">
<p
v-for="(error, index) in errors"
:key="index"
class="input__error"
>
{{ error }}
</p>
</div>
</div>
</template>
<script>
export default {
name: 'custom-input',
props: {
disabled: {
type: Boolean,
default: false,
},
errors: {
type: Array,
default: () => ([]),
},
value: {
type: String,
default: '',
},
placeholder: {
type: String,
default: '',
},
},
methods: {
handleInput({ target: { value } }) {
this.$emit('onInput', value);
},
},
};
</script>
<template>
<form @onSubmit.prevent="handleSubmit">
<custom-input
:value="phone"
:disabled="loading"
:errors="phoneErrors" // передаем только относящиеся к конкретному инпуту ошибки
@onInput="handleInput"
/>
<button type="submit">Отправить</button>
</form>
</template>
<script>
export default {
data: () => ({
phone: '',
errors: [],
loading: false,
}),
computed: {
phoneErrors() {
// этот код лучше вынести в хелпер, чтобы потом переиспользовать с другими поинтерами
if (this.errors.length === 0) return [];
return this.errors
.filter(error => error.pointer === 'phone') // проверка на нужный поинтер
.map(item => item.detail); // делаем массив только из текста ошибок
},
},
methods: {
handleInput(newPhone) {
// при вводе нового значения обнуляем все ошибки.
// Можно сделать обнуление ошибок по конкретному поинтеру
this.errors = [];
this.phone = newPhone;
},
handleSubmit() {
this.errors = [];
// Если инпут пустой, то сами генерируем ошибку
// и не делаем отправку данных на сервер
if (this.phone.length === 0) {
this.errors = [...this.errors, {
detail: 'Телефон не может быть пустым',
pointer: 'phone',
}];
return;
}
// Если же все ок, то отправляем данные на сервер
this.loading = true;
this.sendPhone();
},
},
};
</script>
var item = document.getElementsByTagName('li'); //Выбираем все li-шки в документе
for (var i = 0; i < item.length; i++){ //Запускаем цикл для перебора всех li
item[i].style.position = 'relative'; //Каждому li устанавливаем css-свойство "position: relative"
var span = document.createElement('span'); // Создаем span
span.style.cssText = 'position:absolute;left:0;top:0'; //Присваиваем созданному спану стили
item[i].appendChild(span); //Помещаем span в li
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question