Vuejs: how to update text fields based on autocomplete selection - vue.js

New to vuejs. I have a vue component that has two array props: countries and countryDetails
countries -> ['England', 'Germany']
countryDetails -> [ { country: 'England', capital: 'London' } ]
I’m able to display a dropdown using countries array.
<v-autocomplete
v-model="category"
:items="countries"
label="Countries" />
How do I get the capital to show up in a user editable text field when corresponding country selected and available in countryDetails array (England) or show an empty user editable text field when country not available in countryDetails array (Germany)
<v-text-field
class="mr-2"
v-model="countryDetails[i].capital"
label="Capital" />

You should handle the autocomplete change with a listener calling a method which set the text-field v-model value, if the choice is matching a country in the country details array :
<template>
<div>
<v-autocomplete #change="handleChange"
:items="countries"
label="Countries" />
<v-text-field class="mr-2"
v-model="selectedCountryCapital"
label="Capital" />
</div>
</template>
data() {
return {
selectedCountryCapital : null
}
},
methods: {
handleChange(choice) {
const matchingCountry = this.countryDetails.find(details => details.country === choice);
this.selectedCountryCapital = matchingCountry ? matchingCountry.capital : null;
}
}

Related

Vuejs - How do I change the property's value when Checkbox is checked/unchecked and update the same

I am having two components and i am trying to update the component and i am trying to change value of property based on the checkbox checked or unchecked. I am unable to change the value of the property.
Here is my code:
ComponentA.vue
**Template**
<div class="column" v-for="car in cars">
<label class="label">
<input type="checkbox" v-model="carsSelected" #change="onChange" >
{{ car }}
</label>
</div>
**Script**
data () {
return {
carsSelected: {},
cars: {
hyundai,
maruthi,
audi,
}
}
...
onChange(){
this.$emit('input', this.carsSelected) .---> For updating
}
ComponenrB.vue
<component-a v-model="fourWheeler.brands" />
...
fourWheeler: {}
And here is how fourWheeler.brands looks like:
**It is an object**
{
hyundai: false,
maruti: false,
audi: true,
}
I want to change the values of the car brands ie fourWheeler.brands based on checked or unchecked, if checkbox is unchecked then false, if it is checked then true. Please let me know how to update the values and better way of binding.
Since the checkbox only indicates if it is selected or not, you can't select multiple values with just one checkbox, however you can use your cars object to render the options:
<template>
<main>
<label v-for="(value,key) in cars" :key="key" :for="key">
{{key}}
<input type="checkbox" :id="key" v-model="cars[key]" #change="onChange"/>
</label>
</main>
</template>
<script>
export default {
data(){
return {
cars: {
hyundai:false,
maruthi:false,
audi:false,
}
}
},
methods:{
onChange(){
console.log(this.cars)
}
}
}
</script>
As you can see what I'm doing is iterating through the cars properties and showing a checkbox for each of the properties (each car) and then v-model is changing the specific property of the cars object, so if you do a console.log of the cars object in the onChange now you see the cars object with the selections. Worth notice that I changed the cars object so it holds the car names and true/false for selected.

Vue / Vuetify - Display v-select text value in a <span>

How do I display the text of a v-select in a <span>? I'm trying to create a printable report and I can't pull-out all the item-text value. I also have multiple v-select using array.push
<span>{{ insert item-text }}</span>
<v-select
v-model="value"
:items="data"
item-text="data_name"
item-value="id"
/>
export default {
data() {
return {
data: [],
value: [],
}
}
}
In your case, selected item is stored in value because that is what you specified in v-model:
<span>{{ selected }}</span>
<v-select
v-model="value"
:items="data"
item-text="data_name"
item-value="id"
/>
data: () => ({
data: [
{id: 0, data_name:'Apples'},
{id: 1, data_name:'Apricots'},
{id: 2, data_name:'Avocado'},
{id: 3, data_name:'Bananas'}
],
value: null,
}),
computed: {
selected () {
return this.data.find(item => item.id === this.value)
}
}
Since you specified item-value="id" you are getting the id. If you only need data_name you can specify item-value="data_name" to begin with. And then you have the text stored in the value without doing anything:
<span>{{ value }}</span>
<v-select
v-model="value"
:items="data"
item-text="data_name"
item-value="data_name"
/>

how to create dynamic input filters for columns in bootstrap-vue 2.0

I'm trying to create some dynamic filters in bootstrap-vue 2.0.0-rc.11 for the bootstrap-table columns
In my example I did this
<b-table class="io-store-list-table table-striped" show-empty hover stacked="md" :items="stores" :fields="storeFields" :current-page="currentPage" :per-page="perPage" :filter="filter" :sort-by.sync="sortBy" :sort-desc.sync="sortDesc" :sort-direction="sortDirection" #filtered="onFiltered" empty-filtered-text="{l s='There are no records matching your request' mod='ioweb_slocator'}">
<template slot="top-row" slot-scope="data">
<th v-for="field in fields">
<input v-if="field.filterable" type="text" #click.stop value="" />
</th>
</template>
<template v-for='field in formatted' :slot='field' slot-scope='row'>
<span v-html='row.value'></span>
</template>
</b-table>
<b-row>
<b-container>
<b-col xs="12" class="my-1 io-pagination">
<b-pagination :total-rows="totalRows" :per-page="perPage" v-model="currentPage" class="my-0"/>
</b-col>
</b-container>
</b-row>
</b-table>
Which renders a table like this
Now I'm attempting to filter the items based on what value is entered in each column. For example if I type mypartnername at the input box below Partner column, I would like to dynamically filter the items based on the row key called partner but I'm not sure how to approach this.
Based on the accepted answer I was able to create a structure that helped me like this.
Step 1:
Create a property filteredResults and set it equal to my unfiltered items property
let app = new Vue({
el: "#app",
data() {
return {
...
stores: stores,
groups: groups,
totalRows: stores.length,
filters: [],
loop: 0,
filteredResults: stores,
}
},
Step 2
Used filteredResults in the :items slot
Step 3
Create a single function to set the filters
methods: {
...
setFilter(property, value) {
console.log("Filtering");
this.filters[property] = {};
this.filters[property].value = value;
this.filteredResults = this.stores.filter(item => {
let keep = true;
// This is a basic equality filter. What I did in the actual code was to have an object with filter functions for each key. If a key was missing, it defaulted to straight equality.
this.fieldKeys.forEach(key => {
keep =
keep &&
(this.filters[key] === undefined || this.filters[key].value === undefined || this.filters[key].value === "" || item[key].match(this.filters[key].value));
});
return keep;
});
},
},
what about something like this? I dont know if i got your problem right.
<input v-if="field.filterable" #onchange="setFilter(field.property, $event.target.value)" type="text" #click.stop />
in the setFilter function you could do something like this:
setFilter(property, value) {
this.filters[property].value = value
}
get your results with a computed property
filteredResults(){
return users = this.users.filter((item) => {
for (var key in this.filters) {
if (item[key].value === undefined || item[key].value != filter[key])
return false;
}
return true;
}
}
I dont know if it works, couldnt test it. I am curious about the solution here.

How to search within nested objects

I have done my research trying to figure out how to achieve what I am describing below, however I had no luck.
In my Algolia index, some records have nested objects.
For example, title and subtitle attributes are of the following format:
title:
{
"en": "English title",
"gr": "Greek title"
}
I would like to execute queries only for a specific subset (in our example "en" or "gr") of these attributes, withoute "exposing" any facet in the UI — language selection would ideally be done “automatically” based on a variable (lang) passed to the Vue component with props. I am using Laravel Scout package with default Vue implementation, as described in documentation here.
My InstantSearch implementation is pretty simple, I am not defining anything specific regarding queries and searchable attributes, I am currently using all the default functionality of Algolia.
<template>
<ais-instant-search
:search-client="searchClient"
index-name="posts_index"
>
<div class="search-box">
<ais-search-box placeholder="Search posts..."></ais-search-box>
</div>
<ais-hits>
<template
slot="item"
slot-scope="{ item }"
>
<div class="list-image">
<img :src="'/images/' + item.image" />
</div>
<div class="list-text">
<h2">
{{ item.title }}
</h2>
<h3>
{{ item.subtitle }}
</h3>
</div>
</template>
</ais-hits>
</ais-instant-search>
</template>
<script>
import algoliasearch from 'algoliasearch/lite';
export default {
data() {
return {
searchClient: algoliasearch(
process.env.ALGOLIA_APP_ID,
process.env.ALGOLIA_SEARCH
),
route: route,
};
},
props: ['lang'],
computed: {
computedItem() {
// computed_item = this.item;
}
}
};
</script>
I would like to somehow pass an option to query “title.en” and “subtitle.en” when variable lang is set to “en”. All this, without the user having to select “title.en” or “subtitle.en” in the UI.
Update
Maybe computed properties is the path to go, however I cannot find how to reference search results/hits attributes (eg item.title) within computed property. It is the code I have commented out.
I think, you can use computed property. Just transform current item according to the current language variable.
new Vue({
template: "<div>{{ computedItem.title }}</div>",
data: {
langFromCookie: "en",
item: {
title: {
en: "Hello",
ru: "Привет"
}
}
},
computed: {
computedItem() {
const item = JSON.parse(JSON.stringify(this.item));
for (value in item) {
if (typeof item[value] === "object" && Object.keys(item[value]).includes(this.langFromCookie))
item[value] = item[value][this.langFromCookie];
}
return item;
}
}
}).$mount("#app")
<div id="app"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
If lang variable is available via props, you can check that inside list-text class and return {{title.en}} or {{title.gr}} accordingly by passing a dynamic lang value title[lang] like below
...
<div class="list-text">
<h2>
{{ item.title[lang] }}
</h2>
<h3>
{{ item.subtitle[lang] }}
</h3>
</div>
If you want to make a request according to lang prop when component mounts ,then you can make a request inside mounted() method then query like below
mounted() {
axios.get(`/getSomethingWithLang/:${this.item.title[this.lang]}`)
...
}

Vue: Dropdown box in vue-select not showing value after selecting

I am populating a dropdown from a computed method that returns an array of store objects. Then in the vue-select, I am passing this in as options and having the option.address show in the dropdown. That is working as expected but when clicking a dropdown option, the box doesn't show the value -- it just remains blank.
computed: {
storeLocationsArray: function() {
let arr = [];
this.storeLocations.forEach((location,index) => {
arr.push({id: index, address: location.address})
})
return arr;
}
}
<v-select
v-model="selectedPickupLocation"
:options="storeLocationsArray"
>
<template class="single-option" slot="option" slot-scope="option">
{{option.address}}
</template>
</v-select>
You can use label to display address instead of slot
<v-select
v-model="selectedPickupLocation"
:options="storeLocationsArray"
label="address"
>
</v-select>