clearing select field automatically after selecting item - vuetify.js

I can't find a way to clear the select field in method "afterselection" which is invoked after selecting an item:
template:
<v-select
:items="adrlist"
#input="afterselection"
></v-select>
data in select:
const addressList = [{
"text":"Street 523, 2533",
"value":[1723455.7054408004,5923451.382843224]},
{"text":"Lala 3, 3455",
"value":[1723455.7054408004,5923451.382843224],
}]
vue-code:
new Vue({
el: '#app',
data () {
return {
adrlist: addressList,
}
},
methods:{
afterselection(item){
console.log(item);
//here I want to clear the select
},
},
})
Here's a code pen with this example:
codepen example
I've tried to set the v-model to null, but this is not working.
I have researched and tried for several days now, and I really can't find a solution :-/

Just for reference, you can clear a select field in vuetify with
this.$nextTick(() => {
this.selected = null
})
the important thing is the "nextTick"! otherwise it wont be rendered...
see this codepen provided by a vuetify-dev:
working codepen

I faced with the same issues. I have several v-select components in card text block and clear btn. When i click on clear i run clear func and clear all v-select items by refs.
template:
<v-card>
<v-card-title>Filters</v-card-title>
<v-card-text v-if="selectFilters.length">
<v-select
:ref="filter.id"
v-for="filter in selectFilters"
:items="filter.items"
:key="filter.id"
:label="filter.alias"
multiple
return-object
clearable
#input="selectChangeHandler($event, filter.id)"
></v-select>
</v-card-text>
<v-card-actions>
<v-btn color="primary" #click="clear">Clear</v-btn>
</v-card-actions>
</v-card>
script:
methods: {
...
clear: function() {
Object.values(this.$refs).forEach(ref => {
const vueSelect = ref[0];
vueSelect.internalValue = [];
});
},
}

you can achieve this by adding ref to the component
<v-select
ref="adrlistRef"
:items="adrlist"
#input="afterselection"
></v-select>
then use the reset method of v-select component whenever you want!
afterselection(item) {
if (item) {
console.log(item);
this.$refs['adrlistRef'].reset();
}
}

Looks like you need to bind to the select a v-model that is a computed property. Then it would be possible to change that value with the #input event.

Related

Vuetify3 v-combobox and cypress: How to identify list items?

I am in the process of migrating to vuetify3, and I'm using cypress (the cypress studio) for testing.
The <v-combobox> gives me a dropdown with items, but these are not easily referencable with css selectors. Cypress studio generates stuff like
cy.get('.v-overlay__content > .v-list > :nth-child(2) > .v-list-item__content > .v-list-item-title').click();
... which isn't readable for a human and will break if the dropdown list gets modified (for example, prepend a list item).
The best solution I came up with yet would be to give each list item a data-cy attribute; but how to do that properly? It seems to me that vuetify3 docs are still sparse on how to use the item slot (cf. https://next.vuetifyjs.com/en/components/combobox/); its workings seem to differ from vuetify2. By using the item slot like,
<v-combobox>
<template #item="scope">
myListItem
</template>
</v-combobox>
... the list items are not clickable any more.
Codesandbox: https://codesandbox.io/s/vuetify3-v-combobox-and-cypress-how-to-identify-list-items-gzfs71?file=/src/App.vue
EDIT Of course I could write the Cypress test code myself. But my premise is to use Cypress Studio, which CAN generate meaningful CSS selectors if possible, i. e. if there are id or data-cy attributes in the HTML code. But vuetify does not generate such. So I ask, how can I attach data-cy attributes to list items?
I think your selector is a bit more complex than needed
you can simplify to just the relevant elements
// get based on value
cy.get(".v-overlay-container .v-list-item").contains("Programming").click();
// get based on order (force: true is required if the combo box is still animating)
cy.get(".v-overlay-container .v-list-item").eq(2).click({ force: true });
example used
<template>
Click this combobox:
<v-combobox :items="items" id="combo" />
</template>
<script>
import { VCombobox } from "vuetify/components";
export default {
name: "App",
data() {
return {
items: ["Programming", "Design", "Vue", "Vuetify"],
};
},
components: { VCombobox },
};
</script>
test
describe("💩💩", () => {
beforeEach(() => {
cy.visit("http://10.0.0.248:8080/");
});
it("select with content", () => {
cy.get("#combo").click();
cy.get(".v-overlay-container .v-list-item").contains("Programming").click();
cy.get("#combo").should("have.value", "Programming");
});
it("select with order", () => {
cy.get("#combo").click();
cy.get(".v-overlay-container .v-list-item").eq(2).click({ force: true });
cy.get("#combo").should("have.value", "Vue");
});
});

Manipulating v-list-item-group model with object instead of list index

I am using v-list-item-group to display a list of dynamic items (entities that can be created/deleted), of which can be selected to display more information about the selected item.
Up until this point, I have simply been using the model of v-list-item-group to determine which item has been selected.
<template>
<v-list>
<v-list-item-group v-model="listSelection">
<v-list-item v-for="(item, index) in items" :key="index">
</v-list-item>
</v-list-item-group>
</v-list>
</template>
<script>
export default {
props: {
value: Object
},
computed: {
items: function() {
return this.$store.state.items // Collection of entities from a server
},
listSelection: {
get: function() {
return this.items.indexOf(this.value)
},
set: function(newVal) {
this.$emit('input', this.items[newVal])
}
}
},
}
</script>
This approach works fine with the initial data set, as the first element in the list is the first object in items, etc. However, if I add an entity in the middle, or remove something, or simply cause one of the items to shift to a different position in the list, the index to item position becomes invalid. Essentially if the list adds a new element, regardless of its position, its value (when selected in the group) is the next highest unused value. For example:
let fruits = ['apple', 'carrot']
<v-list-item> for apple will have a value 0, and <v-list-item> for carrot will have a value 1.
fruits.splice(1, 0, "banana")
<v-list-item> for apple will have a value 0, <v-list-item> for banana will have a value 2, and <v-list-item> for carrot will have a value 1.
I've done a bunch of playing around with v-model and value in v-list-item-group, but have not figured out how to avoid this problem. I would be fine with adding an #click on my items, and having the items set a value, rather than computing based on the list, but I would like the list selection to be maintained based on the value.
As best as i've read, the documentation indicates that selection in lists should be handled using a v-list-item-group, but the component doesn't seem to support dynamic lists too well.
Upon additional inspection of the documentation, <v-list-item> supports a value prop, allowing <v-list-item-group to use a dictated value instead of the item index.
So the solution was to simply specify the items id as the value for each item, and then use the id as a means of managing the item group model.
<template>
<v-list>
<v-list-item-group v-model="listSelection">
<v-list-item v-for="(item, index) in items" :key="index" :value="item.id">
</v-list-item>
</v-list-item-group>
</v-list>
</template>
<script>
export default {
props: {
value: Object
},
computed: {
items: function() {
return this.$store.state.items; // Collection of entities from a server
},
listSelection: {
get: function() {
return this.value.id;
},
set: function(newVal) {
this.$emit('input', this.items.find(item => item.id === newVal));
}
}
},
}
</script>

How to get append-outer-icon working in vuetify?

v-select allows to add append-outer-icon but how to force to expand icon list when this item is clicked?
<v-select
:items="selectItems.position"
v-model="selectedPosition"
clear-icon="highlight_remove"
append-icon="unfold_more"
append-outer-icon="unfold_more"
#click:append-outer="openSelect"
>
#click:append-outer allows add a callback function but what i have do in openSelect to expand the item's list?
You should add a ref to your v-select element. And then use this ref into your openSelect function:
<template>
<v-select
ref="theSelect"
:items="selectItems.position"
v-model="selectedPosition"
clear-icon="highlight_remove"
append-icon="unfold_more"
append-outer-icon="unfold_more"
#click:append-outer="openSelect"
/>
</template>
<script>
export default {
methods: {
openSelect () {
this.$refs['theSelect'].onClick()
}
}
}
</script>

Unable to see nativescript-vue popup #ref- nativescript-popup plugin

I am trying to implement popover functionality for one of my mobile app where I need popover with an arrow on different players icon and display info. of a player in a popover. for this after some R & D, I found that I can use this plugin nativescript-popup. But I am unable to see a popup when I try to implement it. Here are my codes. It's not giving any error but it's not opening any popup too.
Home.vue
<template>
<Page actionBarHidden="true">
<Button #tap="openPopup" ref="btn" style="width:100;height:40;"/>
</Page>
</template>
<script>
import { StackLayout } from 'tns-core-modules/ui/layouts/stack-layout';
import { Label } from 'tns-core-modules/ui/label';
import { ScrollView } from 'tns-core-modules/ui/scroll-view';
import { Popup } from 'nativescript-popup';
import Test from './Test'
export default {
components: {
Test
},
data() {
return {
popup: Popup
}
},
methods: {
_showPopup(source, view) {
this.popup = new Popup({
height: 30,
width: 80,
unit: '%',
elevation: 10,
borderRadius: 25
});
this.popup.showPopup(source, view).then(data => {
console.log('aaaa',data);
}).catch(error => {
console.log('aaaa',error);
});
},
openPopup(arg) {
//this._showPopup(this.$refs.btn.nativeView, Test);
const stack = new StackLayout();
stack.height = '100%';
const lbl = new Label();
lbl.text = 'Osei';
stack.addChild(lbl);
const sv = new ScrollView();
sv.content = stack;
this._showPopup(this.$refs.btn.nativeView, sv);
}
}
</script>
Test.vue
<template>
<StackLayout>
<Label text="NativeScript is the bomb.com" color="#ff4801" fontSize="22" textWrap="true"></Label>
</StackLayout>
</template>
Please suggest to me what am I doing wrong? Any help will be appreciated.
Notes: After openPopup() function code update, its working and popup is opening correctly. How can I use it with directly with the Vue component(Test.vue) instead of creating a view inside a function?
This plugin do not have explicit support for Vue so you can not pass Test which I guess a Vue Component, you have to either pass a {N} View or native view instance.
Edit: You could pragramatically create the instance of Vue component and pass the nativeView of root element to your popup.
Playground Sample

Vuetify Combobox - open dropdown on icon click

I'm trying to create a search input field with a history of previous searches on a dropdown, like, for example the search field in the Intellij editor.
I'm new to Vuetify and from what I can see so far it looks like Combobox is the best component to use.
I would like the dropdown to only open if you click the dropdown icon. At the moment the dropdown opens when you click in the text input field. From the documentation is looks like prop :menu-props="{openOnClick: false}" might be what I need, but it doesn't seem to work.
Can anyone give me pointer in the right direction?
https://codepen.io/damianhelme/pen/zMXJvb
<v-combobox
v-model="search"
:items="searchHistory"
label="Search"
:menu-props="{openOnClick: false}"
></v-combobox>
new Vue({
el: '#app',
data () {
return {
search: '',
searchHistory: [
'Apple',
'Banana',
'Pear'
]
}
}
})
Thanks.
EDIT:
Updated pen with custom append slot to deal with icon state:
https://codepen.io/anon/pen/KrjzRL
If you want to open (and close) the combobox only on icon-click, try this trick:
<v-combobox
:menu-props="{value: autoselectMenu}"
#click:append="toggle"
></v-combobox>
Pass custom value to menu - this indicates whether menu should be opened/closed.
Then change that value only on icon-click by using :append-icon-cb prop.
data () {
return {
autoselectMenu: false,
// ...
methods: {
toggle() {
this.autoselectMenu = !this.autoselectMenu
}
// ...
So for any other case when you want to open or close the menu, just change that custom value i.e. autoselectMenu.
codepen

Resources