Vue.js v-autocomplete v-model new data - vue.js

<v-autocomplete v-if="first.title == 'host'"
:items="host"
v-model="selected_host"
item-value="host_n"
outlined
hide-details
dense
></v-autocomplete>
I'd like to input new text which is not included in items.
autocomplete is just suggestion to user.
But I can't input new data in v-autocomplete. Whenever I write new data, it was deleted.

You should use v-combobox (doc here) instead of v-autocomplete if you want the user to add its own value
If you want to deal with multiple values, you can use the multiple attributes and passing an array to the v-model instead of a string (or an object if you use the return-object param)
new Vue({
el: '#app',
vuetify: new Vuetify(),
computed: {
tagsSorted() {
return this.tags.sort()
}
},
data: () => ({
host: [{
host_n: 'Foo',
},
{
host_n: 'Bar',
}
],
first: {
title: 'host'
},
selected_host: ''
}),
methods: {
sendData() {
console.log(this.selected_host)
}
}
})
<script src="https://unpkg.com/vue#2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#2.6.4/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#2.6.4/dist/vuetify.min.css" />
<div id="app" data-app>
<v-combobox v-if="first.title == 'host'" :items="host" v-model="selected_host" item-value="host_n" item-text="host_n" outlined hide-details dense></v-combobox>
<v-btn #click="sendData">Send data</v-btn>
</div>

Related

How can I update an existing v-select by setting the v-model?

I have been teaching myself Vue (with limited success) but have run into the below issue.
I have two s each with a v-model:
Select 1:
<v-select
class="pr-2"
:items="latteSizeList"
v-model="sizeid"
item-text="sizename"
item-value="id"
#change="updateAvailibleOz(), calculate(), togglesizeSelected()"
solo
>
</v-select>
Select 2:
<v-select
:items="shotsArray"
v-model="shotcount"
:value.sync="shotcount"
item-text="shotsAmountName"
item-value="shotsAmountAmount"
#change="calculate()"
solo
>
</v-select>
I want to update the displayed value of the second v-select when the function togglesizeSelected() is called.
methods: {
togglesizeSelected: function () {
this.shotcount= this.sizeList.filter( (item) => item.id.indexOf(this.sizeid) > -1)[0].latteshots;
console.log("Shots Count: " + this.shotcount)
},
}
The variable is updating and is showing in the console. But I have not been able to get the displayed item to update. What am I missing?
Funny thing is that I met the same exact question today :)
(If the console hides the solution, just click "Full page")
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
sizeid: null,
latteSizeList: [{
id: 0,
sizename: "Small",
latteshots: 5,
},
{
id: 1,
sizename: "Large",
latteshots: 10,
},
],
shotcount: null,
shotsArray: [{
shotsAmountName: "5 shots",
shotsAmount: 5,
},
{
shotsAmountName: "10 shots",
shotsAmount: 10,
},
],
}
},
methods: {
latteSizeListClickHandler(e) {
this.togglesizeSelected(e)
this.calculate()
},
togglesizeSelected({
latteshots
}) {
this.shotcount = this.shotsArray.find(({
shotsAmount
}) => shotsAmount === latteshots)
},
calculate() {
console.log('calculate executed')
}
},
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<div id="app">
<v-app>
<v-main>
<v-container>
Select 1:
<v-select class="pr-2" :items="latteSizeList" v-model="sizeid" item-text="sizename" item-value="id" #change="(e) => latteSizeListClickHandler(e)" return-object solo>
</v-select>
Select 2:
<v-select :items="shotsArray" v-model="shotcount" item-text="shotsAmountName" item-value="shotsAmountAmount" solo>
</v-select>
</v-container>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
My idea:
Do not place multiple functions on a handler in the template. Create a "composition function" instead, and call that. (Generally, try to keep the template as simple in terms of JS code as possible. That's just good advice.)
You have to
set the v-select to return the whole object not the value only. You can do this by adding return-object to the v-select
pass in the object to the handler function as the argument ((e) => latteSizeListClickHandler(e) -> e is the argument)
set the shotcount to an object that's in the shotsArray, not only its shotsAmount
remove the :value.sync="shotcount" from the second v-select. .sync is for something else (that's a shorthand syntax for reacting to an event emitted in a child-component)
And voilá! The v-select works!
In a shorter way:
use return-object on the first v-select
find the object in shotsArray & set shotcount to that object
remove :value.sync - this messes up the v-model

Vuetify v-data-table custom filter for dropdown

I have a v-data-table that already has the :search and :sort-by enabled. I have now created a select where I pull in my status from VueX. Accepted, Rejected. What I want to do is not only search or sort but when selecting from the drop down, accepted only the accepted values display in the table.
<v-select
v-model="selectStatus"
label="Status"
:items="statusData"
item-value="id"
item-text="name"
return-object
#change="filterStatus"
/>
Is this the correct way to setup the filter?
methods: {
filterStatus () {
console.log('This is where I am planning to add my custom filter')
}
}
This is my statusData:
userStatus : [
{
id: 0,
name: "Accepted",
},
{
id: 1,
name: " Rejected",
},
];
Or better to pass in the data:
{ text: 'Status', value: 'status.name', filter: value => {}},
To disable certain values to be selected add a disabled property to your items.
var app = new Vue({
el: '#app',
vuetify: new Vuetify(),
data: {
items: [{
id: 0,
name: 'Accepted'
},
{
id: 1,
name: ' Rejected',
disabled: true
}
],
value: null
}
})
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-container>
Value : {{value}}
<v-select
v-model="value"
label="Status"
:items="items"
item-value="id"
item-text="name"
return-object
/>
</v-container>
</v-app>
</div>
Documentation : props-disabled

Vuejs how to use computed properties with a forEach loop

My use case is something like this,
I loop through an array of objects to populate a drop-down menu.
If I v-model that drop down I can only get the object id or name. But I can get id and name both at the same time.
So I need computed property to find the id of the selected object.
This is my v-select
<v-select
label="Select an item"
:items="items"
item-text="name"
v-model="item_name">
/>
This is my computed property
computed: {
id() {
this.items.forEach(element => {
if (element.name == this.item_name) {
return (this.item = element.id);
}
});
}
}
What went wrong with my computed property I expected to {{item}} to print the id of the selected item but it didn't.
You may wan to use find() instead
computed: {
id() {
return this.items.find(element => {
return element.name == this.item.name
}).id;
}
}
This will first find the element in the Array that matches the condition in the function, and then the id of that element
The v-select component has return-object prop. Maybe try to use this to retrieve name and id at the same time, so the computed property will not be necessary at all.
Example:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: {
items: [{
id: 1,
name: 'test1'
},
{
id: 2,
name: 'test2'
},
{
id: 3,
name: 'test3'
},
],
item: null,
},
methods: {
onSelect() {
console.log(this.item);
},
},
});
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#6.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<div id="app">
<v-app>
<v-main>
<v-select v-model="item" :items="items" item-text="name" return-object #change="onSelect"/>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>

How to populate a Vuetify Select using data from axios

I need to populate a Vuetify select, but there is a problem with it, my Get method returns data, but the vuetify select only show something like this:
The text shows valid data:
[ { "id": 1 }, { "id": 2 } ]
And to populate the Select i follow the documentatioin adding :items="entidades" and :item-text="entidades.id" and :item-value="entidades.id"
<v-select :items="entidades" :item-text="entidades.id" :item-value="entidades.id" single-line auto prepend-icon="group_work" label="Seleccionar Grupo"></v-select>
This is my code form script
`data() {
return(){
entidades: [{
id: ''
}],
}
}`
I already tried to put 0, but it's the same result.
My axios.get method.
axios.get('http://localhost:58209/api/GetEntidades', {
headers:{
"Authorization": "Bearer "+localStorage.getItem('token')
}
})
.then(response => {
console.log(response)
this.entidades = response.data;
})
.catch(error => {
console.log(error.response)
});
Thank you so much
item-text and item-value are the name of the properties each item will display and use as value, respectively. So use item-text="id" item-value="id":
<v-select :items="entidades" item-text="id" item-value="id" single-line auto prepend-icon="group_work" label="Seleccionar Grupo"></v-select>
Demo:
new Vue({
el: '#app',
data () {
return {
entidades: [ { "id": 1 }, { "id": 2 } ]
}
}
})
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons'>
<link rel='stylesheet' href='https://unpkg.com/vuetify#1.0.10/dist/vuetify.min.css'>
<script src='https://unpkg.com/vue/dist/vue.js'></script>
<script src='https://unpkg.com/vuetify#1.0.10/dist/vuetify.min.js'></script>
<div id="app">
<v-app>
<v-container>
<v-select :items="entidades" item-text="id" item-value="id" single-line auto prepend-icon="group_work" label="Seleccionar Grupo"></v-select>
</v-container>
</v-app>
</div>

on-change doesn't work on v-select

I tried to use a v-select who display all countries. so i did :
<v-select on-change="updateCountryId" label="country_name" :options="countries" ></v-select>
it works great and display my countries but the function updateCountryId doesn't seems to work
methods: {
updateCountryId: function() {
alert('ok');
}
}
but i never see the ok
to import vue-select I did :
<script src="/js/vue-select/vue-select.js"> </script>
i use it in a twig file so in my vue-select.js i rewrite what i found on https://unpkg.com/vue-select#1.3.3 but replace the {{ }} by <% %>
ps : i already tried v-on:change, #change and onChange
and my code looks like that (i skip thing i judge useless)
<div id="General">
<div class="form-group">
<label>Pays :</label>
<v-select onChange="updateCountryId" label="country_name" :options="countries" ></v-select>
</div>
.
.
.
<script src="/js/vue-select/vue-select.js"> </script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.13/vue.min.js"></script>
<script>
Vue.config.delimiters = ['<%', '%>'];
Vue.component('v-select', VueSelect.VueSelect);
var vm = new Vue({
el: "#General",
data: {
countries: [],
},
filters: {
},
methods: {
updateCountryId: function () {
console.log('ok');
alert('ok');
},`
You are missing the colon :
Vue.component('v-select', VueSelect.VueSelect);
new Vue({
el: '#app',
data: {
options: ['one', 'two', 'three'],
selected: ''
},
methods: {
updateCountryId: function() {
alert('ok');
}
}
});
<script src="https://unpkg.com/vue#latest"></script>
<!-- use the latest release -->
<script src="https://unpkg.com/vue-select#latest"></script>
<div id="app">
<v-select :on-change="updateCountryId" label="country_name" :options="options" :searchable="false" ></v-select>
</div>
Update
you need to use unpkg.com/vue-select#2.0.0 because version 1 is not compatible with the current version of Vuejs
Ok, this was really causing me some headache, it seems it has changed again on version 3. Per the documentation (https://vue-select.org/guide/upgrading.html#index-prop-replaced-with-reduce), they removed these 3 functions: onChange, onInput, onSearch in favor of using an event: #input
export default {
name: 'app',
methods: {
changedValue: function() {
alert("A new value was selected");
}
}
}
<v-select
options: ['one', 'two', 'three']
selected: ''
#input="changedValue" >
</v-select>
you can do this
<v-select :options="etat_nip" v-model="etat_nip_selected"></v-select>
and add the v-model "etat_nip_selected " in watch like this
watch:{
'etat_nip_selected' : function (val, oldval) {
console.log(val);
}
},
for more informations https://v2.vuejs.org/v2/guide/computed.html#Watchers
Vue.component('v-select', VueSelect.VueSelect);
new Vue({
el: '#app',
data: {
options: ['one', 'two', 'three'],
selected: ''
},
methods: {
updateCountryId: function() {
alert('ok');
}
}
});
<script src="https://unpkg.com/vue#latest"></script>
<!-- use the latest release -->
<script src="https://unpkg.com/vue-select#latest"></script>
<div id="app">
<v-select :on-change="updateCountryId" label="country_name" :options="options" :searchable="false" ></v-select>
</div>
It worked when I use #input not #change