How to loop using v-for in VueJS? - javascript

I am trying to loop in VueJS using v-for but for some reason the text doesn't seem to be rendering. Not sure what i am doing wrong?
This is my sample pen
new Vue({
el: "#app",
data() {
return {
inputValue: "",
myArray: []
};
},
methods: {
createArray() {
this.myArray.push(this.inputValue);
console.log(this.myArray);
},
clear() {
this.inputValue = "";
this.myArray = [];
console.log(this.myArray);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.5.14/dist/vuetify.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.5.14/dist/vuetify.min.css" rel="stylesheet" />
<div id="app">
<v-app id="inspire">
<v-layout justify-center>
<v-flex xs6>
<v-text-field v-model="inputValue">
</v-text-field>
<v-btn :disabled="inputValue === ''" #click="createArray">Click Me</v-btn>
<v-btn #click="clear">Clear</v-btn>
<div v-if="myArray.length > 0">
<div v-for="(item,i) in myArray"></div>
<li>{{item}}</li>
</div>
</v-flex>
</v-layout>
</v-app>
</div>
Any help will be appreciated. Thank you,

You put a </div> at the wrong place.
Here it should be :
<div v-for="(item,i) in myArray">
<li>{{item}}</li>
</div>

Related

How to have the button span the whole width?

I am using Vuetify card with a layout and rendering some dynamic vuetify components inside of the card on checkbox selection which renders either a divider, a spacer, toolbar or button but i am not able to figure out how can i make the buttons span the entire width?
Basically the dynamic button should look like the button at the end rendering the entire width.
Please check this codepen.
Please check this working example:-
new Vue({
el: "#app",
data() {
return {
pricing: [{
text: "Actual price:",
value: "$17,000",
},
{
text: " Discount",
value: "$12,345",
}
],
elements: [{
title: "Divider",
value: "v-divider"
},
{
title: "Toolbar",
value: "v-toolbar"
},
{
title: "Button",
value: "v-btn"
}
],
selected: []
};
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.5.14/dist/vuetify.min.js"></script>
<link rel="stylesheet" href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons'>
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.5.14/dist/vuetify.min.css" rel="stylesheet" />
<div id="app">
<v-app id="inspire">
<v-container>
<v-layout row>
<v-flex xs6>
<v-card>
<v-card-text>
<v-layout row justify-space-between v-for="option in pricing" :key="option.value" class="my-3">
<span :class="option.class">{{option.text}}</span>
<component v-for="(el, i) in selected" :key="i" :is="el.value"></component>
<span>{{option.value}}</span>
</v-layout>
<v-layout row justify-center>
<v-flex xs11>
<v-btn block>
Request
</v-btn>
</v-flex>
</v-layout>
</v-card-text>
</v-card>
<v-flex v-for="el in elements" :key="el.value">
<v-checkbox :value="el" v-model="selected" :label="el.title">
</v-checkbox>
</v-flex>
</v-flex>
</v-layout>
</v-container>
</v-app>
</div>
Any help will be appreciated. Thank you so much.
Use .flex.xs12 (12 = flex-basis: 100%;)
-or-
remove xs12 (And add button block attribute = flex: 1 0 auto;).
<!-- block buttons extend the full available width -->
<template>
<v-btn block>
Block Button
</v-btn>
</template>
https://vuetifyjs.com/en/components/buttons/#block

Adding values to an array inside hash in vue not working

I am trying add the feature to add multiple workers when clicked on Add worker. The issue I am facing here is that when I put workers array inside the management then this feature doesn't work. But if puts workers array outside the management hash then it works. But I want it to be inside the management issue. I am getting the error cannot read the property push.
<div v-for="(worker, index) in management.workers" :key="index">
<v-container fluid>
<v-layout row wrap>
<v-flex xs12 md6 class="add-col-padding-right info-align">
<v-text-field
label='Name'
v-model="worker.name"
>
</v-text-field>
</v-flex>
<v-flex xs12 md6 class="add-col-padding-left info-align">
<v-text-field
label='Hours of work'
v-model="worker.hours_of_work"
>
</v-text-field>
</v-flex>
</v-layout>
<v-btn class="red-button next-btn" #click="deleteRow(index)">Delete</v-btn>
</v-container>
</div>
<v-btn class="red-button next-btn" #click="addRow">Add Workers</v-btn>
<script>
export default {
data () {
return {
management: {
workers: []
}
}
}
methods: {
addRow() {
this.management.workers.push({
name: '',
hours_of_work: '',
total: ''
})
},
deleteRow(index) {
this.management.workers.splice(index,1)
}
}
}
</script>
Code seems to work below:
new Vue({
el: "#app",
vuetify: new Vuetify(),
data() {
return {
management: {
workers: []
}
}
},
methods: {
addRow() {
this.management.workers.push({
name: '',
hours_of_work: '',
total: ''
})
},
deleteRow(index) {
this.management.workers.splice(index, 1)
},
getRows(){
console.clear()
console.log(this.management.workers)
}
}
});
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.2.20/dist/vuetify.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.2.20/dist/vuetify.min.js"></script>
<div id="app">
<v-app>
<div v-for="(worker, index) in management.workers" :key="index">
<v-container fluid>
<v-layout row wrap>
<v-flex xs12 md6 class="add-col-padding-right info-align">
<v-text-field label='Name' v-model="worker.name">
</v-text-field>
</v-flex>
<v-flex xs12 md6 class="add-col-padding-left info-align">
<v-text-field label='Hours of work' v-model="worker.hours_of_work">
</v-text-field>
</v-flex>
</v-layout>
<v-btn class="red-button next-btn" #click="deleteRow(index)">Delete</v-btn>
</v-container>
</div>
<v-btn class="red-button next-btn" #click="addRow">Add Workers</v-btn>
<v-btn class="red-button next-btn" #click="getRows">View Workers</v-btn>
</v-app>
</div>

How to add two v-text-fields when I click a button dynamically using vuetify

How can I add two v-text-fields when I click on a button, and if I need more v-text-fields I click on the button and it appears in my content.
I would like something like this
I hope you get the idea.
<v-container fluid>
<v-row align="center" >
<v-col >
<v-text-field color="info" v-model="new.name" label="Name" required></v-text-field>
</v-col>
<v-col>
<v-select color="info" :items="arrResp" v-model="new.idResp" label="Boss" required></v-select>
</v-col>
</v-row>
</v-container>
Thank you for your help.
Codepen
<div id="app">
<v-app id="inspire">
<div
v-for="(textField, i) in textFields"
:key="i"
class="text-fields-row"
>
<v-text-field
:label="textField.label1"
v-model="textField.value1"
></v-text-field>
<v-text-field
:label="textField.label2"
v-model="textField.value2"
></v-text-field>
<v-btn #click="remove(i)" class="error">delete</v-btn>
</div>
<v-btn #click="add" class="primary">add</v-btn>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
textFields: []
}
},
methods: {
add () {
this.textFields.push({
label1: "foo",
value1: "",
label2: "bar",
value2: ""
})
},
remove (index) {
this.textFields.splice(index, 1)
}
}
})
.text-fields-row {
display: flex;
}

Vue transition mode don't work when combined with v-for and v-if

in Vue with Vuetify, I want to change dynamically v-cards with animate.css, and I'm facing a problem. The out-in mode doesn't want to work in this situation. Fade-in and fade-out animations are moving at the same time. How can force it to start the fade-in animation after ending a fade-in?
new Vue({
el: '#app',
data() {
return {
number: 1,
items: [
{
text: "a",
number: 1
},
{
text: "b",
number: 2
},
{
text: "c",
number: 3
},
]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script><script src="https://unpkg.com/vuetify/dist/vuetify.min.js"></script>
<link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/animate.css" rel="stylesheet"/>
<div id="app">
<div v-for="(item, index) in items" :key="index">
<transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
<v-card dark class="ma-3" v-if="number === item.number">
<p>{{item.text}}</p>
</v-card>
</transition>
</div>
<br>
<v-btn #click="number++; if(number === 4) number = 1;">Next</v-btn>
</div>
https://codepen.io/km2442/pen/zgmmwz
What is wrong ?
Your transition is inside a loop which means after the rendering you will have multiple transitions that have no relation to each other (mode doesn't work)... this is how your template will look like after rendering :
<div key="0">
<transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
<v-card dark class="ma-3" v-if="true">
<p>a</p>
</v-card>
</transition>
</div>
<div key="1">
<transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
<!-- <v-card dark class="ma-3" v-if="false">
<p>b</p>
</v-card> -->
</transition>
</div>
<div key="2">
<transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
<!-- <v-card dark class="ma-3" v-if="false">
<p>c</p>
</v-card> -->
</transition>
</div>
<div key="3">
<transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
<!-- <v-card dark class="ma-3" v-if="false">
<p>d</p>
</v-card> -->
</transition>
</div>
so when you press next you are jumping from a transition to another one ...and in this case the mode is lost .
How i fix this ?
we just need to wrap our whole items inside a transition, so in this case there is only one transition that will detect when an element is going out and a new one is coming in (mode will work) :
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
data() {
return {
number: 1,
items: [{
text: "a",
number: 1
},
{
text: "b",
number: 2
},
{
text: "c",
number: 3
},
]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vuetify/dist/vuetify.min.js"></script>
<link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/animate.css" rel="stylesheet" />
<div id="app">
<transition mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
<template v-for="(item, index) in items">
<v-card dark class="ma-3" v-if="number === item.number" :key="index">
<p>{{item.text}}</p>
</v-card>
</template>
</transition>
<br>
<v-btn #click="number++; if(number === 4) number = 1;">Next</v-btn>
</div>
You should use a <transition-group>, when iterating with a v-for loop.
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js">
</script><script src="https://unpkg.com/vuetify/dist/vuetify.min.js"></script>
<link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/animate.css" rel="stylesheet"/>
<div id="app">
<transition-group mode="out-in" enter-active-class="animated slideInLeft" leave-active-class="animated slideOutRight">
<div v-for="(item, index) in items" :key="index">
<v-card dark class="ma-3" v-if="number === item.number">
<p>{{item.text}}</p>
</v-card>
</transition-group>
</div>
<br>
<v-btn #click="number++; if(number === 4) number = 1;">Next</v-btn>
</div>
Documentation: https://v2.vuejs.org/v2/guide/transitions.html#List-Transitions

VUE / VUETIFY - Auto-adjust height adding or removing items from list component "v-list-tile"

I created a simple Contact list with an input to add the contact items but after I add a few items it's not resizing.
I used this as an example and there is resizing but not in my code:
https://v2.vuejs.org/v2/guide/list.html
Could anyone help me with that?
Here is the Codepen:
https://codepen.io/fabiozanchi/pen/qoBpgd
Vue.component('contact-item', {
template: '\
<v-list-tile-title>\
<button #click="$emit(\'remove\')"><v-icon class="remove-email-icon" color="red">remove_circle</v-icon></button>\{{ title }}\
</v-list-tile-title>\
',
props: ['title']
})
new Vue({
el: '#contact-list',
data: {
newContact: '',
contacts: [],
nextContactId: 1
},
methods: {
addNewContact: function() {
this.contacts.push({
id: this.nextContactId++,
title: this.newContact
})
this.newContact = ''
}
}
})
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons" />
<link rel="stylesheet" type="text/css" href="https://unpkg.com/vuetify#1.0.5/dist/vuetify.min.css" />
<script src="https://unpkg.com/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#1.0.5/dist/vuetify.min.js"></script>
<div id="contact-list">
<v-app>
<v-layout row>
<v-flex xs12 sm6 offset-sm3>
<v-card>
<v-toolbar color="blue" dark>
<v-toolbar-title class="text-xs-center">Contacts</v-toolbar-title>
</v-toolbar>
<v-container>
<v-text-field v-model="newContact" #keyup.enter="addNewContact" placeholder="Add new email contact email"></v-text-field>
</v-container>
<v-divider></v-divider>
<v-list class="resize-list">
<v-list-tile>
<v-list-tile-content>
<v-list-tile-title is="contact-item" v-for="(contact, index) in contacts" :key="contact.id" :title="contact.title" #remove="contacts.splice(index, 1)">
</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-card>
</v-flex>
</v-layout>
</v-app>
</div>
Thank you!
Use v-for on v-list-tile component (see vuetify examples).
<v-list-tile
v-for="(contact, index) in contacts"
:key="contact.id"
>
That will produce multiple lis that you want from your examples (currently you only have one li element in list because of v-for on title, so that's why it's not working properly)

Categories

Resources