Vue vuetify Dialog How to tigger dialog component without click - vue.js

How can I tigger the dialog from main file? I have no idea how to tigg ConfirmationDialog value "dislog" to true. Or any other method to do it? Dont want to group the code as a one file.
That is a component called ConfirmationDialog.vue
<template>
<v-layout row justify-center>
<v-btn color="primary" dark #click.native.stop="dialog = true">Open Dialog</v-btn>
<v-dialog v-model="dialog" max-width="290">
<v-card>
<v-card-title class="headline">Use Google's location service?</v-card-title>
<v-card-text>Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running.</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="green darken-1"
flat="flat"
#click.native="dialog = false"
>Disagree</v-btn>
<v-btn color="green darken-1" flat="flat" #click.native="dialog = false">Agree</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-layout>
</template>
<script>
export default {
data() {
return {
dialog: false
}
}
}
</script>
Main File:
<template>
<div class="row">
<div class="col-12">
<confirmationDialog></confirmationDialog>
</div>
</div>
</template>
<script>
import confirmationDialog from '../confirmationDialog'
export default {
data() {
return {}
},
components: {
confirmationDialog
},
methods: {
update() {
// Todo: Tigger Confirmation Dislog
}
},
}
</script>

Add a prop called show to the child component (confirmationDialog ) and bind to a parent property :
confirmationDialog
...
<script>
export default {
props:['show'],
data() {
return {
dialog: false
}
},
mounted(){
this.dialog=this.show;
}
}
</script>
Main
<template>
<div class="row">
<div class="col-12">
<confirmationDialog :show="showDialog"></confirmationDialog>
</div>
</div>
</template>
<script>
import confirmationDialog from '../confirmationDialog'
export default {
data() {
return {
showDialog:false,
}
},
components: {
confirmationDialog
},
methods: {
update() {
this.showDialog=true;
}
},
}
</script>

Related

How do I capture the value of the prop in the text field?

I have a prop and currently am able to get the data of the prop, Am trying a way to capture the item of the prop when saving the form.
Is there a way where i can take the value and pass if in a hidden text-area and bind the data to the vmodel?
Any help I appreciate.
<v-dialog v-model="dialog" persistent max-width="800">
<template v-slot:activator="{ on }">
<v-btn dark v-on="on" color="primary" round> Make payment </v-btn>
</template>
<v-card>
<v-card-title class="headline primary">
<span class="white--text">Add a new Doctor Payment Record {{ queueId }}</span>
<v-btn icon dark #click.native="dialog = false" absolute right>
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-card-text>
<users-search
:leave-selected="true"
idOnly
label="Select Doctor"
#results="setDoctor"
>
</users-search>
<div class="row px-3">
<v-autocomplete
class="px-3 col-sm-8"
v-model="expense.bank"
v-if="banks.data"
:items="banks.data"
outline
chips
label="Select bank"
item-text="name"
item-value="id"
>
</v-autocomplete>
<v-text-field
class="px-3 col-sm-8"
outline
flat
v-model="expense.amount"
type="number"
#input="expense.percentage()"
required
label="Amount *"
persistent-hint
/>
</div>
<v-text-field
class="px-3"
outline
flat
v-model="expense.total_paid"
required
label="amount paid"
persistent-hint
/>
<v-text-field
class="px-3"
outline
flat
:value="setQueue"
v-model="expense.queueId"
required
:label=queueId
persistent-hint
/>
<v-alert :value="true" type="error" v-if="errors.any()">
<div v-html="errors.display()"></div>
</v-alert>
<v-layout row wrap>
<v-flex xs12>
<v-btn
color="success"
:loading="saveLoader"
#click="recordExpense()"
>save</v-btn
>
</v-flex>
</v-layout>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script>
import NewUser from "#finance/libs/users/NewUser";
import {mapActions, mapGetters} from "vuex";
export default {
props: [
'queueId'
],
data: () => ({
dialog: false,
expense: new NewUser(),
saveLoader: false,
}),
computed: {
...mapGetters({
banks: "getBanks",
}),
balance: function () {
return parseFloat(10);
},
submitted() {
return this.expense.form.submitted;
},
contaminated() {
return this.expense.form.errorDetected;
},
errors() {
return this.expense.form.errors;
},
},
watch: {
submitted(v) {
if (v) {
this.saveLoader = false;
}
},
contaminated() {
this.saveLoader = false;
},
},
methods: {
...mapActions({
fetchBanks: "setBanks",
}),
setDoctor(user) {
this.expense.doctor_id = user.id;
},
setQueue(){
console.log(this.queueId);
this.expense.queueId = this.queueId;
},
async recordExpense() {
this.saveLoader = true;
let response = await this.expense.saveExpense();
this.saveLoader = false;
if (response) {
this.dialog = false;
this.$emit("expenseCreated");
}
},
},
mounted() {
this.fetchBanks();
}
};
</script>
The prop queueId i also want to store it along with the user information from the form.
Try this one, it should work:
<template>
<textarea v-model="hiddenValue" :style="{ display: 'none' }"></textarea>
</template>
<script>
export default {
props: [ 'queueId' ],
data() {
return {
hiddenValue: this.queueId
}
}
}
</script>
In case you will no need the prop to be modified, please bind the texarea value to the prop directly:
<textarea hidden v-model="queueId" :style="{ display: 'none' }></textarea>

Copy text upon clicking on icon in v-text-field

I'm trying to figure out how to allow users to copy their login details when they click the copy icon. How to get the value of the relevant v-text-field?
I thought I should use #click:append and link it to a method. However, I struggle how to get a value.
<template>
<v-card class="col-12 col-md-8 col-lg-6 p-6 px-16" elevation="4">
<div class="title h2 mb-10 text-uppercase text-center">
Success
<v-icon color="green" x-large>
mdi-check-circle
</v-icon>
</div>
<v-text-field
:value="newAccount.login"
label="Login"
outlined
readonly
append-icon="mdi-content-copy"
#click:append="copy('login')"
></v-text-field>
<v-text-field
:value="newAccount.password"
label="Password"
outlined
readonly
append-icon="mdi-content-copy"
></v-text-field>
</v-card>
</template>
<script>
export default {
props: ["newAccount"],
data() {
return {
copied: false,
};
},
methods: {
copy(target) {
if (target === "login") {
console.log("login is clicked");
}
},
},
computed: {},
};
</script>
The value of the v-text-field is available from its value property. Apply a template ref on the v-text-field to get a reference to the component programmatically from vm.$refs, then use .value off of that:
<template>
<v-text-field
ref="login"
#click:append="copy('login')"
></v-text-field>
</template>
<script>
export default {
methods: {
copy(field) {
console.log('value', this.$refs[field].value)
}
}
}
</script>
Alternatively, you could access the nested template ref of v-text-field's <input>, which has a ref named "input", so copy() would access it from this.$refs[field].$refs.input. Then, you could select() the text value, and execute a copy command:
export default {
methods: {
copy(field) {
const input = this.$refs[field].$refs.input
input.select()
document.execCommand('copy')
input.setSelectionRange(0,0) // unselect
}
}
}
demo

how to implement a reusable vuetify dialog

I want to create a reusable v-dialog with vuetify,
I created the BaseModal:
<v-dialog
v-model="inputVal"
:hide-overlay="overlay"
:max-width="width"
>
<v-card>
<v-toolbar flat>
<v-btn color="black" dark icon right #click="closeModal">
<v-icon>mdi-close</v-icon>
</v-btn>
<v-spacer></v-spacer>
<v-toolbar-title id="toolbar-title">{{ title }}</v-toolbar-title>
</v-toolbar>
<v-card-title class="headline">
<!--Card Title-->
</v-card-title>
<v-card-text>
<slot name="content"></slot>
</v-card-text>
</v-card>
</v-dialog>
InputVal as computed and dataBindingName as props :
computed: {
inputVal: {
get() {
return this.dataBindingName;
},
set(val) {
this.$emit("input", val);
}
}
},
props: {
dataBindingName: {
Boolean,
required: false
},}
I'm calling this base component in another component like this:
<modal-simple
:dataBindingName="dataBindingName"
title="Nouveau"
width="418"
>
<template v-slot:content>
<add-time-sheet-form />
</template>
</modal-simple>
My problem now is how to implement correctly the closeModal and how to implement a button inside that close the modal and open a new modal
Part 1. Modal component.
Take care that you should not use v-model="dialog". As already described in this answer, you need to replace it with :value and #input.
Moreover, you should not mutate dialog prop directly, that's why you need to emit close-dialog event when you need to close your modal.
<template>
<v-dialog
:value="dialog"
#input="$emit('input', $event)"
max-width="500px"
persistent
>
<v-card>
<v-card-title>
... dialog header ...
</v-card-title>
<v-card-text>
... dialog content ...
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn #click="close">
Close
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
props: {
editedId: Number,
dialog: Boolean,
},
methods: {
close() {
this.$emit("close-dialog");
},
},
};
</script>
Part 2. Parent component.
Imagine you want to use your component when adding or editing entities.
You need to implement two methods: addItem and editItem to open your dialog. You also need to pass extra entity props (editedId in my example), dialog prop with sync modifier and close-dialog event handler that was emitted from modal component.
<template>
<div>
<v-toolbar flat color="white">
<v-spacer />
<edit-modal
:edited-id="editedId"
:dialog.sync="dialog"
#close-dialog="
editedId = null;
dialog = false;
"
/>
<v-btn color="primary" dark class="mb-2" #click="addItem">
Add entity
</v-btn>
</v-toolbar>
<v-data-table :items="items" :headers="headers">
<template v-slot:item="props">
<tr>
<td>{{ props.item.name }}</td>
<td class="justify-center text-center">
<v-icon small class="mr-2" #click="editItem(props.item)">
edit
</v-icon>
</td>
</tr>
</template>
</v-data-table>
</div>
</template>
<script>
import Dialog from "./ReusableDialog";
export default {
components: {
"edit-modal": Dialog,
},
data() {
return {
items: [
... some items ...
],
headers: [
... some headers ...
],
editedId: null,
dialog: false,
};
},
methods: {
addItem() {
this.dialog = true;
},
editItem(item) {
this.editedId = item.id;
this.dialog = true;
},
},
};
</script>
Part 3. Modifying modal to reopen automatically.
In this example, modal component will reopen automatically until editedId will not be set.
In modal component:
...
close() {
this.$emit("close-dialog");
if (this.editedId === null) {
this.$emit("open-dialog");
}
},
...
In parent component:
...
<edit-modal
... some props ...
#open-dialog="
editedId = 999;
dialog = true;
"
/>
...
There is a codesandbox with working example.

Render Component in loop, use Index in method of child component (VueJS)

I have two components where some exchange of props takes place. Props is the whole todo array, which is updated by a click on the button with the "addTodo" method. Passing the array down to the child works fine. I can display the props dynamically in my p-tags, but it seems to be not possible to use it my the methods of my child component.
<template>
<v-app>
<v-content>
<h2>Add a Todo</h2>
<v-col cols="12" sm="6" md="3">
<v-text-field label="Regular" v-model="text"></v-text-field>
</v-col>
<div class="my-3">
<v-btn medium #click="addTodo">Add Todo</v-btn>
</div>
<div v-for="(todo, index) in todos" v-bind:key="index">
<HelloWorld
v-bind:todos="todos"
v-bind:index="index"
v-bind:class="(todos[index].done)?'green':'red'"
/>
</div>
</v-content>
</v-app>
</template>
<script>
import HelloWorld from "./components/ToDo.vue";
export default {
components: {
HelloWorld
},
data: function() {
return {
text: "",
todos: []
};
},
methods: {
addTodo() {
this.todos.push({
text: this.text,
done: false
});
}
}
};
</script>
This is my child component
<template>
<v-card max-width="250">
<v-card-text>
<h2 class="text-center">{{todos[index].text}}</h2>
<p class="display-1 text--primary"></p>
<p>{{index}}</p>
</v-card-text>
<v-card-actions>
<v-btn text color="deep-purple accent-4" #click="done"></v-btn>
<v-btn text color="orange accent-4">Delete Task</v-btn>
</v-card-actions>
</v-card>
</template>
<script>
export default {
props: ["todos", "index"],
methods: {
done() {
this.todos[1].text = "bla";
}
}
};
</script>
<style scoped>
.seperator {
display: flex;
justify-content: space-between;
}
</style>
I pass a whole array with objects as props, and using the index inside the p-tag works fine, but I also want to use it like this:
methods: {
done() {
this.todos[index].text = "bla";
}
}
'index' is not defined
Everything works fine, but I am not able use the index value inside the method. What am I doing wrong here?
The way you write it out, there is nothing in scope defining index. Where is that value coming from?
Index is a prop and so it must be referenced with this.
done () {
this.todos[this.index].text = 'bla'
}

vue-i18n translation for validation error working only after form reset in vuetify form

I'm using form validation in application, I want my validation error message to be translated. It is getting translated only after reset form.
I have tried translation in computed property, and it's working when I do
computed as below, but error message is not disappearing after touched:
{
return [this.$t('LANGUAGE')]
}
In App Component
<template>
<div id="app">
<grid_Component/>
<div class="locale-changer" style="background: black">
<select v-model="$i18n.locale">
<option v-for="(lang, i) in lang" :key="`Lang${i}`" :value="lang">{{
lang }}
</option>
</select>
</div>
</div>
</template>
<script>
import form_Component from './components/form_Component.vue'
import form_Component from './components/form_Component.vue'
import i18n from './i18n'
export default {
data () {
return{
lang: ['GB', 'NO']
}
},
name: 'app',
components: {
form_Component,
},
}
</script>
GB.json file
{
"LANGUAGE": "English"
}
NO.json file
{
"LANGUAGE": "Norwegian"
}
form component
<template>
<v-form ref="form" v-model="valid" lazy-validation>
<v-text-field v-model="name" :counter="10" :rules="nameRules"
label="Name" required>
</v-text-field>
<v-btn :disabled="!valid" color="success" #click="validate">
Validate
</v-btn>
<v-btn color="error" #click="reset">
Reset Form
</v-btn>
<v-btn color="warning" #click="resetValidation">
Reset Validation
</v-btn>
</v-form>
</template>
<script>
export default {
data: () => ({
valid: true,
name: '',
}),
methods: {
validate () {
if (this.$refs.form.validate()) {
this.snackbar = true
}
},
reset () {
this.$refs.form.reset()
},
resetValidation () {
this.$refs.form.resetValidation()
}
},
computed: {
nameRules(){
return [v => !!v || this.$t('LANGUAGE')]
}
}
}
</script>