Vuetify open select/autocomplete/combobox menu on focus - javascript

I have a Vuetifyjs Autocomplete. I want to open its menu when user focuses on it using tab key from previous input. Below is the sample code
<div id="app">
<v-app>
<v-container >
<v-row >
<v-col cols="12" md="4">
<v-text-field label="Text Field"/>
</v-col>
<v-col cols="12" md="6">
<v-autocomplete
label="Autocomplete"
:items="components"
hint="need to open menu on focus, just like click" persistent-hint
></v-autocomplete>
</v-col>
</v-row>
</v-container>
</v-app>
</div>
<script>
new Vue({
el: "#app",
vuetify: new Vuetify(),
data: {
components: [
'Autocompletes', 'Comboboxes', 'Forms', 'Inputs', 'Overflow Buttons', 'Selects', 'Selection Controls', 'Sliders', 'Textareas', 'Text Fields',
],
},
methods: {
}
})
</script>
I have also created a pen for this https://codepen.io/salalaslam/pen/YzzPajN

Because vuetify does not have the option you want, you must control it directly.
An input tag exists inside the autocomplete component. Specify focus event directly on this input tag.
Try this.
// template
<v-autocomplete
ref="autocomplete"
label="Autocomplete"
:items="components"
hint="need to open menu on focus, just like click"
persistent-hint
></v-autocomplete>
export default {
mounted () {
let autocompleteInput = this.$refs.autocomplete.$refs.input
autocompleteInput.addEventListener('focus', this.onFocus, true)
},
methods: {
onFocus (e) {
this.$refs.autocomplete.isMenuActive = true // open item list
}
}
}
pen - https://codepen.io/kdydesign/pen/rNNadXN?editors=1111

Instead of digging to the low-level DOM, you can simply use Vue.js's focus() and activateMenu()
<template>
<v-row>
<v-col cols="12" md="4">
<v-text-field label="Text Field" #keydown.tab="focus" />
</v-col>
<v-col cols="12" md="6">
<v-autocomplete
ref="aut"
label="Autocomplete"
:items="components"
hint="need to open menu on focus, just like click"
persistent-hint
></v-autocomplete>
</v-col>
</v-row>
</template>
<script>
export default {
layout: "center-six",
data() {
return {
components: ["A", "B", "C", "D"],
};
},
methods: {
focus() {
this.$refs["aut"].focus();
this.$refs["aut"].activateMenu();
},
},
};
</script>
I have also created a simple codePen VueJs Menu Activator

Related

Vue.js: How can I put a Login Modal inside a dropdown Menu?

I have the following dropdown menu:
<template>
<v-menu close-on-click transition="slide-y-transition">
<template v-slot:activator="{ on, attrs }">
<v-btn color="primary" v-bind="attrs" v-on="on">
Menu
</v-btn>
</template>
<v-list>
<v-list-item v-for="(item, index) in menuItemsMisc" :key="index" v-model="item.model">
<v-list-item-title>
<v-btn block color="white" #click="item.fn">{{ item.title }}</v-btn>
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
<!-- Modal code here -->
</template>
<script>
export default {
name: 'MenuBar',
data: () => ({
loginModal: false,
purchaseModal: false,
menuItemsMisc: [
{ title: 'Login',
model: 'loginModal',
fn: () => { this.loginModal = true}
},
{ title: 'Purchase',
model: 'purchaseModal',
fn: () => { this.purchaseModal = true }
},
]
}),
}
</script>
And I am trying to display this Login Modal When the Login Button is clicked in the dropdown.
<v-dialog v-model="loginModal" persistent max-width="500px">
<v-card class="elevation-12">
<v-toolbar color="primary" dark flat>
<v-toolbar-title>Login form</v-toolbar-title>
<v-spacer></v-spacer>
</v-toolbar>
<v-card-text>
<v-form>
<v-text-field name="login" prepend-icon="mdi-account" type="text"></v-text-field>
<v-text-field id="password" name="password" prepend-icon="mdi-lock" type="password">
</v-text-field>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary">Login</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
But whenever I click the Login or Purchase Button, I have an error that says:
TypeError: Cannot set property 'loginModal' of undefined
What is the Problem here?
From the Vue docs on v-model:
You can use the v-model directive to create two-way data bindings on form input, textarea, and select elements. It automatically picks the correct way to update the element based on the input type.
The v-model property on your <v-dialog> component is expecting it to be an input of some type.
You should be able to simply change this to a v-if:
<v-dialog v-if="loginModal" persistent max-width="500px">
This will cause the <v-dialog> component to display when your button is clicked.
EDIT: Please also make sure your data property on the Vue instance is declared as a class-style function. If you use a lambda function you will lose the this scope when referring to this.loginModal:
export default {
...
data() {
return {
...
}
}
}

VueJS: Dynamic props based on v-select item

I have got a chart which uses properties.
<template>
<v-row>
<v-col col="12" sm="12">
<Chart :data="series2"></Chart> ### This chart receives the props
</v-col>
<v-col cols="12" sm="6">
<v-select
item-color="red"
item-text="muh"
v-model="e7"
:items="items"
label="Select"
single
chips
hint="Which series do you want?"
persistent-hint
></v-select>
</v-col>
</v-row>
</template>
This is my script with the series.
<script>
import Chart from "./Chart"
export default {
data: function () {
return {
e7: [],
series1: [1,2,3,4,5],
series2: [5,6,5,6,5],
series3: [5,4,3,2,1],
items: ["series1", "series2", "series3"]
}
},
components: {
Chart
},
}
</script>
Passing the props works fine, but I want the v-select to change the selected series (props) based on the selected item. How can I do this?
You can do something like this.
<Chart :data="$data[e7]"></Chart>
Where e7 is the v-model attribute for v-select.

How to have the button span the whole width?

I am using Vuetify card with a layout and rendering some dynamic vuetify components inside of the card on checkbox selection which renders either a divider, a spacer, toolbar or button but i am not able to figure out how can i make the buttons span the entire width?
Basically the dynamic button should look like the button at the end rendering the entire width.
Please check this codepen.
Please check this working example:-
new Vue({
el: "#app",
data() {
return {
pricing: [{
text: "Actual price:",
value: "$17,000",
},
{
text: " Discount",
value: "$12,345",
}
],
elements: [{
title: "Divider",
value: "v-divider"
},
{
title: "Toolbar",
value: "v-toolbar"
},
{
title: "Button",
value: "v-btn"
}
],
selected: []
};
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.5.14/dist/vuetify.min.js"></script>
<link rel="stylesheet" href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons'>
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.5.14/dist/vuetify.min.css" rel="stylesheet" />
<div id="app">
<v-app id="inspire">
<v-container>
<v-layout row>
<v-flex xs6>
<v-card>
<v-card-text>
<v-layout row justify-space-between v-for="option in pricing" :key="option.value" class="my-3">
<span :class="option.class">{{option.text}}</span>
<component v-for="(el, i) in selected" :key="i" :is="el.value"></component>
<span>{{option.value}}</span>
</v-layout>
<v-layout row justify-center>
<v-flex xs11>
<v-btn block>
Request
</v-btn>
</v-flex>
</v-layout>
</v-card-text>
</v-card>
<v-flex v-for="el in elements" :key="el.value">
<v-checkbox :value="el" v-model="selected" :label="el.title">
</v-checkbox>
</v-flex>
</v-flex>
</v-layout>
</v-container>
</v-app>
</div>
Any help will be appreciated. Thank you so much.
Use .flex.xs12 (12 = flex-basis: 100%;)
-or-
remove xs12 (And add button block attribute = flex: 1 0 auto;).
<!-- block buttons extend the full available width -->
<template>
<v-btn block>
Block Button
</v-btn>
</template>
https://vuetifyjs.com/en/components/buttons/#block

How to add two v-text-fields when I click a button dynamically using vuetify

How can I add two v-text-fields when I click on a button, and if I need more v-text-fields I click on the button and it appears in my content.
I would like something like this
I hope you get the idea.
<v-container fluid>
<v-row align="center" >
<v-col >
<v-text-field color="info" v-model="new.name" label="Name" required></v-text-field>
</v-col>
<v-col>
<v-select color="info" :items="arrResp" v-model="new.idResp" label="Boss" required></v-select>
</v-col>
</v-row>
</v-container>
Thank you for your help.
Codepen
<div id="app">
<v-app id="inspire">
<div
v-for="(textField, i) in textFields"
:key="i"
class="text-fields-row"
>
<v-text-field
:label="textField.label1"
v-model="textField.value1"
></v-text-field>
<v-text-field
:label="textField.label2"
v-model="textField.value2"
></v-text-field>
<v-btn #click="remove(i)" class="error">delete</v-btn>
</div>
<v-btn #click="add" class="primary">add</v-btn>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
textFields: []
}
},
methods: {
add () {
this.textFields.push({
label1: "foo",
value1: "",
label2: "bar",
value2: ""
})
},
remove (index) {
this.textFields.splice(index, 1)
}
}
})
.text-fields-row {
display: flex;
}

How to add an icon in front of every VuetifyJS combobox entry?

I'm using the combobox component of VuetifyJS and I need to add an icon in front of every entry in the drop down. How to do that?
Here is a CodePen example of the combobox: https://codepen.io/anon/pen/KBLXYO
HTML
<div id="app">
<v-app id="inspire">
<v-container fluid>
<v-layout wrap>
<v-flex xs12>
<v-combobox
v-model="select"
:items="items"
label="Select a favorite activity or create a new one"
></v-combobox>
</v-flex>
</v-layout>
</v-container>
</v-app>
</div>
JS:
new Vue({
el: '#app',
data () {
return {
select: 'Programming',
items: [
'Programming',
'Design',
'Vue',
'Vuetify'
]
}
}
})
Use the item scoped slot.
<v-combobox
v-model="select"
:items="items"
label="Select a favorite activity or create a new one">
<template slot="item" slot-scope="data">
<v-icon>home</v-icon> {{data.item}}
</template>
</v-combobox>
Here is your pen updated.
FWIW, this is all covered in the documentation.

Categories

Resources