VueJs use attribute value to get array value - vue.js

In a form, I would like to get the name attribute value to find error message, I wrote manually the name on the errors messages array and it works.
But I would like to not have to write the input name each time.
Exemple :
<v-container>
<v-row>
<v-col cols="12">
<v-text-field v-model="label" name="label" :error-messages="errors[NAME_ATTRIBUTE_VALUE]" label="Label" #change="resetFormInputValidation" required></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col cols="9">
<v-text-field v-model="mimeType" name="mime_type" :error-messages="errors['mime_type']" label="MIME Type" required></v-text-field>
</v-col>
<v-col cols="3">
<v-text-field v-model="extension" name="file_extension" :error-messages="errors['file_extension']" label="Extension" required></v-text-field>
</v-col>
</v-row>
</v-container>

There is no way you can access the name attribute in that way. To further elabourate my comment, a way will be to declare an array containing all the values for the name attribute, and then iterating through them using v-for. This gives you access to the dynamic name attribute. A proof-of-concept code:
JS:
data: function() {
return {
names: ['name1', 'name2', 'name3']
};
}
Template:
<v-container v-for="(name, i) in names" :key="i">
<v-row>
<v-col cols="12">
<v-text-field v-model="label" :name="name" :error-messages="errors[name]" label="Label" #change="resetFormInputValidation" required></v-text-field>
</v-col>
</v-row>
<!-- Other markup -->
</v-container>

Related

Vuetify grid across components: can columns in children behave as columns in parent?

For a specific layout for my application, I need to display certain columns inside certains v-rows only if conditions are met.
The conditions being the same each time, and to avoid re-writing v-col after v-col, I decided to write a component which contains the three columns I which to display inside the row. The idea would be to use it like this:
<v-row justify="start">
<v-col cols="12" md="2">
<!-- My first column, that's always here... -->
</v-col>
<MyComponent v-if="myCondition" :data="myData"/>
</v-row>
In turn, MyComponent looks like this:
<template>
<span>
<v-col cols="12" md="4">
<!-- stuff -->
</v-col>
<v-col cols="12" md="2">
<!-- stuff -->
</v-col>
<v-col cols="12" md="4">
<!-- stuff -->
</v-col>
</span>
When rendering this code however, Vuetify considers the whole MyComponent as being part of a single col, and as such displays it all squished. What I expected is it to render all the columns properly, and to have a full row.
Is there anyway to work around this problem?
The problem here is the span tag. The columns need to be a direct child of the row. I would move the three columns out of the component and back into your main component then wrap those 3 columns in a template tag with the v-if
<v-row justify="start">
<v-col cols="12" md="2">
<!-- My first column, that's always here... -->
</v-col>
<template v-if="myCondition">
<v-col cols="12" md="4"></v-col>
<v-col cols="12" md="4"></v-col>
<v-col cols="12" md="4"></v-col>
</template>
</v-row>
or alternatively as you mentioned. you could use a v-row as the root element in your child component
Parent component
<v-row justify="start">
<v-col cols="12" md="2">
<!-- My first column, that's always here... -->
</v-col>
<v-col v-if="myCondition" cols="12" md="10">
<MyComponent :data="myData"/>
</v-col>
</v-row>
Child component
<v-row>
<v-col cols="12" md="4"></v-col>
<v-col cols="12" md="4"></v-col>
<v-col cols="12" md="4"></v-col>
</v-row>

How to display input with the click of a button in Vue?

I've been reading about text-fields but I can't figure it out.. I want to be able to type in a name and age, and then when I press the button "add", I want to be able to see the name and age displayed below. What is the easiest or best way of doing this?
My code:
<v-container>
<v-row>
<v-col cols="12" sm="6" md="3">
<v-text-field label="Name" solo></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field label="Age" solo></v-text-field>
</v-col>
<div class="addbutton">
<v-btn color="green darken-1" large v-on:click="add">Add</v-btn>
</div>
</v-row>
First you should bind inputs to the component data using v-model.
script:
export default {
data(){
return {
name: null,
age: null
}
}
}
html:
<v-col cols="12" sm="6" md="3">
<v-text-field label="Name" solo v-model="name"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field label="Age" solo v-model="age"></v-text-field>
</v-col>
Now you can display current inputs values: <p>{{ name + ', ' + age }}</p>
If you want to show/hide them with a button, you can add a data property to store their state, create a method to toggle it and bind their visibility to the property using v-if:
script:
export default {
data(){
return {
name: null,
age: null,
showValues: false
},
methods: {
toggle() {
this.showValues = !this.showValues
}
}
}
html:
<v-row>
<v-col cols="12" sm="6" md="3">
<v-text-field label="Name" solo v-model="name"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field label="Age" solo v-model="age"></v-text-field>
</v-col>
<div class="addbutton">
<v-btn color="green darken-1" large #click="toogle">Add</v-btn>
</div>
<p v-if="showValues">{{ name + ', ' + age }}</p>
</v-row>
Store the variables in the data of your vue component and the use it to render
<v-row>
<v-col cols="12" sm="6" md="3">
<v-text-field label="Name" solo></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field label="Age" solo></v-text-field>
</v-col>
<div class="addbutton">
<v-btn color="green darken-1" large v-on:click="add">Add</v-btn>
</div>
<v-col cols="12" sm="6" md="3" v-if="render!==null">
<p>{{ render.name }}</p>
<p>{{ render.age }}</p>
</v-row>
<script>
export default {
data(){
return {
name:null,
age:null,
render:null,
},
methods(){
add(){
const name = this.name;
const age = this.age;
this.render = {
name,
age
}
},
}
}
</script>

how can I build such a layout using vuetify grid?

I'm trying to build the form below using vuetify grid.
so far I've only been able to achieve this:
<v-row>
<v-col cols="8">
<v-container>
<v-row no-gutters>
<v-col cols="12" class="d-flex">
<v-text-field
name="title"
label="نام فارسی محصول"
outlined
placeholder=" "
v-model="products.title"
class="ml-1"
></v-text-field>
<v-text-field
name="subtitle"
label="نام انگلیسی محصول"
outlined
placeholder=" "
v-model="products.subtitle"
class="ml-1"
></v-text-field>
<v-text-field
name="image"
label="آدرس عکس محصول"
outlined
placeholder=" "
v-model="products.image"
></v-text-field>
</v-col>
<v-col cols="12">
<v-textarea
name="description"
outlined
label="توضیحات محصول"
placeholder=" "
v-model="products.description"
></v-textarea>
</v-col>
</v-row>
</v-container>
</v-col>
<v-col cols="4">
<v-img :src="require('#/assets/images/upload.png')"></v-img>
</v-col>
<v-col cols="12">
<v-divider light></v-divider>
</v-col>
</v-row>
I have problem lining up the forms with the edges of the upload image and I can't get the textarea to take up the whole height. does anyone have any idea how I can achieve such layout using vuetify? thank you.
You should put your code in v-app tag like this codepen sample

How to handle v-for with input and large data?

I recently facing a problem when using v-for to iterate large data which has input component. The problem is when i text something into the input field, it take so long to respond (almost 2 second on 1000+ data). here is my v-for
<v-col>
<v-row v-for="item in editedItem.priceList" :key="item.id" no-gutters cols="12">
<v-col cols="7" class="mr-3">
<v-text-field v-model.lazy="item.type" solo :rules="[rules.required]" label="Jenis Barang" />
</v-col>
<v-col cols="2" class="mr-3">
<v-autocomplete
v-model.lazy="item.unit"
:items="unit"
label="Satuan"
solo
/>
</v-col>
<v-col cols="2">
<v-text-field v-model.lazy="item.price" solo :rules="[rules.required]" type="number" label="Harga Satuan" prefix="Rp " />
</v-col>
</v-row>
</v-col>
How can i improve the performance of this code? because i know it will rerender all the component everytime value in input changed.

How can I combine vue tel input with input text vuetify?

My code like this :
<v-row>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="Phone"
outlined
dense
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<vue-tel-input v-model="phone"></vue-tel-input>
</v-col>
</v-row>
My codepen like this : https://codepen.io/positivethinking639/pen/qBBKYON?&editable=true&editors=101
I want to combine it to be like this :
The blue sign is taken from vue tel input. The text field next to it is taken from the vuetify component
How do I combine 2 different components into one like the image above?
Yes, it is possible to set the country code next to dropdown
Here is the working codepen: https://codepen.io/chansv/pen/pooZJey?editors=1010
<div id="app">
<v-app id="inspire">
<v-form>
<v-container>
<v-row>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="Phone"
outlined
dense
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<vue-tel-input v-model="phone" #country-changed="countrySelected">
<template v-slot:arrow-icon>
<v-icon>arrow_drop_down</v-icon>
<strong>+{{countryCode}}</strong>
</template>
</vue-tel-input>
</v-col>
</v-row>
</v-container>
</v-form>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
phone: null,
countryCode: null,
}
},
methods: {
countrySelected(val) {
this.countryCode = val.dialCode;
}
}
})