how to pass default value in multiselect component to another vue-multiselect - javascript

I want to pass the default value of vue multiselect component use props, but I can't do this.
I use two selectors. When one option in select-1 selects I want the default value in select-2 is option select
No error just doesn't work properly. The value selected from the first selection does not fall into the default value of the second selection
multiselect component
<template>
<div>
<multiselect v-model="internalValue" id="currency_id" #input="onchange" placeholder="Select Your Currency" label="title" track-by="title" :options="options" :option-height="10" :show-labels="false">
<template slot="singleLabel" slot-scope="props"><img class="option__image" :src="props.option.img"><span class="option__desc"><span class="option__title">{{ props.option.title }}</span></span>
</template>
<template slot="option" slot-scope="props"><img class="option__image" :src="props.option.img">
<div class="option__desc"><span class="option__title" :id="props.option.id">{{
props.option.title }}</span><span class="option__small">{{ props.option.desc }}</span></div>
</template>
</multiselect>
</div>
</template>
import Vue from 'vue';
import Multiselect from 'vue-multiselect'
Vue.component('multiselect', Multiselect);
export default {
props: ['options', 'value'],
components: {
Multiselect
},
data() {
return {
internalValue: this.value,
}
},
methods: {
onchange(options) {
this.$emit('selectvalue', options.id);
}
},
watch: {
internalValue(v) {
this.$emit('input', v);
}
}
}
HTML
**select 1**
<multiselect #selectvalue="apiCalc":options="[
{
id: '1', title: 'Tether', img: 'https://coinnik.com/uploads/crypto-logos/006fe133d48ea7cd45cf8ccb8cb7ec42.png'
}
,
{
id: '2', title: 'ether', img: 'https://coinnik.com/uploads/crypto-logos/006fe133d48ea7cd45cf8ccb8cb7ec42.png'
}
,
{
id: '3', title: 'bitcoin', img: 'https://coinnik.com/uploads/crypto-logos/006fe133d48ea7cd45cf8ccb8cb7ec42.png'
}
]"
> </multiselect>
select2
<multiselect id="receive-currency" :options="receive_currency" v- model="selectedValue"></multiselect>
app.js
new Vue({
el: "#calculate",
data: {
receive_currency: [],
selectedValue: null,
},
methods: {
apiCalc(options) {
let self = this;
this.sendCurrencyId = options;
var receiveCurrency = [];
for (let item in responseData.data.direction.data) {
receiveCurrency.push({
title: responseData.data.direction.data[item].receiveCurrency.data.title,
img: '',
});
}
self.receive_currency = receiveCurrency;
self.selectedValue = receiveCurrency[0]
})
}
}
},
components: {
'multiselect': Multiselect
},
created() {
this.apiCalc();
},
});

In template:
<multiselect v-model="multiSelect1" :options="options" #input="onChange"></multiselect>
<multiselect v-model="multiSelect2" :options="options" :placeholder="placeholder"></multiselect>
In script:
data: () => ({
multiSelect1: "",
multiSelect2: "",
options: ["list", "of", "options"],
placeholder: "Select option"
}),
methods: {
onChange() {
this.multiSelect2 = this.multiSelect1
}
}
Please check this codesandbox: https://codesandbox.io/s/vue-template-t226h

Related

I cannot display the list of countries within the select option: property undefined error vuejs

I have been working with simple dropdown, and I keep having this error returned https://prnt.sc/1xdusd2 (I solved the prop problem)
then I read a bit more on that specific problem and turns out this happens when vue instance cannot find your property.
But countries is there and it is within the instance. I can't understand where I went wrong.
So, the idea is to make the dropdown reactive to the countries data I am getting from api.
data exists only on the parent component and I am sending it as a prop to the child component where I am iterating and displaying within the ooption.
can someone help me what is wrong here specifically
drop down component (child component)
<template>
<div>
<select v-for="(country, ) in countries" :key="country">
<option >{{country.name}} </option>
</select>
</div>
</template>
<script>
export default {
name: "DropDown",
props:['countries'],
data() {
return {
selectedOption: null,
};
},
};
</script>
parent component ************
<template>
<div class="step1 flex flex-col">
<h1 class="self-start mb-5">Шаг 1.</h1>
<div class="flex justify-center ">
<h3 class="text-white font-medium text-xl">Выберите страну</h3>
<div class="mx-5" >
<DropDown :countries="countries" />
{{}}
</div>
</div>
</div>
</template>
<script>
//import Button from "./UI/Button.vue";
import DropDown from "./UI/DropDown.vue";
export default {
name: "Step1",
components: {
DropDown: DropDown,
//Button: Button,
},
data() {
return{
// countries: [
// {
// id: "RU",
// name: "Россия"
// },
// {
// id: "DE",
// name: "Германия"
// },
// {
// id: "EE",
// name: "Эстония"
// }
// ],
}
},
methods:{
async fetchCountry (){
const res = await fetch('api/countries')
let countries = await res.json();
return countries
}
},
created() {
}
};
Vue tries to load your country data before the api fetch has finished, to bypass this add an v-if="countries" in your <select v-for="(country, ) in countries" :key="country">, then vue will only try to load it if countries is not null
You need to have countries in your data in order for it to work in the template, try this in your parent:
import DropDown from "./UI/DropDown.vue";
export default {
name: "Step1",
components: {
DropDown,
},
data() {
return {
countries: [],
}
},
methods: {
async fetchCountry() {
const res = await fetch('api/countries')
this.countries = await res.json();
}
},
};
And this in your child
<template>
<select v-model="selectedOption">
<option
v-for="country in countries"
:key="country.name"
:value="country.name"
>
{{ country.name }}
</option>
</select>
</template>
<script>
export default {
name: "DropDown",
props: {
countries: {
type: Array,
default: () => [],
},
},
data() {
return {
selectedOption: null,
};
},
};
</script>

Storefront UI - SfComponentSelect don't work properly

In my own component, i'm using SfComponentSelect (here in official docs)
When I click on option of select, selected option not show above the label "MySelect", this happen otherwise on sample inside the official docs.
This is my CustomComponent.vue
<template>
<SfComponentSelect label="MySelect">
<SfComponentSelectOption
v-for="option in optionsList"
:key="option.value"
:value="option.value"
class="sort-by__option"
>{{ option.label }}</SfComponentSelectOption>
</SfComponentSelect>
</template>
<script>
import { SfComponentSelect } from '#storefront-ui/vue';
export default {
name: "CustomComponent",
components: {
SfComponentSelect
},
data(){
return {
optionsList: [
{
value: "opt-1",
label: "Option 1",
},
{
value: "opt-2",
label: "Option 2",
}
]
}
}
};
</script>
After struggling on problem, i've found a solution for this problem.
Create new component (called: MyNewComponent) defining SfComponentSelect as mixins and copying from template and scss from SfComponentSelect.
Defining for MyNewComponent a new props and html for this
Using MyNewComponent as below
<SelectStore :label="name"
:size="pdvLists.length"
#change="changeLabel"
:my-new-label="myNewLabel"
persistent>
<SfComponentSelectOption
v-for="option in options"
:key="option.value"
:value="option.value"
class="sort-by__option"
>{{ option.name }}</SfComponentSelectOption>
</SelectStore>
<script>
import MyNewComponent from './MyNewComponent';
export default {
name: "ComponentBlaBla",
components: {
MyNewComponent
},
data() {
return {
options: [
{
value: "opt1",
name: "Opt1"
},
{
value: "opt2",
name: "Opt2"
}
],
myNewLabel: ''
}
},
methods: {
changeLabel(value){
// change something
let selectedOption = this.options.filter((item) => value === item.value);
this.myNewLabel = selectedOption[0].name;
}
}
};
</script>

how to make #click in Vuetify dynamic based on JSON objects

I have a component which shows a list. This list is dynamically populated by pages using this component.
<template>
<v-list
subheader
>
<v-subheader class="font-weight-black">Choose action</v-subheader>
<v-divider/>
<v-list-item
v-for="(item, i) in model.menu"
:key="i"
#click="item.action"
>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item>
</v-list>
</template>
And this is the TypeScript class.
<script lang="ts">
import { Component, Vue, Watch, Prop } from 'vue-property-decorator'
import { app } from 'electron'
#Component
export default class ListItem extends Vue {
#Prop() appStatus!: string
#Prop() appId!: string
model: any = {
menu: [
{ title: 'Title One', action: 'someModalAction(appId)' },
{ title: 'Title Two', action: '' },
{ title: 'Title Three', action: '' }
]
}
someModalAction( appId: string ) {
// show some modal here
}
</script>
Here model object would be dynamic and other pages would pass this object as Prop() (This is just an example here).
When I click on Title One, nothing happens. However, when I change the object to
{title: 'Title One', action: this.someModalAction(this.appId)}
Then I can see the modal when the page is loaded. When I close this modal, the list item cannot be clicked then.
So, how can I pass actions to #click dynamically?
convert data with getter:
import { Component, Vue, Watch, Prop } from 'vue-property-decorator'
import { app } from 'electron'
#Component
export default class ListItem extends Vue {
#Prop() appStatus!: string
#Prop() appId!: string
model: any = {
menu: [
{ title: 'Title One', action: 'someModalAction' },
{ title: 'Title Two', action: '' },
{ title: 'Title Three', action: '' }
]
}
get items(){
return this.model.menu
.map(item => ({...item, action: item.action && () => this[item.action](this.appId)})
}
someModalAction( appId: string ) {
// show some modal here
}
<template>
<v-list
subheader
>
<v-subheader class="font-weight-black">Choose action</v-subheader>
<v-divider/>
<v-list-item
v-for="(item, i) in items"
:key="i"
#click="item.action"
>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item>
</v-list>
</template>
Just make one function for calling you function on click.
To use dynamic function call it is suggested to have a helper function
that receives the function name and call the corresponding function.
data () {
return {
test: '',
submitting: false,
list: [{
title: "One",
action: "itemClicked"
},
{
title: "Two",
action: "itemClicked2"
},
{
title: "Three",
action: "itemClicked3"
}
]
}
},
methods: {
itemClicked() {
alert('item clicked')
},
itemClicked2() {
alert('item clicked 2')
},
itemClicked3() {
alert('item clicked 3')
},
funcioncall(name){
this[name]();
}
}
codepen - https://codepen.io/Pratik__007/pen/JjoVxbj?editors=1010
v-list-item v-for="(item,index) in profileItems" #click="item.action" ripple="ripple"
:key="index">
{
icon: 'mdi-exit-to-app',
href: '/',
title: 'Logout',
action: () => {
this.onUserLogout()
}
},
]

Reset filtered data Vue.js

I need to implement a button that would drop the filters in my application. The application is written on Vue. The filters themselves were implemented, but I do not know how to implement their reset.
<template>
<div id="app">
<input type="text" v-model="search">
<select name="sort" v-model="sort">
<option v-for="option in options" :value="option.value" :label="option.label"></option>
</select>
<table>...</table>
</div>
</template>
<script>
import goodsList from './api/data';
export default {
name: 'app',
data() {
return {
search: '',
sort: '',
options: [
{ label: 'Default', value: 'none' },
{ label: 'Brand', value: 'brand' },
{label: 'Price', value: 'price'}
],
goods: goodsList,
}
},
computed: {
filteredList() {
let filteredGoods = this.goods.filter( item => {
return item.name.toLowerCase().includes(this.search.toLowerCase());
});
switch (this.sort) {
case 'brand':
filteredGoods.sort((a, b) => a.brand.localeCompare(b.brand));
break;
case 'price':
filteredGoods.sort((a, b) => parseInt(a.price - b.price));
break;
}
return filteredGoods;
}
},
}
</script>
You will need a reset function which will assign the default selected value eg: 'none' to the v-model 'sort'. Since it is a two way binding, changing the value of 'sort' variable will eventually reset the selected option.
Function to be added:
resetOptions: function () {
this.sort='none';
}
Link below
https://jsfiddle.net/RohanPatil/68wced20/9/

Vue js v-if condicional rendering on a shared toggle button

//PARENT COMPONENT
<template>
....
<div class="input-wrapper">//Toggle button container
<label class="input-label">
SELECT YES OR NOT
</label>
<toggle //child component, toggle button
:options="shipping"
/>
</div>
<div
v-if="destiny[0].value"
class="input-wrapper">
<label class="input-label">
IF YES THIS CONTAINER WILL BE DISPLAYED
</label>
<toggle
:options="Options"
/>
</div>
.....
</template>
<script>
import Toggle from "....";
export default {
components: {
Toggle,
},
data: function () {
return {
destiny: [{
label: 'Yes',
value: true
},
{
label: 'No',
value: false
}
],
Options: [{
label: 'A',
value: 'a'
},
{
label: 'B',
value: 'b'
},
{
label: 'C',
value: 'c'
}]
}
}
}
</script>
///CHILD COMPONENT
<template>
<div class="toggle">
<button
v-for="option in options"
:key="option.value"
:class="{
active: option.value === value
}"
class="btn"
#click="() => toggleHandler(option.value)">{{ option.label }} .
</button>
</div>
</template>
<script>
export default {
props: {
options: {
type: Array,
required: true
}
},
data: function () {
return {
value: this.options[0].value
}
},
methods: {
toggleHandler (value) {
this.$emit('input', value)
this.value = value
}
}
}
</script>
There is toggle with to options YES or NOT, if yes is selected the child component will be rendered otherwise will keep hide.
I'm trying to use a conditional in order to display a child component into a parent component using directives v-if or v-show, but I could not find the way to send the boolean value from the child component to the parent component.
Hope this helps!!
// CHILD
Vue.component('child', {
template: '<div>TOGGLE:- <input type="checkbox" #click="emit"/></div>',
data() {
return {
checked: false
};
},
methods: {
emit: function() {
this.checked = !this.checked;
this.$emit('event_child', this.checked);
}
}
});
// PARENT
var vm = new Vue({
el: '#app',
data: function() {
return {
toggleStatus: false
}
},
methods: {
eventChild: function(checked) {
this.toggleStatus = checked;
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
<div id="app">
<child v-on:event_child="eventChild"></child>
<div id="toggle">TOGGLE STATUS => {{toggleStatus}}</div>
</div>

Categories

Resources