How to make vuetify v-autocomplete behave like a search bar? - vue.js

I want to make vuetify v-autocomplete behave like google search bar
Do not open dropdown when focusing
Only show dropdown when user press Enter key in searchbar
In https://vuetifyjs.com/en/api/v-autocomplete/, I did not see any function could control dropdown is shown or not

you can bind items to an empty array like searchResults and have your actual items in another array, then you can use #update:search-input event to update the searchText property and then call a method on #keydown.enter to populate the searchResults array.
also use hide-no-data prop to prevent dropdown from opening when there is no data in searchResults array.
side-note: you can pass empty string to append-icon prop to remove the drop down icon from the input
try the demo below by typing 'zz' in the input and pressing enter for example:
Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
items: ['foo', 'bar', 'fizz', 'buzz'],
searchResults: [],
searchText: '',
msg: '',
}),
methods: {
search() {
this.searchResults = this.items.filter((x) => this.searchText && x.includes(this.searchText));
this.msg = `${this.searchResults.length} result(s) found`;
},
},
});
<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">
<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>
<div id="app">
<v-app>
<v-container>
<v-autocomplete ref="searchBar" :items="searchResults" outlined dense hide-no-data label="type and press Enter to search" #update:search-input="searchText = $event" #keydown.enter="search" :messages="msg" append-icon=""></v-autocomplete>
</v-container>
</v-app>
</div>

Related

Vuetify date picker add tooltip in disabled days

How to add tootlip in the disabled days when using the Vuetify's date picker
I cannot seem to find it in documentation, is this possible somehow?
I don't think that you can do this in Vuetify because there are no slots provided to customize the dates' display. I can think of one solution using pure JS. The strategy would be to-
Find all disabled date elements and assign a title attribute (HTML tooltip) to it.
Important 1- The title attribute will not work with the disabled elements, so, you need to use pointer-events: auto on that disabled element. (Reference from this answer.)
Important 2- Above CSS will add a pointer cursor on the disabled button but it won't trigger any click event.
Here is a working demo. Try hovering on disabled dates and you should see a tooltip. Hope this helps.
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
date: '2023-02-16',
}),
mounted() {
let disabled_dates = document.querySelectorAll('.v-date-picker-table button');
disabled_dates.forEach(date => {
if(date.disabled) {
date.title = "tooltip";
}
})
},
methods: {
allowedDates: val => parseInt(val.split('-')[2], 10) % 2 === 0,
},
})
.v-btn--disabled {
pointer-events: auto !important;
}
<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>
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<div id="app">
<v-app id="inspire">
<v-row justify="center">
<v-date-picker
v-model="date"
:allowed-dates="allowedDates"
class="mt-4"
min="2023-02-01"
max="2023-02-28"
></v-date-picker>
</v-row>
</v-app>
</div>

vue.js 2.6 use :to="leading to a component " and :href="leading to a web page" at the same time, is it possible?

I am working in a Vue.js app with vue router doing a sidebar menu, and I want this behavior:
When clicking on it in the menu
render a component and
open a new web page in new window.
As far I've tried I only can do one thing or the other.
<v-list-item " target="_blank" :href="'https://google.com'" >
<v-list-item-title>universal</v-list-item-title>
</v-list-item>
and also
<v-list-item " :to="'universal'" >
<v-list-item-title>universal</v-list-item-title>
</v-list-item>
Is there a way to achieve both behaviors? If I place both props it renders the component in a new page.
Just use a method to do both things:
<v-list-item #click="onClicked" >
<v-list-item-title>universal</v-list-item-title>
</v-list-item>
//In script:
methods: {
onClicked() {
this.$router.push('/universal');
window.open('google.com', '_blank');
}
}
You can use .native modifier on click event:
const Home = { template: `<b>home</b>`}
const Component1 = { template: `<p>UniversaL</p>`}
const routes = [
{ path: '', component: Home },
{ path: '/universal', component: Component1 },
]
const router = new VueRouter({
routes
});
new Vue({
router,
vuetify: new Vuetify(),
data() {
return {
site: null
}
},
methods: {
otherPage() {
window.open('www.google.com', '_blank');
}
}
}).$mount('#app')
<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-container>
<router-view></router-view>
<v-list-item #click.native="otherPage" :to="'/universal'">
<v-list-item-title>universal</v-list-item-title>
</v-list-item>
</v-container>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.6.5/vue-router.min.js" integrity="sha512-hyOQvTtBERvssSiEFSSccyA/ZImk0QLpP92CuKgClbrc72zcMRUVapwZb/6IC0669Q0GWCu4/EhswVJcC0kwXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>

Without using v-model, how to set default value of v-combobox?

I'm creating a form with a v-combobox component.
The :items are being retrieved from a table in my DB and I am using v-model to enter whatever is selected into a different table in the DB, so I'm using v-model to link to the new DB table.
I know that I can use v-model to set a default value (meaning that that item is automatically selected), however is there an alternative way to do this since I'm currently using v-model for connecting to the DB?
Form:
<v-combobox
outlined
:items="allTypes"
v-model="plates[plates.findIndex(obj => obj.id === 1)].value"
:search-input="search"
>
</v-combobox>
If I'm following what you are trying to accomplish here...
You want to have a default value set on your combo box that is not the true value of the data it is binded to with v-model?
I'm not sure that is a great idea. Because if the user wants the default value they will leave it, thinking "it's already set to what I want" but it's not actually an accurate reflection of the value they would be setting?
Either way, it sounds like you probably want to move the logic from your current v-model prop to a computed property, so you can separate the logic of getting and setting.
UPDATED With Code Snippet
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
// the set value, initially false to use as a 'has a value been set' flag
setValue: false,
// the default value shown before selection has happened
defaultValue: "Pick a value (default)",
// the options to select from
allTypes: [
'dogs',
'cats',
'hamsters',
'something else',
],
// your table data
table: {
value: "null (initially)"
}
}
},
computed: {
// the value the we are binding the combo box to
comboBoxValue: {
// the value to output
get() {
// if a value has not been set
if (!this.setValue) {
// return the default
return this.defaultValue;
} else {
// else return whatever you would like
return this.setValue;
/* plates[plates.findIndex(obj => obj.id === 1)].value */
}
},
// the function that happens when the combo box is set
set(val) {
// val is the value the combox HAS been set to, not something you define here
console.log(val);
// update your table, pass in "val" the combo box value
this.updateTable(val);
// update the set value, combo box no longer show the default value
this.setValue = val;
}
}
},
methods: {
// some method to update your table
updateTable(newValue) {
alert('update table with value: ' + newValue)
this.table.value = newValue;
}
}
})
<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">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
<div id="app">
<v-app>
<v-content>
<v-container fluid>
<v-row>
<v-col cols="12">
table value: {{table.value}}
</v-col>
<v-col cols="12">
<v-combobox outlined :items="allTypes" v-model="comboBoxValue">
</v-combobox>
</v-col>
</v-row>
</v-container>
</v-content>
</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>

vuejs update component value on button click is not working

I have a header component. i cant able to update value of header component on button click
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<header>
<my-component ref="foo"></my-component>
</header>
<div id="app">
<h1>Component Test</h1>
<button v-on:click="test">Button</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var MyComponent = Vue.extend({
template: '<div><p>Hello</p><div v-if="islogin">User</div></div>',
data: function () {
return {
islogin: false
};
}
});
var vm = new Vue({
el: '#app',
components: {
'my-component': MyComponent
},
methods: {
test: function () {
this.$refs.foo.islogin = true;
}
}
});
</script>
</body>
</html>
i want to update the islogin to true on button click. Now it shows "TypeError: Cannot set property 'islogin' of undefined" error.
Thanks
Your component 'my-component' is not in the scope of Vuejs. Vue is in the div with the id 'app'. So you can't add others components outside this main div
Put the component inside Vuejs #app scope :
<div id="app">
<header>
<my-component ref="foo"></my-component>
</header>
<h1>Component Test</h1>
<button v-on:click="test">Button</button>
</div>

How to add a listener to a vue-multiselect after the page has loaded?

I need to add a listener to a vue-multiselect, like this (but this does not work):
$('.multiselect').change(console.log("multiselect changed"));
It must be added in the updated hook.
I've tried a lot of things, but because of the nature of vue-multiselect, conventional jQuery doesn't work ie, you can't listen for a change on the multiselect__input because its value doesn't actually change.
There's a .multiselect__single element that is added\removed depending on the state, but I'd rather not listen\test for html changes.
The vue-multiselect events don't include change, but you're probably looking for input (emitted after the value changes) or searchChanged (emitted after the search query changes).
The idiomatic way to listen to an event is to use this syntax: #EVENTNAME="METHOD". Example:
<multiselect #input="onSelection">
new Vue({
el: '#app',
components: {
Multiselect: window.VueMultiselect.default
},
data() {
return {
value: '',
options: ['list', 'of', 'options']
};
},
methods: {
onSelection(newValue) {
console.log({newValue})
}
}
})
<script src="https://unpkg.com/vue#2.5.17"></script>
<script src="https://unpkg.com/vue-multiselect#2.1.0"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-multiselect#2.1.0/dist/vue-multiselect.min.css">
<div id="app">
<multiselect :options="options" v-model="value" #input="onSelection"></multiselect>
<div>value: {{value}}</div>
</div>