How to fill object with the selected value of dropdown in Vue - vue.js

I have a dropdown as you see in the picture:
The value of this dropdown is coming from the fetched data:
"data": {
"type": "products",
"id": "2021-01-04.1.1",
"attributes": {
"name": "product 1",
"descriptions": "some description",
"image": null,
"date": "2021-01-04",
"valid_from": null,
"valig_untill": null,
"xparc_paid_product_id": 1,
"xparc_unpaid_product_id": 1,
"xparc_access_id": 1,
"stock": null,
"variations": [
{
"id": 1,
"product_template_id": "1",
"name": "child ticket",
"description": "Only for children!",
"price_excl_vat": 1,
"created_at": "2021-09-15T13:16:00.000000Z",
"updated_at": "2021-09-15T13:16:00.000000Z"
},
{
"id": 2,
"product_template_id": "1",
"name": "Adults",
"description": "Not for children!",
"price_excl_vat": 2,
"created_at": "2021-09-15T13:16:10.000000Z",
"updated_at": "2021-09-15T13:16:10.000000Z"
},
{
"id": 3,
"product_template_id": "1",
"name": "Test",
"description": "Test",
"price_excl_vat": 10,
"created_at": "2021-09-30T11:29:44.000000Z",
"updated_at": "2021-09-30T11:29:44.000000Z"
}
]
},
As you see I am displaying variations of this object into my dropdown. What I am trying to achieve is according to the selected value I want to put some info into object (for example this
info: {
"id": 1,
"product_template_id": "1",
"name": "child ticket",
"description": "Only for children!",
"price_excl_vat": 1,
"created_at": "2021-09-15T13:16:00.000000Z",
"updated_at": "2021-09-15T13:16:00.000000Z"
},
)
For this I have a `dropdown component:
<template>
<div class="custom-select" :tabindex="tabindex" #blur="open = false">
<div class="selected" :class="{ open: open }" #click="open = !open">
{{ selected.name }}
</div>
<div class="items" :class="{ selectHide: !open }">
<div
v-for="(option, i) of options"
:key="i"
#click="
selected = option;
open = false;
$emit('input', option);
"
>
{{ option.name }}
</div>
</div>
</div>
</template>
<script>
export default {
props: {
options: {
type: Array,
required: true,
},
default: {
type: String,
required: false,
default: null,
},
tabindex: {
type: Number,
required: false,
default: 0,
},
},
data() {
return {
selected: this.default
? this.default
: this.options.length > 0
? this.options[0]
: null,
open: false,
sel: '',
};
},
mounted() {
this.$emit("input", this.selected);
},
computed: {
variations() {
return this.data.attributes.variations
}
},
methods: {
getSelected(opt) {
this.sel = opt.description
}
}
};
</script>
And a parent of this component, I am trying to fill the object:
<Dropdown
:options="getVariations"
:default="'Choose an option'"
class="select"
#input="getSelected"
/>
<script>
data() {
return {
selectedObject: "",
};
},
computed: {
getVariations() {
return this.product.attributes.variations;
},
getSelected(opt) {
this.selectedObject= opt;
}
},
</script>
But unfortunately, I am not getting anything from selectedObject. Could you please have a look?
Thanks...

You emit selected item data from dropdown component, so set your object in method:
getSelected(opt) {
this.selectedObject = opt
Vue.component('Dropdown', {
template: `
<div class="custom-select" :tabindex="tabindex" #blur="open = false">
<div class="selected" :class="{ open: open }" #click="open = !open">
{{ selected.name }}
</div>
<p>Description child :{{ selected.description }}</p>
<div class="items" :class="{ selectHide: !open }">
<div
v-for="(option, i) of options"
:key="i"
#click="
selected = option;
open = false;
$emit('input', option);
"
>
{{ option.name }}
</div>
</div>
</div>
`,
props: {
options: {
type: Array,
required: true,
},
default: {
type: String,
required: false,
default: null,
},
tabindex: {
type: Number,
required: false,
default: 0,
},
},
data() {
return {
selected: this.default
? this.default
: this.options.length > 0
? this.options[0]
: null,
open: false,
};
},
mounted() {
this.$emit("input", this.selected);
},
})
new Vue({
el: '#demo',
data(){
return {
"data":
{
"type": "products",
"id": "2021-01-04.1.1",
"attributes": {
"name": "product 1",
"descriptions": "some description",
"image": null,
"date": "2021-01-04",
"valid_from": null,
"valig_untill": null,
"xparc_paid_product_id": 1,
"xparc_unpaid_product_id": 1,
"xparc_access_id": 1,
"stock": null,
"variations": [
{
"id": 1,
"product_template_id": "1",
"name": "child ticket",
"description": "Only for children!",
"price_excl_vat": 1,
"created_at": "2021-09-15T13:16:00.000000Z",
"updated_at": "2021-09-15T13:16:00.000000Z"
},
{
"id": 2,
"product_template_id": "1",
"name": "Adults",
"description": "Not for children!",
"price_excl_vat": 2,
"created_at": "2021-09-15T13:16:10.000000Z",
"updated_at": "2021-09-15T13:16:10.000000Z"
},
{
"id": 3,
"product_template_id": "1",
"name": "Test",
"description": "Test",
"price_excl_vat": 10,
"created_at": "2021-09-30T11:29:44.000000Z",
"updated_at": "2021-09-30T11:29:44.000000Z"
}
]
},
},
sel: '',
selectedObject: null
}
},
computed: {
variations() {
return this.data.attributes.variations
}
},
methods: {
getSelected(opt) {
this.selectedObject = opt
this.sel = opt.description
}
}
})
Vue.config.productionTip = false
Vue.config.devtools = false
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<h3>selected object</h3>
<p>{{ selectedObject }}</p>
<Dropdown
:options="variations"
:default="'Choose an option'"
class="select"
#input="getSelected"
/>
</div>

Related

Why is v-for can't show the value with computed

This is for select a city and area, It will filter the same data to show it. But I meet with a problem is that when I selected, the value doesn't appear.
I have been try and searched similar code but still doesn't find the solution.
This is the image when of HTML rendering :
Here is template :
<a href="#" class="list-group-item" v-for="(live , idx) of filterLivingNames" :key="idx">
<h3 class="text-center">{{live.Name}}</h3>
<p>Address:</p>
<p>Phone:</p>
</a>
Here is script
import LivingData from '#/assets/LivingData.json';
export default {
computed: {
livedata(){
return LivingData;
},
filterLivingNames(){
let livelength = this.livedata.length
for(let i = 0 ; i < livelength ; i++){
if(this.livedata[i].Region === this.city && this.livedata[i].Town === this.area){
console.log(this.livedata[i])
return this.livedata[i]
}
else{
continue
}
}
}
}
}
Update json file
[
{
"Id": "1",
"Name": "Hotel-1",
"Region": "Region-1",
"Town": "Town-1",
},
{
"Id": "2",
"Name": "Hotel-2",
"Region": "Region-2",
"Town": "Town-2",
},
{
"Id": "3",
"Name": "Hotel-3",
"Region": "Region-2",
"Town": "Town-1",
},
{
"Id": "4",
"Name": "Hotel-4",
"Region": "Region-1",
"Town": "Town-2",
},
]
As you are filtering out the livedata based on Region and Town. You can simply use the Array.filter() method and this will resolve the issue you are facing as it will return the array.
Live Demo :
new Vue({
el: '#app',
data: {
livedata: [
{
"Id": "1",
"Name": "Hotel-1",
"Region": "Region-1",
"Town": "Town-1",
},
{
"Id": "2",
"Name": "Hotel-2",
"Region": "Region-2",
"Town": "Town-2",
},
{
"Id": "3",
"Name": "Hotel-3",
"Region": "Region-2",
"Town": "Town-1",
},
{
"Id": "4",
"Name": "Hotel-4",
"Region": "Region-1",
"Town": "Town-2",
}
],
city: 'Region-1',
area: 'Town-1'
},
computed: {
filterLivingNames() {
return this.livedata.filter(obj => obj.Region === this.city && obj.Town === this.area)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<a href="#" class="list-group-item" v-for="(livingData, index) of filterLivingNames" :key="index">
<h3 class="text-center">{{ livingData.Name }}</h3>
<p>Address:</p>
<p>Phone:</p>
</a>
</div>

Vue country and state selection with select2

I want to list the states of the country in 2nd selection (JSON) format when country is selected in 1 selection I want to make with vuejs. I can do this with normal select but I want to do it in "select2" action. I have not seen or encountered an example of it anywhere.
For example, when France is chosen as the country. in the second option i want the states of france to be listed
Please answer considering that you are a beginner when writing an answer.
select2 or vue-select
[
{
"country": "America",
"plate": 1
},
{
"country": "France",
"plate": 2
},
{
"country": "Holland",
"plate": 3
},
{
"country": "China",
"plate": 4
},
{
"country": "state",
"plate": 5
}
]
[
{
"id": 1,
"country": "America",
"state": "Texas"
},
{
"id": 2,
"country": "America",
"state": "NewMexico"
},
{
"id": 3,
"country": "America",
"state": "Montana"
},
{
"id": 4,
"country": "France",
"state": "Normandy"
},
{
"id": 5,
"country": "France",
"state": "Paris"
},
{
"id": 6,
"country": "France",
"state": "Occitanie"
},
{
"id": 7,
"country": "Holland",
"state": "Köln"
},
{
"id": 8,
"country": "Holland",
"state": "Brüksel"
},
{
"id": 9,
"country": "China",
"state": "Gansu"
},
{
"id": 10,
"country": "China",
"state": "Hubei"
},
{
"id": 11,
"country": "China",
"state": "Hainan"
},
{
"id": 12,
"country": "Iraq",
"state": "Erbil"
},
{
"id": 13,
"country": "Iraq",
"state": "Bagdat"
}
]
<template>
<div class="container">
<div class="row">
<div class="col-md-4">
<label class="my-1 mr-2">countries</label>
<select class="custom-select my-1 mr-sm-2 form-control" v-model="selected" #change="getState()">
<option v-if="selected === 'Choose'">Choose</option>
<option v-for="item in countries" v-bind:key="item.id">{{ item.country}}
</option>
</select>
</div>
<div class="col-md-4 ">
<label class="my-1 mr-2">state</label>
<select class="custom-select my-1 mr-sm-2 form-control">
<option v-if="selectedCountry === false">Choose</option>
<option v-for="list in states" v-bind:key="id">{{ list.state}}</option>
</select>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
selected: 'Choose',
countries: {},
states: [],
selectedCountry: false,
}
},
created() {
this.getCounty()
},
methods: {
getCounty() {
axios.get('json/country.json')
.then(res => this.countries = res.data)
},
getState() {
this.selectedCountry = true
this.states = []
axios.get('json/states.json')
.then(res => {
res.data.forEach(i => {
if (this.selected === i.country) {
this.states.push(i.state)
}
})
})
}
}
}
</script>
You can prepare data and use vue-multiselect :
Vue.config.productionTip = false
new Vue({
el: '#demo',
components: { Multiselect: window.VueMultiselect.default },
data() {
return {
options: [
{"id": 1,"country": "America", "plate": 1}, {"id": 2,"country": "France","plate": 2},
{"id": 3,"country": "Holland","plate": 3}, {"id": 4,"country": "China","plate": 4},
{"id": 5,"country": "state","plate": 5}
],
states: [
{"id": 1,"country": "America","state": "Texas"},
{"id": 2,"country": "America","state": "NewMexico"},
{"id": 3,"country": "America","state": "Montana"},
{"id": 4,"country": "France","state": "Normandy"},
{"id": 5,"country": "France","state": "Paris"},
{"id": 6,"country": "France", "state": "Occitanie" },
{"id": 7,"country": "Holland","state": "Köln"},
{"id": 8,"country": "Holland","state": "Brüksel"},
{"id": 9,"country": "China","state": "Gansu"},
{"id": 10,"country": "China","state": "Hubei"},
{"id": 11,"country": "China","state": "Hainan"},
{"id": 12,"country": "Iraq","state": "Erbil"},
{"id": 13,"country": "Iraq","state": "Bagdat"}
],
value: '',
statesSel: [],
selectedCountry: '',
}
},
methods: {
getCounty() {
//axios.get('json/country.json')
//.then(res => this.countries = res.data)
},
getStates() {
//axios.get('json/states.json')
//.then(res => {this.states.push(i.state)
},
updateSelected: function(newValue) {
this.selectedCountry = '';
this.statesSel = this.states.filter(s => s.country === newValue.country)
}
},
created() {
this.getCounty()
this.getStates()
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
<link rel="stylesheet" href="https://unpkg.com/vue-multiselect#2.1.0/dist/vue-multiselect.min.css">
<script src="https://unpkg.com/vue-multiselect#2.1.0"></script>
<div id="demo">
<div class="row">
<div class="col-md-4 col-md-ofset-2 form-group">
<label class="typo__label">Select with search</label>
<multiselect v-model="value" placeholder="İl" :multiple="false" :options="options" label="country" track-by="country" :allow-empty="false" #select="updateSelected">
</multiselect>
</div>
<div class="col-md-4 col-md-ofset-2 form-group">
<label class="typo__label">Select with search</label>
<multiselect v-model="selectedCountry" placeholder="İlçe" :multiple="false" :options="statesSel" label="state" track-by="state" :allow-empty="false">
</multiselect>
</div>
</div>
</div>

Vuetify - custom rule on v-text-field returns first element as undefined

I used this rule to calculate the minimum purchase quantity and as long as this is not reached the form cannot be sent. The calculation itself works, but the first element is always "undefined".
Because the first element is "undefined", the number in the function getSizesQuantity is not correct if the value of the input field is 0.
What could be the reason for this?
product.json
{
"sku": "12345",
"name": "Product Name",
"variants": [
{
"color": "White",
"sku": "246420009",
"colorimage": "path/to/image",
"sizes": [
{
"size": "XS",
"sku": "246420002"
},
{
"size": "S",
"sku": "246420003"
},
{
"size": "M",
"sku": "246420004"
},
{
"size": "L",
"sku": "246420005"
},
{
"size": "XL",
"sku": "246420006"
},
{
"size": "2XL",
"sku": "246420007"
},
{
"size": "3XL",
"sku": "246420008"
},
{
"size": "4XL",
"sku": "246420009"
}
],
"images": [
{
"look": "front",
"packshot": "path/to/image"
}
]
}
]
}
<v-form
ref="form"
v-model="isValid"
lazy-validation
#submit.prevent="onSubmit">
<v-form ref="sizeform">
<div class="grid-row sizes-col">
<template v-for="(size, index) in variant.selected.sizes">
<v-text-field
ref="sizeInputs"
:key="size.sku"
v-model.number="variantSize[index]"
:rules="sizeRules"
:label="size.size"
type="number"
min="0"
#change="(value) => setVariantSize(value, size, index)"
required />
</template>
</div>
</v-form>
<div class="small muted">
* Mindestabnahme Menge 25 Stück / {{ getSizesQuantity }}
</div>
</v-form>
data() {
return {
variant: this.activeVariant,
variantSize: [],
minimumSizesQuantity: 25,
sizeQuantity: 0,
sizeRules: [ (v) => {
let totalQuantity = 0;
console.log(this.$refs.sizeInputs && this.$refs.sizeInputs.length);
if (this.$refs.sizeInputs && this.$refs.sizeInputs.length > 0) {
this.$refs.sizeInputs.forEach((input) => {
if (input.value) {
totalQuantity += parseInt(input.value, 10);
this.sizeQuantity = totalQuantity;
}
});
}
return totalQuantity >= this.minimumSizesQuantity;
}
],
};
},
computed: {
getSizesQuantity() {
return this.minimumSizesQuantity - this.sizeQuantity;
},
},
this is the output of console.log(this.$refs.sizeInputs && this.$refs.sizeInputs.length);
undefined
1
2
3
4
5
6
7

How to looping in img tag src using vuejs?

I'm making some booking movie ticket webapp and now I want to fetch Movie Poster.jpg in loop and It's not working
Movie.vue
<template>
<v-container grid-list-xs text-xs-center>
<v-layout justify-center row wrap>
<v-flex v-for="m in movies" :key="`1${m}`" xs2>
<img :src="imgsrc(m.id)" height="326px" width="220px"> ///my problem
</v-flex>
</v-layout>
</v-container>
</template>
And i want to use
<img :src="imgsrc(m.id)">
For looping and here my script
<script>
import { movies } from "#/Others/movie.json";
console.log(movies);
export default {
props: ["movieId"],
data() {
return {
movies
};
},
methods: {
imgsrc(movieId) {
let result = `assets/movie_poster/${movieId}.jpg`;
return result;
}
.
.
.
Movie.vue path
project/src/components/Movie.vue
Movie Poster.jpg path
project/src/assets/movies_poster/[filename].jpg
My Movie.JSON
{
"movies":[
{ "id": "Black panther"},
{ "id": "Avengers Infinity"},
{ "id": "Avengers Endsgame"},
{ "id": "Ant-Man"},
{ "id": "Spiderman Home Coming"}
],
"Black_panther":[
{"id":"A1", "seated": false, "price": 120},
{"id":"A2", "seated": false, "price": 120},
{"id":"A3", "seated": false, "price": 120},
{"id":"A4", "seated": false, "price": 120},
{"id":"A5", "seated": true, "price": 120},
{"id":"B1", "seated": true, "price": 120},
{"id":"B2", "seated": false, "price": 120},
{"id":"B3", "seated": true, "price": 120},
{"id":"B4", "seated": true, "price": 120},
{"id":"B5", "seated": false, "price": 120},
{"id":"C1", "seated": true, "price": 120},
{"id":"C2", "seated": false, "price": 120},
{"id":"C3", "seated": true, "price": 120},
{"id":"C4", "seated": false, "price": 120},
{"id":"C5", "seated": true, "price": 120}
],
.
.
.
.
Instead of using a function, you can do this directly:
<v-img contain
:src="require('assets/movie_poster/' + m.id + '.jpg')"
/>
EDIT: I didn't take into account that you are destructuring during import... so I added destructuring to my example, which is working just fine.. I'm not really sure what the issue is here since it's working just fine for me...
Are you exporting that JSON object from 'movies.json' via export default ... ?
[CodePen Mirror]
const moviesJson = {
movies: [
{ id: "Black panther" },
{ id: "Avengers Infinity" },
{ id: "Avengers Endsgame" },
{ id: "Ant-Man" },
{ id: "Spiderman Home Coming" }
],
Black_panther: [
{ id: "A1", seated: false, price: 120 },
{ id: "A2", seated: false, price: 120 },
{ id: "A3", seated: false, price: 120 },
{ id: "A4", seated: false, price: 120 },
{ id: "A5", seated: true, price: 120 },
{ id: "B1", seated: true, price: 120 },
{ id: "B2", seated: false, price: 120 },
{ id: "B3", seated: true, price: 120 },
{ id: "B4", seated: true, price: 120 },
{ id: "B5", seated: false, price: 120 },
{ id: "C1", seated: true, price: 120 },
{ id: "C2", seated: false, price: 120 },
{ id: "C3", seated: true, price: 120 },
{ id: "C4", seated: false, price: 120 },
{ id: "C5", seated: true, price: 120 }
]
};
// SIMULATE DESTRUTURE DURING IMPORT
const { movies } = moviesJson;
new Vue({
el: "#app",
props: ["movieId"],
data() {
return {
movies
};
},
methods: {
imgsrc(movieId) {
let result = `assets/movie_poster/${movieId}.jpg`;
return result;
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.5.14/dist/vuetify.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.5.14/dist/vuetify.min.css" rel="stylesheet" />
<div id="app">
<v-app id="inspire">
<ul>
<li v-for="m in movies" :key="`1${m}`">{{ imgsrc(m.id) }}</li>
</ul>
<v-container grid-list-xs text-xs-center>
<v-layout justify-center>
<v-flex v-for="m in movies" :key="`1${m}`" xs2>
<img :src="imgsrc(m.id)" height="326px" width="220px">
</v-flex>
</v-layout>
</v-container>
</v-app>
</div>

DataTable reorder data automatically in Vuetify v0.12

Project features:
- VueJS
- Vuetify v0.12
I have an Object Json that I get from the backend already ordered, only to show it in a table. However, v-data-table automatically reorders the JSON and does not show the order I want.
This is my code in my component Table:
<v-data-table :headers="headers" :items="items" :loading="loading" class="elevation-1" hide-actions>
<template slot="headers" scope="props">
<span v-if="props.item.value!='actions'">
{{ props.item.text }}
</span>
</template>
<template slot="items" scope="props">
<td>
<span>props.item.value</span>
</td>
<td>
<v-btn floating small class="green darken-2 mt-0" #click.native="onEdit(props.item)">
<v-icon light>edit</v-icon>
</v-btn>
</td>
</template>
</v-data-table>
export default {
props: ['compName', 'headers', 'items', 'pageCount',
'recordCount', 'loading', 'paginationOpts', 'applyFilters',
'onAdd', 'onEdit', 'onDelete', 'getAmountPerClient'],
methods: {
[...]
},
mounted() {
},
data() {
return {
expanded: false,
pagination: {},
gridRowsPerPageItems: process.env.GRIDS_ROWS_PER_PAGE_ITEMS,
collapsibleFields: {},
}
}
}
My items parameter has a value similar to the following::
[
{
"id": "93d22f3b-8af8-4920-a828-121ecc0e8abe",
"name": "Christhian",
"is_default": false,
"description": null,
"reference_code": null
},
{
"id": "167f32c7-0d84-4ec8-b5a4-fffbb42e293f",
"name": "Client 2",
"is_default": false,
"description": null,
"reference_code": null
},
{
"id": "0ee8f89b-aa5f-45f2-8cfd-5acc94171eba",
"name": "Client Test",
"is_default": false,
"description": null,
"reference_code": null
},
{
"id": "06e79101-8808-49d4-8b4e-41ec6120ed18",
"name": "DEFAULT",
"is_default": false,
"description": null,
"reference_code": null
}
]
But in table, this data has been reorded and show in this other order:
[
{
"id": "06e79101-8808-49d4-8b4e-41ec6120ed18",
"name": "DEFAULT",
"is_default": false,
"description": null,
"reference_code": null
},
{
"id": "0ee8f89b-aa5f-45f2-8cfd-5acc94171eba",
"name": "Client Test",
"is_default": false,
"description": null,
"reference_code": null
},
{
"id": "167f32c7-0d84-4ec8-b5a4-fffbb42e293f",
"name": "Client 2",
"is_default": false,
"description": null,
"reference_code": null
},
{
"id": "93d22f3b-8af8-4920-a828-121ecc0e8abe",
"name": "Christhian",
"is_default": false,
"description": null,
"reference_code": null
}
]
I do not know why it is automatically reordered. I do not have a sort method. The sort is done before the data reaches the datatable.
You can just use the disable-initial-sort directive.
<v-data-table disable-initial-sort ... >