I'm using vue.js with vuetify and saving some data in localstorage but whenever I save once and try to save a new data it calls the save function until the end but it doesn't save in localstorage being necessary to reload the page to be able to save a new data.
<v-card>
<v-card-title>
<span class="text-h5">{{ formTitle }}</span>
</v-card-title>
<v-card-text>
<v-container>
<v-row>
<v-col cols="12" sm="12" md="12">
<v-text-field
v-model="contact.name"
label="Name"
:error-messages="nameErrors"
required
#input="$v.contact.name.$touch()"
#blur="$v.contact.name.$touch()"
>
</v-text-field>
</v-col>
<v-col cols="12" sm="12" md="12">
<v-text-field
v-model="contact.cellPhone"
label="Phone"
v-mask="'(##) #####-####'"
:error-messages="cellPhoneErrors"
required
#input="$v.contact.cellPhone.$touch()"
#blur="$v.contact.cellPhone.$touch()"
>
</v-text-field>
</v-col>
</v-row>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text #click="close"> Cancel</v-btn>
<v-btn color="blue darken-1" text #click="save"> Save </v-btn>
</v-card-actions>
</v-card>
save() {
this.submitted = true;
this.$v.$touch();
if (this.$v.$error) {
return;
}
this.editing = false;
if (this.contact.id === 0) {
this.contact.id = this.contacts.length + 1;
this.contact.ddd = this.contact.cellPhone.substr(
1,
2
);
this.contacts.push(this.contact);
} else {
this.contacts[this.index] = this.contact;
}
localStorage.setItem(
'contacts',
JSON.stringify(this.contacts)
);
this.close();
this.contact = {
id: 0,
name: null,
cellPhone: null,
ddd: null,
};
},
I've already tried using async await but the problem remains, the only solution so far was using a normal html form instead of the vuetify form.
I have a Kanban board inside my dashboard which displays issues of a project. I added a menu to allow the user to filter the kanban board by project such that only one project's issue are visible at once. The default view is the issues of all the projects.
In my Dashboard component, I get the list of all projects from a server using axios (which works correctly).
When a user chooses a project, I send to the Kanban board component a prop which is the project id so that I can fetch that project's issues from the server.
However, the prop I'm sending from Dashboard is undefined somehow, and I cannot figure out why
Dashboard.vue
<template>
<v-container>
<v-row class="my-1">
<v-col cols="3">
<h2 style="font-size:40px;color:rgb(92, 92, 92)">Kanban Board</h2>
</v-col>
<v-col cols="7"></v-col>
<v-col cols="2">
<v-menu offset-y>
<template v-slot:activator="{ on, attrs }">
<v-btn color="primary" dark v-bind="attrs" v-on="on">
View
</v-btn>
</template>
<v-list>
<v-list-item v-for="(project, index) in ProjectList" :key="index">
<v-list-item-title #click="changeView(project.id)">{{ project.title }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-col>
</v-row>
<v-row>
<KanBanBoard :projectid="project_id"></KanBanBoard>
</v-row>
</v-container>
</template>
<script>
import KanBanBoard from './KanBanBoard.vue'
import { mapGetters, mapActions } from 'vuex'
export default {
components: {
KanBanBoard,
},
data() {
return {
project_id: '',
}
},
computed: {
...mapGetters(['ProjectList']),
},
methods: {
...mapActions(['getProjectList']),
changeView(project_id) {
this.project_id = project_id
},
},
created() {
this.getProjectList()
},
}
</script>
<style scoped>
.view {
font-size: 20px;
}
</style>
NavBar.js (Vuex file Dashboard uses to get the list of projects)
import axios from 'axios'
const state = {
Projects: [],
ProjectsIssuesList: []
}
const getters = {
ProjectList: (state) => state.Projects,
ProjectIssuesList: (state) => state.ProjectsIssuesList
}
const actions = {
async getProjectList({ commit }) {
var projectList = []
var issuesList = []
await axios
.get('https://fadiserver.herokuapp.com/api/v1/my-projects/')
.then(response => {
projectList = response.data
for (let i = 0; i < projectList.length; i++) {
let projectid = projectList[i].id
axios
.get('https://fadiserver.herokuapp.com/api/v1/my-issues-titles/?projectid=' + projectid)
.then(response => {
issuesList.push(response.data)
})
.catch(error => {
console.log(error)
})
}
})
.catch(error => {
console.log(error)
})
commit('setProjects', projectList),
commit('setProjectsIssues', issuesList)
},
}
const mutations = {
setProjects: (state, Projects) => (state.Projects = Projects),
setProjectsIssues: (state, ProjectsIssuesList) => (state.ProjectsIssuesList = ProjectsIssuesList)
}
export default {
state,
getters,
actions,
mutations
}
KanBanBoard.vue
<template>
<v-container>
<v-row wrap>
<v-col xl="4" lg="4" md="4" sm="4" xs="12">
<v-card>
<v-card-title class="blue lighten-3">
<span class="white--text">Open</span>
</v-card-title>
<v-divider horizontal></v-divider>
<v-card-text class="blue lighten-3">
<draggable class="list-group kanban-column" :list="Open" group="tasks">
<v-card
class="#f4f5fa"
style="height:auto; margin-top:10px"
v-for="issue in Open"
:key="issue"
align-center
elevation="3"
>
<v-card-text>
<v-row dense style="width:auto">
<router-link
class="d-flex align-center text-decoration-none grey--text"
style="font-size:18px;"
:to="{ name: 'IssuePage', params: { id: issue.id, issue } }"
>
{{ issue.title }}
</router-link>
</v-row>
<v-row dense>
<v-col>
<v-chip
class="ma-2"
color="red"
outlined
style="position:relative; right:10px;top:10px; height:min-content"
>
{{ issue.issueSeverity }}
</v-chip>
</v-col>
<v-col>
<v-chip
class="ma-2"
color="green"
outlined
style="position:relative; right:83px; top:10px;height:min-content"
>
{{ issue.issueType }}
</v-chip>
</v-col>
</v-row>
</v-card-text>
</v-card>
</draggable>
</v-card-text>
</v-card>
</v-col>
<v-col xl="4" lg="4" md="4" sm="4" xs="12">
<v-card>
<v-card-title class="light-green lighten-3">
<span class="white--text">In Progress</span>
</v-card-title>
<v-divider horizontal></v-divider>
<v-card-text class="light-green lighten-3">
<draggable class="list-group kanban-column" :list="InProgress" group="tasks">
<v-card
class="#f4f5fa"
style="height:auto; margin-top:10px"
v-for="issue in InProgress"
:key="issue"
align-center
elevation="3"
>
<v-card-text>
<v-row dense style="width:auto">
<router-link
class="d-flex align-center text-decoration-none grey--text"
style="font-size:18px;"
:to="{ name: 'IssuePage', params: { id: issue.id, issue } }"
>
{{ issue.title }}
</router-link>
</v-row>
<v-row>
<v-col>
<v-chip
class="ma-2"
color="red"
outlined
style="position:relative; right:10px;top:10px; height:min-content"
>
{{ issue.issueSeverity }}
</v-chip>
</v-col>
<v-col>
<v-chip
class="ma-2"
color="green"
outlined
style="position:relative; right:83px; top:10px;height:min-content"
>
{{ issue.issueType }}
</v-chip>
</v-col>
</v-row>
</v-card-text>
</v-card>
</draggable>
</v-card-text>
</v-card>
</v-col>
<v-col xl="4" lg="4" md="4" sm="4" xs="12">
<v-card>
<v-card-title class="orange lighten-3">
<span class="white--text">Completed</span>
</v-card-title>
<v-divider horizontal></v-divider>
<v-card-text class="orange lighten-3">
<draggable class="list-group kanban-column" :list="Completed" group="tasks">
<v-card
class="#f4f5fa"
style="height:auto; margin-top:10px"
v-for="issue in Completed"
:key="issue"
align-center
elevation="3"
>
<v-card-text>
<v-row dense style="width:auto">
<router-link
class="d-flex align-center text-decoration-none grey--text"
style="font-size:18px;"
:to="{ name: 'IssuePage', params: { id: issue.id, issue } }"
>
{{ issue.title }}
</router-link>
</v-row>
<v-row dense>
<v-col>
<v-chip
class="ma-2"
color="red"
outlined
style="position:relative; right:10px;top:10px; height:min-content"
>
{{ issue.issueSeverity }}
</v-chip>
</v-col>
<v-col>
<v-chip
class="ma-2"
color="green"
outlined
style="position:relative; right:83px; top:10px;height:min-content"
>
{{ issue.issueType }}
</v-chip>
</v-col>
</v-row>
</v-card-text>
</v-card>
</draggable>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
import draggable from 'vuedraggable'
import { mapGetters, mapActions } from 'vuex'
export default {
props: ['project_id'],
components: {
draggable,
},
computed: {
...mapGetters(['Open']),
...mapGetters(['InProgress']),
...mapGetters(['Completed']),
},
watch: {
projectid() {
this.fetchIssuesofProject(this.project_id)
this.test()
},
},
methods: {
...mapActions(['fetchIssuesofProject']),
test() {
console.log(this.projectid)
},
},
created() {
this.test(), this.fetchIssuesofProject(this.project_id)
},
}
</script>
<style scoped>
hr {
margin-top: 0.1px;
margin-bottom: 0.1px;
border: 1;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
</style>
Kanban.js
import axios from 'axios'
const state = {
Issues: [],
}
const getters = {
Open: (state) => state.Issues.filter(x => x.issueStatus == 'Open'),
InProgress: (state) => state.Issues.filter(x => x.issueStatus == 'In Progress'),
Completed: (state) => state.Issues.filter(x => x.issueStatus == 'Closed'),
}
const actions = {
async fetchIssuesofProject({ commit }, projectid) {
const response = await axios.get('https://fadiserver.herokuapp.com/api/v1/my-issues-titles/?projectid=' + projectid).catch(error => {
console.log("The error is here")
})
commit('setIssues', response.data)
}
}
const mutations = {
setIssues: (state, Issues) => (state.Issues = Issues)
}
export default {
state,
getters,
actions,
mutations
}```
Probably it's because in KanBanBoard.vue you defined your prop as project_id and in Dashboard.vue you're passing it like this:
<KanBanBoard :projectid="project_id"></KanBanBoard>
instead do:
<KanBanBoard :project_id="project_id"></KanBanBoard>
I have an edit form, and I'm trying to populate my input base on the response from API. My campaign data look like this.
{
"id": 219,
"name": "finishedddd-1642606412049"
}
Testing
You see that I can access campaign.name like this
<p>Campaign Name : {{ campaign.name }}</p>
Trying
I want to pre-populated my name input, so I did this
data() {
return {
campaign: {},
form: {
errors: {},
values: {
name: this.campaign.name,
...
Result
Somehow that kept getting me :
"TypeError: Cannot read properties of undefined (reading 'name')"
Code
<template>
<v-container fluid class="my-1">
<Navbar />
<Breadcrumbs />
<v-row>
<v-col cols="12">
<v-card elevation="2">
<PanelHeader type="create" icon="campaign" title="Campaigns" />
<v-stepper v-model="e1" justify="center" elevation="0">
<v-stepper-header>
<v-stepper-step :complete="e1 > 1" step="1"> Campaign </v-stepper-step>
<v-divider></v-divider>
<v-stepper-step :complete="e1 > 2" step="2"> Setup </v-stepper-step>
<v-divider></v-divider>
<v-stepper-step step="3"> Finish </v-stepper-step>
</v-stepper-header>
<v-stepper-items>
<v-stepper-content step="1">
<v-card class="mb-12" elevation="0">
<v-form ref="form" lazy-validation v-model="valid" id="form">
<v-row>
<v-card-text class="font-weight-bold">
Campaigns
<p>Campaign Name : {{ campaign.name }}</p>
<v-tooltip right>
<template v-slot:activator="{ on, attrs }">
<v-btn icon v-bind="attrs" v-on="on">
<v-icon color="grey lighten-1">info</v-icon>
</v-btn>
</template>
<span>Select marketing campaign type for Print Materials or Product Tags. Provide a name to identify the marketing campaign.</span>
</v-tooltip>
</v-card-text>
</v-row>
<v-row>
<v-col class="col-sm-2 col-lg-2 col-12">
<v-select disabled dense outlined :items="types" label="Type" v-model="form.values.type" :rules="form.rules.type"></v-select>
</v-col>
<v-col cols="12" sm="6" md="2">
<v-text-field dense outlined v-model="form.values.name" :rules="form.rules.name" label="Name" required></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col cols="12" sm="6" md="4">
<v-textarea dense rows="1" outlined v-model="form.values.description" label="Description" required></v-textarea>
</v-col>
</v-row>
<v-row>
<v-card-text class="font-weight-bold"
>Schedule :
<v-tooltip right>
<template v-slot:activator="{ on, attrs }">
<v-btn icon v-bind="attrs" v-on="on">
<v-icon color="grey lighten-1">info</v-icon>
</v-btn>
</template>
<span>Set the time zone, start and end date for this campaign to be active.</span>
</v-tooltip>
</v-card-text>
<v-col cols="12" sm="6" md="4">
<v-select dense outlined :items="timezones" v-model="form.values.timezone" :rules="form.rules.timezone" label="Timezone" append-icon="lock_clock"></v-select>
</v-col>
</v-row>
<v-row>
<v-col cols="12" sm="6" md="2">
<v-menu v-model="form.values.startDateMenu" :close-on-content-click="false" :nudge-right="40" transition="scale-transition" offset-y min-width="auto">
<template v-slot:activator="{ on, attrs }">
<v-text-field dense outlined v-model="form.values.startDate" :rules="form.rules.startDate" label="Start Date" append-icon="mdi-calendar" readonly v-bind="attrs" v-on="on"></v-text-field>
</template>
<v-date-picker v-model="form.values.startDate"></v-date-picker>
</v-menu>
</v-col>
<v-col cols="12" sm="6" md="2">
<v-menu ref="menu" v-model="startTimeMenu" :close-on-content-click="false" :nudge-right="40" :return-value.sync="form.values.startTime" transition="scale-transition" offset-y max-width="290px" min-width="290px">
<template v-slot:activator="{ on, attrs }">
<v-text-field dense v-model="form.values.startTime" label="Start Time" append-icon="mdi-clock-time-four-outline" readonly v-bind="attrs" v-on="on" outlined></v-text-field>
</template>
<v-time-picker v-if="startTimeMenu" v-model="form.values.startTime" full-width #click:minute="$refs.menu.save(form.values.startTime)"></v-time-picker>
</v-menu>
</v-col>
</v-row>
<v-row>
<v-col cols="12" sm="6" md="2">
<v-menu v-model="endDateMenu" :close-on-content-click="false" :nudge-right="40" transition="scale-transition" offset-y min-width="auto">
<template v-slot:activator="{ on, attrs }">
<v-text-field dense outlined v-model="form.values.endDate" :rules="form.rules.endDate" :min="form.values.startDate" label="End Date" append-icon="mdi-calendar" readonly v-bind="attrs" v-on="on"></v-text-field>
</template>
<v-date-picker v-model="form.values.endDate"></v-date-picker>
</v-menu>
</v-col>
<v-col cols="12" sm="6" md="2">
<v-menu ref="menu" v-model="endTimeMenu" :close-on-content-click="false" :nudge-right="40" :return-value.sync="form.values.endTime" transition="scale-transition" offset-y max-width="290px" min-width="290px">
<template v-slot:activator="{ on, attrs }">
<v-text-field dense v-model="form.values.endTime" label="End Time" append-icon="mdi-clock-time-four-outline" readonly v-bind="attrs" v-on="on" outlined></v-text-field>
</template>
<v-time-picker v-if="endTimeMenu" v-model="form.values.endTime" :min="form.values.startTime" full-width #click:minute="$refs.menu.save(form.values.endTime)"></v-time-picker>
</v-menu>
</v-col>
</v-row>
</v-form>
</v-card>
<v-btn color="primary" #click="validate()" :disabled="!valid"> Continue </v-btn>
<router-link :to="`/${segment1}`">
<v-btn text> Cancel </v-btn>
</router-link>
</v-stepper-content>
<v-stepper-content step="2">
<v-card class="mb-12" elevation="0">
<v-form ref="form2" lazy-validation v-model="valid2" id="form2">
<v-row>
<v-card-text class="font-weight-bold">
Destination
<v-tooltip right>
<template v-slot:activator="{ on, attrs }">
<v-btn icon v-bind="attrs" v-on="on">
<v-icon color="grey lighten-1">info</v-icon>
</v-btn>
</template>
<span>The scan destination is the end point for a consumer experience. Can be single URL or use URL Groups. </span>
</v-tooltip>
</v-card-text>
</v-row>
<v-row>
<v-col class="col-sm-2 col-lg-2 col-12">
<v-select dense outlined :items="urlTypes" label="Single or Multi URL" v-model="form.values.urlType" :rules="form.rules.urlType"></v-select>
</v-col>
<v-col cols="12" sm="6" md="2">
<v-text-field dense outlined v-model="form.values.url" :rules="form.rules.url" label="URL" required></v-text-field>
</v-col>
</v-row>
<v-row>
<v-card-text class="font-weight-bold"
>Conditions :
<v-tooltip right>
<template v-slot:activator="{ on, attrs }">
<v-btn icon v-bind="attrs" v-on="on">
<v-icon color="grey lighten-1">info</v-icon>
</v-btn>
</template>
<span>Set the conditions for a campaign. If all conditions are true, this campaign will trigger for consumer experience.</span>
</v-tooltip>
</v-card-text>
<v-col cols="12" sm="6" md="4">
<v-select dense outlined :items="attributes" item-text="name" item-value="id" v-model="form.values.attribute" :rules="form.rules.attribute" label="Attribute"></v-select>
</v-col>
<v-col cols="12" sm="6" md="1">
<v-combobox v-model="operator" :items="operators" item-text="operator" item-value="id" label="Operator" outlined dense></v-combobox>
</v-col>
<v-col cols="12" sm="6" md="4">
<!-- <v-text-field dense outlined v-model="form.values.value" :rules="form.rules.value" label="Values" required></v-text-field> -->
<v-text-field v-model="value" :items="values" label="Value" multiple outlined dense></v-text-field>
</v-col>
</v-row>
</v-form>
</v-card>
<v-btn color="primary" #click="validate2()" :disabled="!valid2"> Update </v-btn>
<v-btn text #click="e1 = 1"> Back </v-btn>
</v-stepper-content>
<v-stepper-content step="3"> </v-stepper-content>
</v-stepper-items>
</v-stepper>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
import Navbar from '../../../components/Navbar'
import Breadcrumbs from '../../../components/Breadcrumbs'
import PanelHeader from '../../../components/PanelHeader'
import axios from 'axios'
import moment from 'moment-timezone'
export default {
components: {
Navbar,
Breadcrumbs,
PanelHeader
},
beforeMount() {},
computed: {
segment1: function () {
const firstSegment = new URL(window.location.href).pathname.split('/')[1]
return `${firstSegment}`
},
timeZone: function () {
console.log('timeZone')
}
},
beforeMount() {},
mounted() {
this.getCampaign()
},
data() {
return {
campaign: {},
form: {
errors: {},
values: {
name: this.campaign.name,
type: 'Marketing',
description: null,
timezone: 'America/New_York',
startDate: new Date(Date.now() - new Date().getTimezoneOffset() * 60000).toISOString().substr(0, 10),
endDate: new Date(Date.now() - new Date().getTimezoneOffset() * 60000).toISOString().substr(0, 10),
startTime: moment().format('HH:mm'),
endTime: '24:00',
urlType: 'Single',
url: 'https://',
attribute: '',
operator: '',
value: ''
},
rules: {
type: [(v) => !!v || 'Type is required'],
name: [(v) => !!v || 'Name is required'],
startDate: [(v) => !!v || 'Start Date is required'],
endDate: [(v) => !!v || 'End Date is required'],
timezone: [(v) => !!v || 'Timezone is required'],
startTime: [(v) => !!v || 'Start Time is required'],
endTime: [(v) => !!v || 'End Time is required'],
urlType: [(v) => !!v || 'URL Type is required'],
url: [(v) => !!v || 'URL is required'],
attribute: [(v) => !!v || 'Attribute is required'],
operator: [(v) => !!v || 'Operator is required'],
value: [(v) => !!v || 'Value is required']
}
},
e1: 1,
valid: false,
valid2: false,
types: ['Product', 'Marketing'],
operator: [],
operators: ['=', '!=', 'in', 'not in'],
value: [],
values: ['Italy', 'Finland', 'Norway'],
timezones: moment.tz.names(),
startDateMenu: false,
endDateMenu: false,
startTimeMenu: false,
endTimeMenu: false,
urlTypes: ['Single', 'Multiple'],
attributes: []
}
},
watch: {
'form.values.attribute'() {
this.operator = null
axios.defaults.headers['Content-Type'] = 'application/json'
let data = {
$root: 'vc_operator',
op: 'read',
brand: 'COLM',
selection: {
filters: [`id:${this.form.values.attribute}`]
},
_SESSION: localStorage.getItem('session')
}
axios.post(`${process.env.VUE_APP_API_ENDPOINT_URL}`, data).then((response) => {
this.operators = response.data.operators
})
}
},
methods: {
getAllData(id) {
let myForm = document.getElementById(id)
console.log(
Array.from(myForm.elements).map((e) => {
return e.value
})
)
},
validate() {
this.$refs.form.validate()
if (this.$refs.form.validate()) {
let data = {
$root: 'vc_rule_attribute',
op: 'read',
brand: 'COLM',
_SESSION: localStorage.getItem('session')
}
axios.defaults.headers['Content-Type'] = 'applcation/json'
axios.post(`${process.env.VUE_APP_API_ENDPOINT_URL}`, data).then((response) => {
this.attributes = response.data.rule_attributes
})
this.e1 = 2
console.info(this.form.values)
} else {
console.info(this.form.values)
}
},
validate2() {
this.$refs.form2.validate()
if (this.$refs.form2.validate()) {
let data = {
id: this.form.values.id,
name: this.form.values.name,
description: this.form.values.description,
start_date: this.form.values.startDate,
end_date: this.form.values.endDate,
priority: '100',
status_id: 1,
type_id: 1
}
let body = {
$root: 'vc_campaign',
op: 'update',
brand: 'COLM',
campaigns: [data],
_SESSION: localStorage.getItem('session')
}
// this.$store
// .dispatch('editCampaign', body)
// .then(() => {
// this.$router.push({
// path: `/campaigns`
// })
// })
// .catch((err) => {
// console.log('Something went wrong: ', err)
// })
} else {
console.info(this.form.values)
}
},
displayTime(time) {
time = time.split(':')[0]
if (time > 12) {
return 'PM'
} else {
return 'AM'
}
},
getCampaign() {
let filters = 'id:' + this.$route.params.id
let body = {
$root: 'vc_campaign',
op: 'read',
brand: 'COLM',
selection: {
filters: [filters]
},
_SESSION: localStorage.getItem('session')
}
axios.defaults.headers['Content-Type'] = 'applcation/json'
axios
.post(`${process.env.VUE_APP_API_ENDPOINT_URL}`, body)
.then((response) => {
if (response.data.status == 0) {
this.campaign = response.data.campaigns[0]
} else {
alert(response.data.statustext)
reject(response.data.statustext)
}
})
.catch((err) => {
console.log('Something went wrong: ', err)
})
}
}
}
</script>
<style></style>
You are basically trying to access a variable which is not defined yet. data() is called only once when you initialize the component. This happens way before you get the response from api and assign a value to this.campaign.
That's why this line doesn't work:
name: this.campaign.name
What you can do instead is something like this:
data() {
return {
campaign: {},
form: {
errors: {},
values: {
name: "",
...
getCampaign() {
...
axios.post(`${process.env.VUE_APP_API_ENDPOINT_URL}`, body)
.then((response) => {
if (response.data.status == 0) {
this.campaign = response.data.campaigns[0]
this.form.values.name = this.campaign.name
...
Keeping your requirements in mind, you can use watch property to keep both the values in sync
Set the initial form.values.name to ''
data() {
return {
campaign: {},
form: {
errors: {},
values: {
name: '',
...
and to keep the values in sync, you can do something like this:
watch: {
campaign: {
handler(newVal) {
this.form.values.name = newVal.name
},
immediate: true
}
}
Try
<p>Campaign Name : {{ campaign?.name }}</p>
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;
}
i have vuetify
<v-col cols="12" md="8">
<v-select :items="driverName" v-bind:id="editedItem.driverId" v-model="editedItem.score" label="score"></v-select>
</v-col>
and me need know resulr id v-bind:id="editedItem.driverId" in :items keep
<v-data-table
:headers="headers"
:items="desserts"
sort-by="calories"
class="elevation-1"
>
i get data with api in axios
here my code https://github.com/ivan556258/crm/blob/master/src/views/table/AppBillAll.vue
<v-col cols="12" md="8">
<v-select :items="drivers" item-value="_id" item-text="lastname" v-model="editedItem.score" label="Счёт">
</v-select>
</v-col>
console.log(this.editedItem.score); // here id