Vuetify autocomplete both menus active at the same time - javascript

Here is my code pen https://codepen.io/aaronk488/pen/MWbKNOq?editors=1011
Here is the HTML
<div id="app">
<v-app>
<v-container >
<v-row >
<v-col cols="6" md="6">
<v-autocomplete
ref="autocomplete"
label="Autocomplete"
:items="components"
hint="need to open menu on focus, just like click" persistent-hint
></v-autocomplete>
</v-col>
<v-col cols="6" md="6">
<v-autocomplete
ref="autocomplete2"
label="Autocomplete2"
:items="components2"
hint="need to open menu on focus, just like click this" persistent-hint
></v-autocomplete>
</v-col>
</v-row>
</v-container>
</v-app>
</div>
and here is the JS
new Vue({
el: "#app",
vuetify: new Vuetify(),
data: {
components: [
'Autocompletes', 'Comboboxes', 'Forms', 'Inputs', 'Overflow Buttons', 'Selects', 'Selection Controls', 'Sliders', 'Textareas', 'Text Fields',
],
components2: [
'Autocompletes2', 'Comboboxes2', 'Forms2', 'Inputs2', 'Overflow Buttons2', 'Selects2', 'Selection Controls2', 'Sliders2', 'Textareas2', 'Text Fields2',
],
},
mounted () {
let autocompleteInput = this.$refs.autocomplete.$refs.input
autocompleteInput.addEventListener('focus', this.onFocus, true)
let autocompleteInput2 = this.$refs.autocomplete2.$refs.input
autocompleteInput2.addEventListener('focus', this.onFocus2, true)
},
methods: {
onFocus() {
this.$refs.autocomplete.isMenuActive = true
this.$refs.autocomplete.isMenuActive = true
},
onFocus2() {
this.$refs.autocomplete.isMenuActive = true
}
}
})
Here is what the UI looks like
Is there a way to get both v-autocomplete menu to show at the exact same time?
If the user clicks on either v-autocomplete both that v-autocomplete and the other v-autocomplete drop-downs with the options show at the same time.

Set isMenuActive && isFocused to true
this.$refs.example.isMenuActive = true;
this.$refs.example.isFocused = true;

Related

How to submit form to array and clear inputs in vue

I have a vue form inside a dialog. Where the user can select a date and multplie starting times and ending times. So far I can save one object consisting of one date and multiple times. But when I want to add another object it takes the new date but changes the time values for every object.
for example if I add first an object with 05.09.2021 start:15:00 end: 16:00 and then add another object with date: 06.09.2021 start: 16:00 end: 17:00. The start and end is changed to the latest value of all objects, but I want each of them to be individually. I tried submitting a form, but sadly I could not make it work because it is reloading the page which I do not want, if i use .prevent on submit my error with time changing for every object still consists. Could someone take a look at my code and point me my mistake out`?
HTML:
<v-row>
<v-col cols="12" sm="12">
<v-menu
ref="menu3"
v-model="menu3"
:close-on-content-click="false"
:return-value.sync="dates"
transition="scale-transition"
offset-y
min-width="auto"
>
<template v-slot:activator="{ on, attrs }" >
<v-text-field
v-model="dates"
label="Picker in menu"
prepend-icon="mdi-calendar"
readonly
v-bind="attrs"
v-on="on"
></v-text-field>
</template>
<v-date-picker
v-model="dates"
no-title
scrollable
>
<v-spacer/>
<v-btn
text
color="primary"
#click="menu3 = false"
>
Cancel
</v-btn>
<v-btn
text
color="primary"
#click="$refs.menu3.save(dates) "
v-on:click=" menu3 = false"
>
OK
</v-btn>
</v-date-picker>
</v-menu>
<v-btn v-on:click="addTimeFields()">Add Time</v-btn>
</v-col>
</v-row>
<v-row v-for="(find, index) in selectedTime" >
<v-col
cols="6"
sm="6">
<v-text-field
v-model="find.startTime"
label="Starttime"
type="time"
></v-text-field>
</v-col>
<v-col
cols="6"
sm="6">
<v-text-field
v-model="find.endTime"
label="Untiltime"
type="time"></v-text-field>
</v-col>
</v-row>
</form>
Javascript:
<script>
import MeetingsTableComponent from "#/components/MeetingsTableComponent";
import DatePickerComponent from "#/components/DatePickerComponent";
export default {
name: "NextMeetingCardComponent",
data: () => ({
selectedTime: [],
dates: new Date().toISOString().substr(0,10),
datesFinal: [],
dialog: false,
menu: false,
modal: false,
menu2: false,
menu3: false
}),
methods:{
addTimeFields(){
this.selectedTime.push({
startTime:"",
endTime: "",
})
},
saveDateAndTIme(e){
this.datesFinal.push({
date: this.dates,
times : [this.selectedTime]
}
)
this.$refs.form.submit()
},
clearArrays(){
while (this.selectedTime.length){
this.selectedTime.pop()
}
}
}
};
</script>
I tried clearing the selectedTimes array which is pushed to datesFinal after pushing it but then every value is deleted.
I think there's an error in saveDateAndTIme(): times contains a nested array of the this.selectedTime array, but that should be unnested (i.e., set times to this.selectedTime itself).
After pushing this.selectedTime into datesFinal, you could clear the form by setting this.selectedTime to an empty array.
export default {
methods: {
saveDateAndTIme(e) {
this.datesFinal.push({
date: this.dates,
times: this.selectedTime, 👈
})
this.selectedTime = [] 👈
},
}
}
demo

Why is my :search-input.sync function called twice?

In my code pen https://codepen.io/aaronk488/pen/MWbKNOq?editors=1011 everything works, but my sync function search is called twice and I don't know why. I added a conditional statement so my code works, but am curious if there is a reason why the sync function is called twice.
Here is my HTML
<div id="app">
<v-app>
<v-container >
<v-row >
<v-col cols="4" md="4">
<v-autocomplete
ref="autocomplete"
label="Autocomplete"
:items="components"
v-model="first"
:search-input.sync="search"
hint="need to open menu on focus, just like click" persistent-hint
></v-autocomplete>
</v-col>
<v-col cols="4" md="4">
<v-autocomplete
v-model="second"
ref="autocomplete2"
label="Autocomplete2"
:items="components2"
item-text="name"
item-value="id"
hint="need to open menu on focus, just like click this" persistent-hint
></v-autocomplete>
</v-col>
</v-row>
</v-container>
</v-app>
</div>
and here is my js
new Vue({
el: "#app",
vuetify: new Vuetify(),
data: {
search: null,
first: "",
second: "",
components: [
'Autocompletes testOne', 'Comboboxes testTwo', 'Forms', 'Inputs', 'Overflow Buttons', 'Selects', 'Selection Controls', 'Sliders', 'Textareas', 'Text Fields',
],
components2: [
'Autocompletes2', 'Comboboxes2', 'Forms2', 'Inputs2', 'Overflow Buttons2', 'Selects2', 'Selection Controls2', 'Sliders2', 'Textareas2', 'Text Fields2',
],
},
watch: {
search(val){
if(val){
console.log(val)
const temp = val.split(" ");
console.log(temp)
// this.components = [];
// this.components2 = [];
this.components.push(temp[0]);
console.log(this.components);
if(!temp[1]){
return;
}
console.log(temp[1]);
this.components2.push(temp[1]);
this.first = temp[0];
this.second = temp[1];
console.log(this.second )
}
},
},
})
and here is the console output
You're changing the property bound with v-model to that search input in your watcher. This line:
this.first = temp[0];
since this first property is bound with v-model, it's changing the search-input. You'll notice it doesn't happen if you select an item with only one word, because that single word will be the same as temp[0].

How to add a google autocomplete input inside of a vuetify dialog box

As the title states, Im looking to add a google autocomplete inside of a vuetify dialog box within vue.js. I have successfully added autocomplete to regular inputs on the page by using the mounted() function and attaching there(code below). However it seems that since the dialog box doesnt render until you click a button to launch it, using this.$refs and attaching an autocomplete to those inputs wont work. Ive also tried creating a function to attach after the dialog launches and it still does not work. Any insight appreciated.
The part that works:
mounted() {
console.log(this.$refs)
//creates google maps automcomplete on the address inputs. Gets the addresses and saves them as well as getting the lat and long from each and saving them
for (let ref in this.$refs) {
const options = {
componentRestrictions: { country: 'us' },
fields: ['geometry', 'name', 'formatted_address'],
strictBounds: false,
types: ['address'],
}
const autocomplete = new google.maps.places.Autocomplete(
this.$refs[ref],
options
)
autocomplete.addListener('place_changed', () => {
// selected place object, bring up info such as address & geo coords
const place = autocomplete.getPlace()
// gets the address and lat/long from the found address and saves them to be used later when actually creating the order
if (ref == 'pickupAddress') {
this.pickupAddress = `${place.formatted_address}`
this.pickupPair = place.geometry.location
} else {
this.dropoffAddress = `${place.formatted_address}`
this.dropoffPair = place.geometry.location
}
})
}
this.$store.dispatch('getOpenOrders')
}
The dialog box
<v-row justify="center">
<v-dialog v-model="dialog" persistent max-width="600px">
<template v-slot:activator="{ on, attrs }">
<v-btn
color="rgb(216, 52, 125)"
dark
v-bind="attrs"
v-on="on"
style="margin-top: 10px"
#click="addRefs"
>
Add a leg to an existing order
</v-btn>
</template>
<v-card>
<v-card-title>
<span class="headline">Add a leg</span>
</v-card-title>
<v-card-text>
<v-container>
<v-row>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Order ID*"
required
v-model="legId"
hint="Order ID of the order you want to add a leg to"
persistent-hint
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field
label="Leg Letter (a-z)*"
required
v-model="legLetter"
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
label="Leg Pickup Address*"
ref="legPickupAddress"
required
v-model="legPickup"
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
label="Leg Dropoff Address*"
ref="legDropoffAddress"
required
v-model="legDropoff"
></v-text-field>
</v-col>
</v-row>
</v-container>
<small>*indicates required field</small>
<v-alert
class="v-alert"
v-if="noLegFoundAlert"
type="error"
dismissible
#click="noLegFoundAlert = !noLegFoundAlert"
>
No matching leg found, please enter another id or create a leg!
</v-alert>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn text #click="dialog = false"> Close </v-btn>
<v-btn text #click="addLeg"> Save </v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-row>
and finally the addRefs function which DOES NOT WORK
async addRefs() {
const options = {
componentRestrictions: { country: 'us' },
fields: ['geometry', 'name', 'formatted_address'],
strictBounds: false,
types: ['address'],
}
var input = this.$refs['legPickupAddres'] //DOES NOT WORK DOESNT EXIST APPARENTLY!!!!!!
const autocomplete1 = new google.maps.places.Autocomplete(input, options)
autocomplete1.addListener('place_changed', () => {
// selected place object, bring up info such as address & geo coords
const place = autocomplete.getPlace()
// gets the address and lat/long from the found address and saves them to be used later when actually creating the order
this.legPickup = `${place.formatted_address}`
})
}

v-list-item-group select all / deselect all items at once

I want to use Vuetify's v-list-item-group component for my Vue app. This list represents nodes that are related to a graph. I can select none, some or all of them and delete the selected ones.
For a better user experience I want to provide a "select all / deselect all" checkbox at the top next to the header. If only some nodes are selected, the checkbox should render the indeterminate state.
Currently this is the code I'm using
<div id="app">
<v-app id="inspire">
<v-list>
<v-list-item>
<v-list-item-action>
<v-checkbox :indeterminate="someNodesSelected" :input-value="allNodesSelected" #click="toggleCompleteSelection" />
</v-list-item-action>
<v-list-item-content>
<v-list-item-title v-text="graphWithNodes.name"></v-list-item-title>
</v-list-item-content>
<v-list-item-action>
<v-btn icon :disabled="noNodesSelected" #click="deleteNodes">
<v-icon color="error">mdi-delete</v-icon>
</v-btn>
</v-list-item-action>
</v-list-item>
<v-list-item-group v-model="selectedNodeIds" multiple>
<v-list-item v-for="node in graphWithNodes.nodes" :key="node.id" :value="node.id">
<template v-slot:default="{ active, toggle }">
<v-list-item-action>
<v-checkbox :input-value="active" :true-value="node.id" #click="toggle" />
</v-list-item-action>
<v-list-item-content>
<v-list-item-subtitle v-text="node.id"></v-list-item-subtitle>
</v-list-item-content>
</template>
</v-list-item>
</v-list-item-group>
</v-list>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
selectedNodeIds: [],
graphWithNodes: {
id: 1,
name: "The graph",
nodes: [{
id: 1,
graphId: 1
}, {
id: 2,
graphId: 1
}]
},
}
},
computed: {
noNodesSelected() {
return this.selectedNodeIds.length === 0;
},
someNodesSelected() {
return this.selectedNodeIds.length > 0 && !this.allNodesSelected;
},
allNodesSelected() {
return (
this.selectedNodeIds.length === this.graphWithNodes.nodes.length
);
}
},
methods: {
deleteNodes(nodeIds) {
for (const nodeId of this.selectedNodeIds) {
this.deleteNode(nodeId);
}
this.selectedQueueIds = [];
},
deleteNode(id) {
this.graphWithNodes.nodes = this.graphWithNodes.nodes.filter(node => node.id !== id);
},
toggleCompleteSelection() {
if(this.noNodesSelected || this.someNodesSelected) {
this.selectedNodeIds = this.graphWithNodes.nodes.map(node => node.id);
} else {
this.selectedNodeIds = [];
}
}
}
})
If you want to play around I created a codepen for this
https://codepen.io/magicfoobar/pen/RwPBNmV?editors=1010
So the problem I have is that when I click on the header checkbox the function toggleCompleteSelection gets executed twice and I can't figure out why.
Does someone know why the header checkbox is broken and how to fix it?
Thanks in advance
It works if you change the checkbox trigger from #click to #change
<v-checkbox
:indeterminate="someNodesSelected"
:input-value="allNodesSelected"
#change="toggleCompleteSelection" />
Just add .stop after the click and it works.
<v-checkbox :indeterminate="someNodesSelected" :input-value="allNodesSelected" #click.stop="toggleCompleteSelection" />
codepen - https://codepen.io/Pratik__007/pen/MWwBKRL?editors=1010
I'm not sure that you need to run toggleCompleteSelection directly from the checkbox.
I would achieve the "select all" functionality with a Watcher, see https://codepen.io/joffff/pen/06cd75ea651660d13d4ddc288b8448d7?editors=1010

Event when "select-all" button clicked in Vuetify

I'm currently implementing a data table using Vuetify, but I have stumbled into a problem while trying to react to a click on the "select-all" button in a data table. Right now, when the select-all button is clicked, the currently visible rows are selected (which is exactly what I want). However, I would like to be notified of the user clicking on this select-all button.
My plan is to provide the user with a "select everything" button, once the user clicks this "select-all" checkbox, but I can't seem to find a way (without having to reside to hacks) to get notified of a click on the "select-all" button.
There is a toggle-select-all method.
<div id="app">
<v-app id="inspire">
<v-data-table
:value="selected"
#toggle-select-all="selectAll"
:items-per-page="itemsPerPage"
:headers="headers"
:items="desserts"
item-key="name"
show-select
class="elevation-1"
>
</v-data-table>
<v-dialog>
<v-card>
</v-card>
</v-dialog>
</v-app>
</div>
Javascript is below:
new Vue({
el: '#app',
vuetify: new Vuetify(),
methods: {
selectAll(event) {
if (event.status) {
alert('selected all')
} else {
alert('deselected all')
}
}
},
data () {
return {
selected: [],
itemsPerPage: 10,
headers: ['headers', 'data'],
desserts: ['your', 'data']
}
}
})
You can do this by using :value and #input on the Vuetify table rather than v-model. Check if the selected array is equal to items per page when the user selects something.
<div id="app">
<v-app id="inspire">
<v-data-table
:value="selected"
#input="enterSelect($event)"
:items-per-page="itemsPerPage"
:headers="headers"
:items="desserts"
item-key="name"
show-select
class="elevation-1"
>
</v-data-table>
<v-dialog>
<v-card>
</v-card>
</v-dialog>
</v-app>
</div>
Javascript is below:
new Vue({
el: '#app',
vuetify: new Vuetify(),
methods: {
enterSelect(values) {
if (values.length == this.itemsPerPage) {
alert('selected all')
}
}
},
data () {
return {
selected: [],
itemsPerPage: 10,
headers: ['headers', 'data'],
desserts: ['your', 'data']
}
}
})
Working example here: https://codepen.io/CodingDeer/pen/QWLyaog?editors=1010

Categories