vue2 + element ui - how to setting dynamic v-model - vue.js

Let's make the string(categoryV3) an array with ','
and create array length.
and icon-add click add ..
but v-model not working.. and i don't know add .........
I am not good at speaking English.
Please give me your opinion.
<template>
<el-table
:data="tableData"
>
<el-table-column type="selection" width="55" align="center"> </el-table-column>
<el-table-column props="category" label="category" show-overflow-tooltip>
<template slot-scope="{row}">
<div v-for="(item, index) in generateArray(row.categoryV3)" :key="index">
<el-select class="filter-item select1" filterable v-model="item[index]" placeholder="-">
<el-option
v-for="item in options"
:key="item.value"
:label="`${item.value}. ${item.label}`"
:value="item.value"
/>
</el-select>
<span class="tmp-icon icon-add"><i class="el-icon-circle-plus-outline"></i></span>
<span class="tmp-icon icon-remove" v-show="generateArray(row.categoryV3).length > 1"
><i class="el-icon-remove-outline"></i
></span>
</div>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [{
categoryV3:"option1,option2"
}, {
categoryV3:""
}],
options: [{
value: 'Option1',
label: 'Option1'
}, {
value: 'Option2',
label: 'Option2'
}]
};
},
methods: {
generateArray(val) {
return val.split(',');
},
}
};
</script>

data add 'categoryV3: []'
<div v-for="(item, index) in categoryV3[scope.$index]" :key="index">
<el-select class="filter-item select1" filterable v-model="categoryV3[scope.$index][index]" placeholder="-">
<el-option
v-for="item in relationCode"
:key="item.code_value"
:label="`${item.code_value}. ${item.code_name}`"
:value="item.code_value"
/>
</el-select>
<span class="tmp-icon icon-add" #click="addModel(categoryV3[scope.$index], '')"
><i class="el-icon-circle-plus-outline"></i
></span>
<span
class="tmp-icon icon-remove"
#click="removeModel(categoryV3[scope.$index], index)"
v-show="categoryV3[scope.$index].length > 1"
><i class="el-icon-remove-outline"></i
></span>
</div>

Related

How do I make dynamic routing work in Vue?

I got a project and when I use :to, my dynamic routes dont work..I also can't seem to pass params. The buttons supposed to be used as dynamic routes are declared in the v-for loop. I am using Quasar CLI / Vue3.
It'd be really awesome if some of you had an insight as to why this does not work. I get no errors, simply, when I hover over the button it shows no url as it normally would in a browser.
The view displaying items:
<template>
<div class="projects">
<div class="text-h3 project-title">
Favourite Projects <q-icon name="star" color="yellow" />
</div>
</div>
<div class="project-container">
<div class="q-pa-md project-card">
<q-card class="my-card single-projects no-shadow no-border-radius">
<q-img
src="https://res.cloudinary.com/practicaldev/image/fetch/s--9yBkqrjS--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nphrgz8yfnjylrwfr0yl.png"
>
<div class="absolute-bottom">
<div class="text-h6">
Damn good project
<q-icon name="star" color="yellow" />
</div>
<div class="text-subtitle2">by Big Boi</div>
</div>
</q-img>
<q-card-actions class="project-btns">
<q-btn
unelevated
size="md"
class="open-btn no-border-radius dropdown-btn"
>Open</q-btn
>
<q-btn
flat
no-caps
unelevated
size="md"
class="delete-btn no-border-radius"
color="red"
#click="confirm = true"
>Delete</q-btn
>
<q-dialog v-model="confirm" persistent class="dialog no-shadow">
<q-card>
<q-card-section class="row items-center">
<span class="q-ml-sm"
>Are you sure you want to delete this project?</span
>
</q-card-section>
<q-card-actions align="center">
<q-btn
flat
no-caps
label="Cancel"
color="black"
class="no-border-radius"
v-close-popup
/>
<q-btn
flat
no-caps
label="Delete"
color="red"
class="no-border-radius"
v-close-popup
/>
</q-card-actions>
</q-card>
</q-dialog>
</q-card-actions>
</q-card>
</div>
</div>
<div class="projects">
<div class="text-h3 project-title">All Projects</div>
</div>
<div v-for="item in items" :key="item.project" class="project-container">
<div class="q-pa-md project-card">
<q-card class="my-card single-projects no-shadow no-border-radius">
<q-img
src="https://res.cloudinary.com/practicaldev/image/fetch/s--9yBkqrjS--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nphrgz8yfnjylrwfr0yl.png"
>
<div class="absolute-bottom">
<div class="text-h6">{{ item.project }}</div>
<div class="text-subtitle2">by {{ item.author }}</div>
</div>
</q-img>
<q-card-actions class="project-btns">
<q-btn
:to="{
name: 'project',
params: {
project: item.project,
},
}"
unelevated
size="md"
class="open-btn no-border-radius dropdown-btn"
>Open
</q-btn>
<q-btn
flat
no-caps
unelevated
size="md"
class="delete-btn no-border-radius"
color="red"
#click="confirm = true"
>Delete</q-btn
>
<q-dialog v-model="confirm" persistent class="dialog no-shadow">
<q-card>
<q-card-section class="row items-center">
<span class="q-ml-sm"
>Are you sure you want to delete this project?</span
>
</q-card-section>
<q-card-actions align="center">
<q-btn
flat
no-caps
label="Cancel"
color="black"
class="no-border-radius"
v-close-popup
/>
<q-btn
flat
no-caps
label="Delete"
color="red"
class="no-border-radius"
v-close-popup
/>
</q-card-actions>
</q-card>
</q-dialog>
</q-card-actions>
</q-card>
</div>
</div>
</template>
<script lang="ts">
import { ref } from 'vue';
export default {
name: 'myProjects',
setup() {
return {
confirm: ref(false),
items: [
{ project: 'good project', id: '302a49g8Aa43', author: 'Josh' },
{ project: 'okay fine', id: '65at9g847a11', author: 'Tray' },
{ project: 'let me see', id: '538s3fg4782f', author: 'Martin' },
],
};
},
};
</script>
This is also my router where I do the routing:
{
path: '/project/:id',
props: true,
component: () => import('layouts/SingleProLayout.vue'),
children: [{ path: '', component: () => import('pages/Project.vue') }],
},
Try wrapping the q-btn inside a router-link https://router.vuejs.org/api/

how to display data from props in b-table template tag?

i am new in vue.js and get some problem while displaying data in b-table. my data from database is fetched properly. and i passed from one file to products.vue and received data in products.vue as props. when i console my data is showing in console properly, but when i used to display data in b-table, i got some problem. data is not displaying correctly.
please let me know where is mistake in my code?
Products.vue (script tag)
<script>
export default {
props: ['category','singular', 'plural','products'],
data() {
return {
title: `All ${this.plural}`,
items: [],
editing: false,
weight_assignment: false,
model: null,
formTitle: '',
fields: [
{
key: 'index',
label: 'S.No.'
},
{
key: 'name',
sortable: true
},
{
key: 'weights'
},
{
key: 'default_weight',
sortable: true
},
{
key: 'status',
sortable: true
},
{
key: 'action'
}
],
}
</script>
Product.vue (template tag)
<template>
<div class="row">
</div>
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">{{title}}</h3>
<div class="card-tools">
<b-button variant="primary" #click="newItem">New {{singular}}</b-button>
<div></div>
</div>
</div>
<div class="card-body table-responsive p-0">
<spinner v-if="$root.loading"></spinner>
<b-table ref="table" v-for="type in this.products" :items="type" :key="type.id" :fields="fields" bordered hover :head-variant="'light'" responsive="sm" v-else>
<template v-slot:cell(index)="type">
{{ type.index + 1 }}
</template>
<template v-slot:cell(name)="type">
<b-img thumbnail fluid :src="getImageUrl(type.image)" alt="Image 1" class="thumb-img"></b-img>
{{type.name}}
</template>
<template v-slot:cell(weights)="type">
<span v-weights="type.item"></span>
</template>
<template v-slot:cell(default_weight)="type">
<span v-floatFormatter="type.default_weight"></span>{{type.unit.sname}}
</template>
<template v-slot:cell(status)="type">
<span v-if="type.status" class="text-success text-bold">Active</span>
<span class="text-danger" v-else>Inactive</span>
</template>
<template v-slot:cell(action)="data">
<a #click.prevent="editItem(data.index)"><i class="fa fa-edit" aria-hidden="true" title="Update product" v-b-tooltip.hover></i></a>
<a #click.prevent="assignWeights(data.index)"><i class="fa fa-balance-scale" title="Assign weights" aria-hidden="true" v-b-tooltip.hover></i></a>
</template>
</b-table>
</div>
</div>
</div>
</div>
</template>
v-for="type in this.products" - try to delete this key. In template tag do not use this keyword to access data or any other values.
I have spotted you pass data completely wrong way. Please use below variant and tell me if it work.
EDITED template:
<template>
<div class="row">
</div>
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">{{title}}</h3>
<div class="card-tools">
<b-button variant="primary" #click="newItem">New {{singular}}</b-button>
<div></div>
</div>
</div>
<div class="card-body table-responsive p-0">
<spinner v-if="$root.loading"></spinner>
<b-table ref="table" :items="products" :fields="fields" bordered hover :head-variant="'light'" responsive="sm" v-else>
<template v-slot:cell(index)="data">
{{ data.index + 1 }}
</template>
<template v-slot:cell(name)="data">
<b-img thumbnail fluid :src="getImageUrl(data.image)" alt="Image 1" class="thumb-img"></b-img>
{{data.name}}
</template>
<template v-slot:cell(weights)="data">
<span v-weights="data.item"></span>
</template>
<template v-slot:cell(default_weight)="data">
<span v-floatFormatter="data.default_weight"></span>{{data.unit.sname}}
</template>
<template v-slot:cell(status)="data">
<span v-if="data.status" class="text-success text-bold">Active</span>
<span class="text-danger" v-else>Inactive</span>
</template>
<template v-slot:cell(action)="data">
<a #click.prevent="editItem(data.index)"><i class="fa fa-edit" aria-hidden="true" title="Update product" v-b-tooltip.hover></i></a>
<a #click.prevent="assignWeights(data.index)"><i class="fa fa-balance-scale" title="Assign weights" aria-hidden="true" v-b-tooltip.hover></i></a>
</template>
</b-table>
</div>
</div>
</div>
</template>
I tried a lot, after all this, my code is working correctly now, this given below code is the right solution.
<b-table ref="table" :items="products" :fields="fields" bordered hover :head-variant="'light'" responsive="sm" v-else>
<template v-slot:cell(index)="data">
{{ data.index+1 }}
</template>
<template v-slot:cell(name)="data">
<b-img thumbnail fluid :src="getImageUrl(data.item.image)" alt="Image 1" class="thumb-img"></b-img>
{{data.item.name}}
</template>
<template v-slot:cell(weights)="data">
<span v-weights="data.item"></span>
</template>
<template v-slot:cell(default_weight)="data">
<span v-floatFormatter="data.item.default_weight"></span>{{data.item.unit.sname}}
</template>
<template v-slot:cell(status)="data">
<span v-if="data.status" class="text-success text-bold">Active</span>
<span class="text-danger" v-else>Inactive</span>
</template>
<template v-slot:cell(action)="data">
<a #click.prevent="editItem(data.item.id)"><i class="fa fa-edit" aria-hidden="true" title="Update product" v-b-tooltip.hover></i></a>
<a #click.prevent="assignWeights(data.item.id)"><i class="fa fa-balance-scale" title="Assign weights" aria-hidden="true" v-b-tooltip.hover></i></a>
</template>
</b-table>

Accessing Vuex data within dynamic _id.vue page - Vue/Nuxt

I want to access my user details stored in the state when visiting a dynamic (_id.vue) page. I have set the id of the page like this after using the link to the page:
data() {
return {
selectedTutor: null,
id: this.$route.params.id,
}
},
But now I need to define the selectedTutor by searching the id within the data in the vuex state. I was trying to do something like this:
created() {
this.selectedTutor = this.$store.state.tutors.find((tutor) => tutor.id === this.id)
},
But everything stays undefined. So when id equals to the id within the object, that object needs to be set as selectedTutor so I can access all the necessary data to be displayed on the page.
Here you can see the Vuex state
EDIT
_id.vue page
<template>
<div>
<section>
<div>
<h3>
{{ id }}
</h3>
</div>
</section>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'TutorPage',
/* eslint-disable vue/require-prop-types */
layout: 'app',
props: ['id'],
middleware: 'auth',
data() {
return {
selectedTutor: null,
}
},
computed: {
...mapState(['tutors']),
},
created() {
this.selectedTutor = this.$store.state.tutors.find(
(tutor) => tutor.id === this.id
)
},
}
</script>
MainResult Page
<base-grid>
<ul id="tutors" class="grid grid-cols-2 gap-6">
<tutor-item
v-for="tutor in tutors"
:id="tutor.id"
:key="tutor.id"
:name="tutor.attributes.name"
:rate="student.hourlyRate"
:subject="student.subject"
:description="student.biography"
:profile-image="student.imageUrl"
:image-alt="student.imageAlt"
:age="student.age"
:rating="student.rating"
:total-reviews="student.reviewCount"
class="overflow-hidden bg-white border rounded-lg shadow-md"
>
</tutor-item>
</ul>
</base-grid>
Tutor Item (the resultcard)
<template>
<div>
<li>
<div class="flex">
<div class="w-2/3">
<img
class="flex-shrink-0 object-cover w-full h-64 mx-auto bg-gray-200"
:src="profileImage"
:alt="imageAlt"
/>
</div>
<div class="p-6">
<div
class="text-xs font-semibold leading-snug tracking-wide text-gray-500 uppercase"
>
{{ subject }} • {{ age }} jaar
</div>
<NuxtLink :to="'/tutors/' + id">
<h4 class="text-lg font-semibold leading-5 tracking-wide">
{{ name }}
</h4>
</NuxtLink>
<div class="mt-2">
{{ rate }}€
<span class="text-sm text-gray-600">per uur</span>
</div>
<div class="mt-2">
<span class="font-semibold text-light-blue-800"
>{{ rating }}/5 sterren</span
>
<span class="text-sm text-gray-600 truncate">
(na {{ totalReviews }} reviews)
</span>
</div>
<div class="mt-2">{{ description }}</div>
<div>
<div class="mt-4 text-sm font-semibold text-gray-600">
<span>MA</span>
<span
class="inline-block leading-7 text-center text-gray-100 bg-yellow-400 bg-opacity-50 w-7 h-7 rounded-xl"
>DI</span
>
<span>WO</span>
<span
class="inline-block leading-7 text-center text-gray-100 bg-yellow-400 bg-opacity-50 w-7 h-7 rounded-xl"
>DO</span
>
<span
class="inline-block leading-7 text-center text-gray-100 bg-yellow-400 bg-opacity-50 w-7 h-7 rounded-xl"
>VR</span
>
<span>ZA</span>
<span>ZO</span>
</div>
</div>
</div>
</div>
</li>
</div>
</template>
<script>
export default {
/* eslint-disable vue/require-prop-types */
name: 'TutorItem',
props: [
'id',
'firstName',
'lastName',
'name',
'rate',
'subject',
'age',
'rating',
'totalReviews',
'description',
'profileImage',
'imageAlt',
],
computed: {
fullName() {
return this.firstName + ' ' + this.lastName
},
tutorsDetailsLink() {
return this.$route.path + '/' + this.id
},
},
}
</script>
<style></style>
EDIT
Whoops, what a mistake. It was returning the id as a string but I needed a number. This is why it returned undefined. It is solved now! Thanks

bootstrap-vue using colgroup to group the column with column header

I have to create the table as in the design shown below in the figure, using Bootstrap Vue.
Here the Male and Female is grouped by respective section, this can be done using the simple <td> and <col-group>,
there is the slot table-colgroup in bootstrap-vue documentation, but i did not found the way to use in this scenario.
I have implemented the table in the code snippets below:
Vue.config.productionTip = false
Vue.component('icons', {
template: '<a><slot></slot></a>'
})
new Vue({
el: '#app',
methods: {
addService() {
this.model.services.push({});
}
},
computed: {
sec_a_male: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_a_male) || 0)
}, 0)
},
sec_a_female: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_a_female) || 0)
}, 0)
},
sec_b_male: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_b_male) || 0)
}, 0)
},
sec_b_female: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_b_female) || 0)
}, 0)
}
},
data: {
model: {
services: []
},
fields: [{
key: "class",
label: "Class"
},
{
key: "section_a_male",
label: "Male"
},
{
key: "section_a_female",
label: "Female"
},
{
key: "section_b_male",
label: "Male"
},
{
key: "section_b_female",
label: "Male"
}
]
}
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.css" />
<script src="https://unpkg.com/vue"></script>
<script src="//unpkg.com/babel-polyfill#latest/dist/polyfill.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.js"></script>
<div id="app">
<b-card header-tag="header" footer-tag="footer">
<template slot="header" class="mb-0">
<button type="button" class="btn btn-primary btn-sm" #click.prevent="addService">
<icons :icon="['fas', 'plus']" /> Add Items/Service</button>
</template>
<b-card-body>
<b-table responsive bordered striped hover caption-top :fields="fields" :items="model.services" caption-top>
<template slot="top-row" slot-scope="data">
<td rowspan="1"></td>
<th colspan="2" scope="colgroup">Section A</th>
<th colspan="2" scope="colgroup">Section B</th>
</template>
<template slot="class" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.class" :name="`class_${data.index}`" type="text" />
</template>
<template slot="section_a_male" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_a_male" :name="`section_a_male_${data.index}`" type="text" />
</template>
<template slot="section_a_female" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_a_female" :name="`section_a_female_${data.index}`" type="text" />
</template>
<template slot="section_b_male" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_b_male" :name="`section_b_male_${data.index}`" type="text" />
</template>
<template slot="section_b_female" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_b_female" :name="`section_b_female_${data.index}`" type="text" />
</template>
<template slot="bottom-row" slot-scope="data">
<td>Total</td>
<td>{{sec_a_male}}</td>
<td>{{sec_a_female}}</td>
<td>{{sec_b_male}}</td>
<td>{{sec_b_female}}</td>
</template>
<template slot="table-colgroup">
<col>
<col span="2">
<col span="2">
</template>
</b-table>
</b-card-body>
</b-card>
</div>
Expected Output:
Please help!
This might get you started. You can add a class bg-danger to your td elements, and you can add variants/classes to your fields array.
Vue.config.productionTip = false
Vue.component('icons', {
template: '<a><slot></slot></a>'
})
new Vue({
el: '#app',
methods: {
addService() {
this.model.services.push({});
}
},
computed: {
sec_a_male: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_a_male) || 0)
}, 0)
},
sec_a_female: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_a_female) || 0)
}, 0)
},
sec_b_male: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_b_male) || 0)
}, 0)
},
sec_b_female: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_b_female) || 0)
}, 0)
}
},
data: {
model: {
services: []
},
fields: [{
key: "class",
label: "Class"
},
{
key: "section_a_male",
label: "Male",
variant: 'danger'
},
{
key: "section_a_female",
label: "Female",
variant: 'danger'
},
{
key: "section_b_male",
label: "Male",
variant: 'warning'
},
{
key: "section_b_female",
label: "Male",
variant: 'warning'
}
]
}
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.css" />
<script src="https://unpkg.com/vue"></script>
<script src="//unpkg.com/babel-polyfill#latest/dist/polyfill.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.js"></script>
<div id="app">
<b-card header-tag="header" footer-tag="footer">
<template slot="header" class="mb-0">
<button type="button" class="btn btn-primary btn-sm" #click.prevent="addService">
<icons :icon="['fas', 'plus']" /> Add Items/Service</button>
</template>
<b-card-body>
<b-table responsive bordered hover caption-top :fields="fields" :items="model.services" foot-clone>
<template slot="class" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.class" :name="`class_${data.index}`" type="text" />
</template>
<template slot="section_a_male" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_a_male" :name="`section_a_male_${data.index}`" type="text" />
</template>
<template slot="section_a_female" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_a_female" :name="`section_a_female_${data.index}`" type="text" />
</template>
<template slot="section_b_male" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_b_male" :name="`section_b_male_${data.index}`" type="text" />
</template>
<template slot="section_b_female" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_b_female" :name="`section_b_female_${data.index}`" type="text" />
</template>
<template slot="bottom-row" slot-scope="data">
<td>Total</td>
<td class="bg-danger">{{sec_a_male}}</td>
<td class="bg-danger">{{sec_a_female}}</td>
<td class="bg-warning">{{sec_b_male}}</td>
<td class="bg-warning">{{sec_b_female}}</td>
</template>
</b-table>
</b-card-body>
</b-card>
</div>
This hasn't been on the boostrap-vue before, new changes has just been published on current version of boostrap-vue v2.0.0-rc.14, which support for the header row.
<b-table responsive bordered striped hover caption-top :fields="fields" :items="model.services" caption-top>
<template slot="thead-top" slot-scope="{}">
<tr>
<th></th>
<th class="text-center" colspan="2">Section A</th>
<th class="text-center" colspan="2">Section B</th>
</tr>
</template>
</b-table>
This can be done by using thead-top slot, further explained here
https://bootstrap-vue.js.org/docs/components/table#adding-additional-rows-to-the-header
This might give the alternate case:
<b-table class ="table" :fields="fields" :items="items">
<template slot="bottom-row" slot-scope="{}">
<th colspan="5" class="text-center">No Data</th>
</template>
</b-table>
get header table from :fields
default row in bottom with text "No Data" align center. Post condition :items is null.
Check table output below:

VueJS aligning recursive component

I've built a recursive component that is doing what I want. However, I'm struggling to figure out how to programmatically keep the elements in align:
Here is the component in it's entirety:
<template>
<div class="row-creator" ref="row">
<div v-for="(item, index) in row" :key="index" :style="[indent, newWidth]">
<div v-if="typeof(item) === 'string'">
<v-multi-select
:value="properties.filter((prop) => { return prop.target === item; })"
class="mb-3"
track-by="target"
label="target"
placeholder="Choose an attribute"
:options="properties"
:searchable="false"
:allow-empty="false"
:show-labels="false">
<template slot="singleLabel" slot-scope="{ option }"></template>
</v-multi-select>
<i class="fa fa-minus-circle"></i>
<i class="pl-2 fa fa-plus-circle" id="addBtn"></i>
<b-popover target="addBtn" placement="bottomleft" triggers="click">
<b-list-group class="list-group">
<b-list-group-item button><i class="fa fa-plus fa-2x pr-2"></i> Add a field</b-list-group-item>
<b-list-group-item button><i class="fa fa-plus fa-2x pr-2"></i> Add a group</b-list-group-item>
</b-list-group>
</b-popover>
</div>
<div v-else>
<v-multi-select
:value="options[0].key === Object.keys(item)[0] ? options[0] : options[1]"
class="mb-3"
track-by="key"
label="text"
:options="options"
:searchable="false"
:allow-empty="false"
:show-labels="false">
</v-multi-select>
<i class="fa fa-minus-circle"></i>
<i class="pl-2 fa fa-plus-circle" id="addBtn"></i>
<b-popover target="addBtn" placement="bottomleft" triggers="click">
<b-list-group class="list-group">
<b-list-group-item button><i class="fa fa-plus fa-2x pr-2"></i> Add a field</b-list-group-item>
<b-list-group-item button><i class="fa fa-plus fa-2x pr-2"></i> Add a group</b-list-group-item>
</b-list-group>
</b-popover>
<row-creator
:row="item[Object.keys(item)[0]]"
:properties="properties"
:options="options"
:depth="depth + 1">
</row-creator>
</div>
</div>
</div>
</template>
<script>
import vMultiselect from 'vue-multiselect';
export default {
props: [ 'row', 'properties', 'options', 'depth' ],
name: 'row-creator',
components: {
'v-multi-select': vMultiselect
},
computed: {
indent () {
return { transform: `translate(${this.depth * 20}px)` };
},
newWidth () {
// return { width: this.$refs.row.clientWidth - this.depth * 20 + 'px' };
}
}
};
</script>
How can create a computed property to adjust the width of the various rows? This form represents an object. What is the best way to keep the data object in sync? Can I use v-model?
Don't use css transform for this. Use margin-left instead!