I want to update dropdown list. Here is my dropdown
<div v-for="(field, key) in config" :key="key">
<div>
<v-row>
<v-col cols="1">
<div class="mt-4 ml-3">
</div>
</v-col>
<v-col cols="5">
<v-autocomplete
dense
:items="items[key]"
item-text="description"
item-value="id"
no-filter
return-object
single-line
#change="(event) => updateData(event, key)"
#click="click()"
>
</v-autocomplete>
</v-col>
</v-row>
</div>
</div>
methods: {
updateData(value, index) {
getReport(this.id, this.param).then((res) => {
this.items[index] = res.data.data;
});
},
},
and my code. How can I update the this.items[index]. Is this way correct ? It does not update this.items.
Try to avoid this reactivity issue by using this.$set helper :
this.$set(this.items,index,res.data.data);
Related
I am a vuejs newbie and i am having difficulties trying to make my objects return back in a row they are in a column.
components/sellingItems.vue
<template>
<v-container class="my-5">
<v-row>
<v-col
sm="6"
md="4"
>
<v-card outlined>
<v-img :src="image" height="200px" />
<v-card-title> {{ name}} </v-card-title>
<v-card-subtitle> ${{ price }}</v-card-subtitle>
<v-card-actions>
<v-btn #click="addToCart" color="success" outlined >
<v-icon small left> add </v-icon>
Add to Cart
</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
props: ['id', 'image', 'name', 'price'],
}
</script>
pages/index.vue
After adding the for loop my products list turns into a column, i prefer it in a row to suit my aim
The Index Page
Stack overflow wont let me post the index page code so heres a screenshot
Check this
use a row and columns by editing your class to determine how many items per row I have added code in codepen
https://codepen.io/Juan-Carlos-MA/pen/yLMdLRX?editors=1010
<div id="app">
<v-app id="inspire">
<br>
<br>
<v-slider
v-model="fruits"
:tick-labels="ticksLabels"
:max="3"
step="1"
ticks="always"
tick-size="4"
></v-slider>
<div class="row">
<div v-for="item in items" :class="selection">
<v-card :loading="loading" class="mx-auto my-12" max-width="374">
<template slot="progress">
<v-progress-linear color="deep-purple" height="10" indeterminate></v-progress-linear>
</template>
<v-img height="250" src="https://cdn.vuetifyjs.com/images/cards/cooking.png"></v-img>
<v-card-title>{{ item.mensaje }}</v-card-title>
<v-divider class="mx-4"></v-divider>
<v-card-title>{{ item.precio }}</v-card-title>
<v-card-actions>
<v-btn color="deep-purple lighten-2" text #click="reserve">
Add TO CART
</v-btn>
</v-card-actions>
</v-card>
</div>
</div>
</v-app>
</div>
new Vue({
el: "#app",
vuetify: new Vuetify(),
data: () => ({
loading: false,
selection: "col-6",
value: 0,
fruits: 1,
ticksLabels: ["one", "two", "tree", "four"],
items: [
{ mensaje: "Tamales", precio: "$300" },
{ mensaje: "Atole", precio: "$300" },
{ mensaje: "Taquito", precio: "$300" },
{ mensaje: "Taquito", precio: "$300" }
]
}),
methods: {
reserve() {
this.loading = true;
setTimeout(() => (this.loading = false), 2000);
}
},
watch: {
fruits: function (val) {
console.log(val);
if (val == 0) {
this.selection = "col-12";
} else {
if (val == 1) {
this.selection = "col-6";
} else {
if (val == 2) {
this.selection = "col-4";
} else {
if (val == 3) {
this.selection = "col-3";
}
}
}
}
}
}
});
Thew problem seems to be that you are creating a new row vor every item
<template>
<v-container class="my-5">
<v-row> <!-- <=== here is your row -->
<v-col sm="6" md="4">
... etc
</v-col>
</v-row>
</v-container>
</template>
you can either move the <v-row> into the parent component and wrap <SellingItems v-for...> or pass an array (products) into the component and have the v-for within that component
<SellingItems :items="products" ... >
<template>
<v-container class="my-5">
<v-row>
<v-col sm="6" md="4" v-for="item in items"> <!-- <=== move v-for here -->
... etc
</v-col>
</v-row>
</v-container>
</template>
At the moment, I have the following code:
<template>
<v-container>
<v-form v-model="valid" ref="form" v-for="(resposta,index) in formData.body" :key="index">
<v-row>
<v-col cols="8">
<v-text-field
v-model="resposta.answer"
:rules="idRules"
:counter="200"
label="Texto da Resposta"
required
></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col xl="2" lg="3" md="3" sm="4" class="mt-4">
<p class="grey--text text--darken-1">Resposta Correta:</p>
</v-col>
<v-radio-group
v-model="resposta.correction"
row
mandatory
>
<v-col md="4" sm="4">
<v-radio
label="0"
value="0"
></v-radio>
</v-col>
<v-col md="4" sm="4">
<v-radio
label="1"
value="1"
></v-radio>
</v-col>
</v-radio-group>
</v-row>
<v-row>
<v-col xl="2" lg="3" md="3" sm="4" class="mt-4">
<p class="grey--text text--darken-1">Resposta Obrigatória:</p>
</v-col>
<v-radio-group
v-model="resposta.mandatory"
row
mandatory
>
<v-col md="4" sm="4">
<v-radio
label="0"
value="0"
></v-radio>
</v-col>
<v-col md="4" sm="4">
<v-radio
label="1"
value="1"
></v-radio>
</v-col>
</v-radio-group>
</v-row>
<v-row>
<v-col xl="2" lg="3" md="3" sm="4" class="mt-4">
<p class="grey--text text--darken-1">Resposta Eliminatória:</p>
</v-col>
<v-radio-group
v-model="resposta.eliminative"
row
mandatory
>
<v-col md="4" sm="4">
<v-radio
label="0"
value="0"
></v-radio>
</v-col>
<v-col md="4" sm="4">
<v-radio
label="1"
value="1"
></v-radio>
</v-col>
</v-radio-group>
</v-row>
<v-row>
<v-col cols="5">
<v-select :items="pontos"
v-model="resposta.points"
label="Pontos"
dense
></v-select>
</v-col>
<v-col cols="7" align="center">
<v-btn #click="addAnswer" class="white--text" color="#2A3F54" grey--text>
Add Answer
</v-btn> {{formData.body}}
</v-col>
</v-row>
</v-form>
</v-container>
</template>
<script>
export default {
data(){
return{
formData:{
body: [{
answer: '',
correction: '',
mandatory: '',
eliminative: '',
points:''
}]
}
}
},
methods: {
addAnswer(){
this.formData.body.push({answer: '',
correction: '',
mandatory: '',
eliminative: '',
points:''})
alert("inserida")
}
},
watch: {
formData: {
handler: function() {
this.$emit('newdataRespostas', this.formData.body);
},
deep: true
}
},
}
</script>
The goal with this is to be able to get the information in the array in another component, which I'm being able to do. The problem here is that everytime I click on the Add Answer button, it creates a new identical form right under the previous one. The data is being pushed correctly into the array, the other component is being able to watch for the information inside that array, but I'm just not able to get rid of the new forms that get created. If I add 4 new answers, I'll have 5 forms by the end, which is clearly not optimal. Also any tips regarding any part of the code are welcome. I'm completely new to Vue.js and Vuetify.
Sorry for the long code, but almost all of it is just the different form components.
The form uses v-for on formData.body[], so each array element (each answer) renders a new form. It sounds like you want only the newest form to be shown, in which case you don't need v-for.
I would replace the v-for with a different data property (e.g., named resposta to match the current variable used in your template), and append that property to formData.body[] in addAnswer():
<template>
<v-form v-model="valid" ref="form">
<!--...-->
<v-text-field v-model="resposta.answer" />
</v-form>
</template>
<script>
export default {
data() {
return {
formData: {
body: [],
},
resposta: {},
};
},
methods: {
addAnswer() {
this.formData.body.push(this.resposta)
this.resposta = {}
},
},
}
</script>
demo
So I want to bind batch_code data from dashboard.vue parent to review.vue child component
so, the dashboard contains details like the batch_code, then I have trouble passing the data to the review component, of which it will get the batch_code upon clicking the "Rate and Review" button
when I did try, I am just getting null values from returning said data. any suggestions?
dashboard.vue
<template>
<div>
<v-col cols="10" class="mx-auto">
<v-card class="pa-4" outlined>
<v-card-title class="pb-0 pt-2">Dashbard</v-card-title>
<div v-if="checkifEmpty()">
<v-row>
<v-col
v-for="item in myBatch.all_batch"
:key="item.batch_code"
cols="6"
>
<v-card class="ma-2" outlined>
<div class="d-flex">
<v-avatar class="ma-3" size="150" tile>
<v-img :src="item.image"></v-img>
</v-avatar>
<div>
<v-card-title class="pb-0 pt-2"
>{{ item.offer }} ({{ item.level }})</v-card-title
>
<v-card-text>
<div class="mt-0">{{ item.techer_name }}</div>
<div class="mt-0">{{ item.batch_name }}</div>
<div class="Heading 6 pb-0">
{{ item.start_date }} -
{{ item.end_date }}
</div>
<div class="subtitle-1 pb-0">{{ item.type }}</div>
</v-card-text>
</div>
<v-btn elevation="3" v-on:click="openReviewDialog"
>Rate and Review!</v-btn
>
</div>
</v-card>
</v-col>
</v-row>
</div>
<div v-else>
<v-card-text class="pb-0 pt-2"
>You have no enrolled offers</v-card-text
>
</div>
</v-card>
</v-col>
<review />
</div>
</template>
<script>
import store from "../../store/index";
import review from "./review"
export default {
name: "Dashboard",
components:{
review,
},
computed: {
myBatch() {
return store.getters.getMyOffers;
},
},
methods: {
checkifEmpty() {
let batch = this.myBatch;
if (batch == null || batch.all_batch.length == 0) {
return false;
} else {
return true;
}
},
openReviewDialog() {
this.$store.dispatch("setreviewDialog");
this.sidebarFront = false;
}
},
};
</script>
<style>
</style>
review.vue
<template>
<v-row justify="center">
<v-dialog v-model="reviewDialog" persistent max-width="900px">
<v-card>
<v-card-title class="justify-center">
<span class="headline font-weight-bold"
>Rate and Review this Course!</span
>
</v-card-title>
<v-card-text>
<v-container fluid>
<v-row>
<v-col cols="12" sm="12" md="12">
<v-form
ref="userReview"
v-model="userReviewForm"
lazy-validation
>
<v-text-field
rounded
outlined
v-model="subject"
label="Subject"
required
></v-text-field>
<v-text-field
rounded
outlined
v-model="batch_code"
label="batch_code"
readonly
></v-text-field>
<v-textarea
rounded
outlined
v-model="review"
counter="250"
label="Review"
required
></v-textarea>
<v-rating v-model="rating">
<template v-slot:item="props">
<v-icon
:color="props.isFilled ? 'orange lighten-1' : 'grey lighten-1'"
size = "30"
#click="handleRatingChange(props)">mdi-star</v-icon>
</template>
</v-rating>
<div>
<v-btn
:loading="loginLoader"
large
block
rounded
elevation="0"
color="primary"
#click="submit"
>
Submit
</v-btn>
</div>
</v-form>
</v-col>
</v-row>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<div class="close"> <v-btn color="error" text #click="closeReviewDialog()"> Close </v-btn></div>
</v-card-actions>
</v-card>
</v-dialog>
</v-row>
</template>
<script>
import store from "../../store/index";
export default {
props: {
item:{
batch_code: null;
}
},
name: "review",
data() {
return {
getters: store.getters,
rating: null
};
},
computed: {
reviewDialog: function () {
return this.getters.getreviewDialog;
},
},
methods: {
closeReviewDialog: function () {
//this.show = false;
//this.$refs.card.hide();
//store.dispatch("removeLoginError");
store.dispatch("setreviewDialog");
},
handleRatingChange(props){
console.log(props.index + 1)
this.rating = props.index +1
}
},
};
</script>
'''
p.s: i don't know if it's different when calling props for a component than to a dialog box.
just update your code like below tips,
openReviewDialog() {
this.$store.dispatch("setreviewDialog", **your_rating_data**);
this.sidebarFront = false;
}
so update your dispatch/action accordingly in store.
and when loading your form just pull data from the store using getter and show on dialog.
I using vuetify.js on laravel project.
and I create [station][verhicle][take a time] form like this.
its simple form. but ...
station select box is used v-autocomplete component.
so it seems that the input tag is automatically embedded like this.
this input tag is unnecessary.
I expect return one array.
Is there any good way?
thank you
<template>
<v-container>
<v-row dense>
<v-col sm="4">
<v-autocomplete
v-model="StationModel"
:items="stationsSon"
:search-input.sync="search"
item-text="name"
item-value="id"
name="station_id[]"
label="station"
clearable
hide-details
hide-selected
outlined
>
<template v-slot:selection="{ item,selected }">
<span>{{ item.routell_name + item.name }}</span>
</template>
<template v-slot:item="{ item }">
<v-list-item-content>
<v-list-item-title v-text="item.name"></v-list-item-title>
<v-list-item-subtitle v-text="item.routell_name"></v-list-item-subtitle>
</v-list-item-content>
</template>
</v-autocomplete>
</v-col>
<v-col sm="4">
<v-select
name="verhicle_id[]"
:items="verhiclesSon"
item-value="id"
item-text="name"
label="verhicle"
outlined
clearable
>
</v-select>
</v-col>
<v-col sm="4">
<v-text-field
name="take_time[]"
type="number"
:rules="[v => v && v.length <= 2 || 'Warn:2 charactor']"
label="take a time"
outlined
>
</v-text-field>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
data: () => ({
stationsDefault: [],
StationModel: null,
search: null,
tab: null,
}),
watch: {
model (val) {
if (val != null) this.tab = 0;
else this.tab = null;
},
search (val) {
if (this.stationsDefault.length > 0) return;
},
},
props:{
stationsSon:{
type: Array
},
verhiclesSon:{
type: Array
},
},
methods:{
snipeDown: function(){
const target = document.getElementsByClassName('v-select__selections');
document.removeChild(target("input"));
}
},
};
</script>
I've been trying to push a text field whenever the "add button" is pressed.
This is my code so far.
<v-container fluid>
<v-row>
<v-col cols="7">
<v-row class= "mx-1 my-1">
<v-text-field outlined label="Test 1" v-model="test1"></v-text-field>
</v-row>
</v-col>
<v-col cols="5">
<v-row class= "mx-4 my-1">
<v-text-field type="number" outlined label="Test 2" v-model="test2"></v-text-field>
</v-row>
</v-col>
</v-row>
<v-row>
<v-col cols="12">
<v-row class= "mx-1 my-n8">
<v-btn
#click="doWork()"
width = 100%
small
outlined
color="#0000b0"
>
<v-icon dark>mdi-plus</v-icon></v-btn>
</v-row>
</v-col>
</v-row>
</v-container>
Here is my javascript
<script>
export default {
data () {
return {
test1:'',
test2:''
}
},
methods: {
doWork () {
//just for debugging purposes
console.log(this.valor)
console.log(this.precio)
}
}
}
</script>
What should I add in the "doWork()" method in order to push another pair of text fields
Thanks in advance <3
You can transform your fields into a fields array:
data () {
return {
inputs: []
}
}
Your addWork method becomes a method that push a new value in this inputs array:
methods: {
doWork () {
this.inputs.push({
label: 'Test',
value: ''
})
}
}
And you display those inputs with a v-for directive:
<v-row>
<v-col cols="2" v-for="(input, index) in inputs" :key="index">
<v-row class="mx-1 my-1">
<v-text-field outlined :label="input.label" v-model="input.value"></v-text-field>
</v-row>
</v-col>
</v-row>
Working example: https://codesandbox.io/s/festive-dream-gbo6t?file=/src/App.vue