How to pass value from Vue prompt to JS variable - javascript

I am using the Buefy UI Components and would like to pass on the $(value) outside the function to use it in an alert(thevalue) or something like that. Tried to find a solution out there, but haven't found a helpful one. So I am very thankful for your support on this!
<template>
<section>
<div class="buttons">
<button
class="button is-medium is-dark"
#click="prompt">
Launch prompt (default)
</button>
</div>
</section>
</template>
<script>
export default {
methods: {
prompt() {
this.$buefy.dialog.prompt({
message: `What's your name?`,
inputAttrs: {
placeholder: 'e.g. Walter',
maxlength: 10
},
trapFocus: true,
onConfirm: (value) => this.$buefy.toast.open(`Your name is: ${value}`)
})
}
}
}
</script>

You can store the value inside the data and call it later by other methods.
Haven't tested this yet, but it should work:
<template>
<section>
<div class="buttons">
<button
class="button is-medium is-dark"
#click="prompt">
Launch prompt (default)
</button>
</div>
</section>
</template>
<script>
export default {
data() {
return {
name: ""
}
},
methods: {
prompt() {
this.$buefy.dialog.prompt({
message: `What's your name?`,
inputAttrs: {
placeholder: 'e.g. Walter',
maxlength: 10
},
trapFocus: true,
onConfirm: (value) => {
// Set name
this.name = value;
this.$buefy.toast.open(`Your name is: ${value}`);
}
})
},
other() {
alert(this.name);
}
}
}
</script>

Related

Vue.js - How to dynamically bind v-model to route parameters based on state

I'm building an application to power the backend of a website for a restaurant chain. Users will need to edit page content and images. The site is fairly complex and there are lots of nested pages and sections within those pages. Rather than hardcode templates to edit each page and section, I'm trying to make a standard template that can edit all pages based on data from the route.
I'm getting stuck on the v-model for my text input.
Here's my router code:
{
path: '/dashboard/:id/sections/:section',
name: 'section',
component: () => import('../views/Dashboard/Restaurants/Restaurant/Sections/Section.vue'),
meta: {
requiresAuth: true
},
},
Then, in my Section.vue, here is my input with the v-model. In this case, I'm trying to edit the Welcome section of a restaurant. If I was building just a page to edit the Welcome text, it would work no problem.:
<vue-editor v-model="restInfo.welcome" placeholder="Update Text"></vue-editor>
This issue is that I need to reference the "welcome" part of the v-model dynamically, because I've got about 40 Sections to deal with.
I can reference the Section to edit with this.$route.params.section. It would be great if I could use v-model="restInfo. + section", but that doesn't work.
Is there a way to update v-model based on the route parameters?
Thanks!
Update...
Here is my entire Section.vue
<template>
<div>
<Breadcrumbs :items="crumbs" />
<div v-if="restInfo">
<h3>Update {{section}}</h3>
<div class="flex flex-wrap">
<div class="form__content">
<form #submit.prevent>
<vue-editor v-model="restInfo.welcome" placeholder="Update Text"></vue-editor>
<div class="flex">
<button class="btn btn__primary mb-3" #click="editText()">
Update
<transition name="fade">
<span class="ml-2" v-if="performingRequest">
<i class="fa fa-spinner fa-spin"></i>
</span>
</transition>
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import { VueEditor } from "vue2-editor"
import Loader from '#/components/Loader.vue'
import Breadcrumbs from '#/components/Breadcrumbs.vue'
export default {
data() {
return {
performingRequest: false,
}
},
created () {
this.$store.dispatch("getRestFromId", this.$route.params.id);
},
computed: {
...mapState(['currentUser', 'restInfo']),
section() {
return this.$route.params.section
},
identifier() {
return this.restInfo.id
},
model() {
return this.restInfo.id + `.` + this.section
},
crumbs () {
if (this.restInfo) {
let rest = this.restInfo
let crumbsArray = []
let step1 = { title: "Dashboard", to: { name: "dashboard"}}
let step2 = { title: rest.name, to: { name: "resthome"}}
let step3 = { title: 'Page Sections', to: { name: 'restsections'}}
let step4 = { title: this.$route.params.section, to: false}
crumbsArray.push(step1)
crumbsArray.push(step2)
crumbsArray.push(step3)
crumbsArray.push(step4)
return crumbsArray
} else {
return []
}
},
},
methods: {
editText() {
this.performingRequest = true
this.$store.dispatch("updateRest", {
id: this.rest.id,
content: this.rest
});
setTimeout(() => {
this.performingRequest = false
}, 2000)
}
},
components: {
Loader,
VueEditor,
Breadcrumbs
},
beforeDestroy(){
this.performingRequest = false
delete this.performingRequest
}
}
</script>
Try to use the brackets accessor [] instead of . :
<vue-editor v-model="restInfo[section]"

My component template can't find value property from <script> VueJS

So for some reason my app doesn't read my value variable that was defined in data. Not sure what's going on. Npm compiles this without any errors.
Here's the fiddle with my code:
https://jsfiddle.net/invinivi/yr164pb7/
<template>
<div id="exercise">
<div>
<p>Current Value: {‌{ value }}</p>
<button #click="value += 5">Add 5</button>
<button #click="value += 1">Add 1</button>
<p>{‌{ result }}</p>
</div>
<div>
<input type="text">
<p>{‌{ value }}</p>
</div>
</div>
</template>
<script>
export default {
name: 'Ex3',
el: '#exercise',
data: function () {
return {
value: 0
}
},
computed: {
result: function () {
return this.value == 37 ? 'done' : 'not there yet';
}
},
watch: {
result: function () {
var vm = this;
setTimeout(function () {
vm.value = 0;
}, 5000);
}
}
}
</script>
// FILE - Ex3.vue
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<div id="app">
<Ex3/>
</div>
</template>
<script>
import Ex3 from "./components/Ex3"
export default {
name: 'App',
components: {
Ex3
}
}
</script>
The curly brackets had wrong encoding through Windows settings. After changing the settings to utf-8, everything runs fine.

Why does javascript assume that a function is a variable?

Well, I just noticed that JS somehow takes a function as a variable in my code. Here is it:
<template>
<div id="">
<div>
<input type="text" v-model="value">
<button v-on:click='[factorial(), show=!show]'>Factorial</button>
<span v-show="show">{{value}}</span>
</div>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
value : 0,
show: false
}
},
methods: {
},
computed: {
factorial(x=this.value){
if (!x){return 1}
else {return x*factorial(x-1)}
}
},
mounted() {}
}
</script>
<style lang="scss">
</style>
The error is ReferenceError: Can't find variable: factorial.
What am I doing wrong?
You cannot pass arguments to computed properties, that is what methods are for.
You also need to use this when calling the function.
methods: {
factorial(x) {
if (!x) {
x = this.value;
}
return x * this.factorial(x-1);
},
},
You mustn't use factorial() as a computed function. You should instead make it a method:
<template>
<div id="">
<div>
<input type="text" v-model="value">
<button v-on:click='[factorial(), show=!show]'>Factorial</button>
<span v-show="show">{{value}}</span>
</div>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
value : 0,
show: false
}
},
methods: {
factorial(x=this.value){
if (!x){return 1}
else {return x * this.factorial(x-1)}
}
},
}
</script>
Here is a working sandbox for you:
https://codesandbox.io/s/lingering-voice-p6d9l

How to write a plugin that shows a modal popup using vue. Call should be made as a function()

I am trying to make a VueJS plugin that exports a global method, which when called, will popup a message with an input text field. Ideally, I want to be able to make the following call from any Vue component:
this.$disaplayMessageWithInput("Title","Body","Value");
And a popup should come on the screen.
I've tried building it but when the install() calls this.$ref., it isn't recognized:
DeleteConfirmation.vue
<template>
<b-modal size="lg" ref="deleteConfirmationModal" :title="this.title" header-bg-variant="danger" #ok="confirmDelete" #cancel="confirmCancel">
<p>
{{this.body}}
</p>
</b-modal>
</template>
<script>
export default {
data()
{
return {
title: null,
body: null,
valueCheck: null,
value: null
};
},
install(vue, options)
{
Vue.prototype.$deleteConfirmation = function(title, body, expectedValue)
{
this.title = title;
this.body = body;
this.valueCheck = expectedValue;
this.$refs.$deleteConfirmation.show()
}
},
}
</script>
app.js
import DeleteConfirmation from './components/global/DeleteConfirmation/DeleteConfirmation';
Vue.use(DeleteConfirmation);
The call I am trying to make is:
$vm0.$deleteConfirmation("title","body","val");
I get the below error at the run time:
app.js?id=c27b2799e01554aae7e1:33 Uncaught TypeError: Cannot read property 'show' of undefined
at Vue.$deleteConfirmation (app.js?id=c27b2799e01554aae7e1:33)
at <anonymous>:1:6
Vue.$deleteConfirmation # app.js?id=c27b2799e01554aae7e1:33
(anonymous) # VM1481:1
It looks like, this.$refs in DeleteConfirmation.vue is undefined.
Try to avoiding $ref with vue ( $ref is here for third party and some very special case )
$ref isn't reactive and is populate after the render ...
the best solution for me is using a event bus like this :
const EventBus = new Vue({
name: 'EventBus',
});
Vue.set(Vue.prototype, '$bus', EventBus);
And then use the event bus for calling function of your modal ...
(
this.$bus.on('event-name', callback) / this.$bus.off('event-name');
this.$bus.$emit('event-name', payload);
)
You can create a little wrapper around the bootstrap modal like mine
( exept a use the sweet-modal)
<template>
<div>
<sweet-modal
:ref="modalUid"
:title="title"
:width="width"
:class="klass"
class="modal-form"
#open="onModalOpen"
#close="onModalClose"
>
<slot />
</sweet-modal>
</div>
</template>
<script>
export default {
name: 'TModal',
props: {
eventId: {
type: String,
default: null,
},
title: {
type: String,
default: null,
},
width: {
type: String,
default: null,
},
klass: {
type: String,
default: '',
},
},
computed: {
modalUid() {
return `${this._uid}_modal`; // eslint-disable-line no-underscore-dangle
},
modalRef() {
return this.$refs[this.modalUid];
},
},
mounted() {
if (this.eventId !== null) {
this.$bus.$on([this.eventName('open'), this.eventName('close')], this.catchModalArguments);
this.$bus.$on(this.eventName('open'), this.modalRef ? this.modalRef.open : this._.noop);
this.$bus.$on(this.eventName('close'), this.modalRef ? this.modalRef.close : this._.noop);
}
},
beforeDestroy() {
if (this.eventId !== null) {
this.$off([this.eventName('open'), this.eventName('close')]);
}
},
methods: {
onModalOpen() {
this.$bus.$emit(this.eventName('opened'), ...this.modalRef.args);
},
onModalClose() {
if (this.modalRef.is_open) {
this.$bus.$emit(this.eventName('closed'), ...this.modalRef.args);
}
},
eventName(action) {
return `t-event.t-modal.${this.eventId}.${action}`;
},
catchModalArguments(...args) {
if (this.modalRef) {
this.modalRef.args = args || [];
}
},
},
};
</script>
<style lang="scss" scoped>
/deep/ .sweet-modal {
.sweet-title > h2 {
line-height: 64px !important;
margin: 0 !important;
}
}
</style>
AppModal.vue
<template>
<div class="modal-wrapper" v-if="visible">
<h2>{{ title }}</h2>
<p>{{ text }}</p>
<div class="modal-buttons">
<button class="modal-button" #click="hide">Close</button>
<button class="modal-button" #click="confirm">Confirm</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
visible: false,
title: '',
text: ''
}
},
methods: {
hide() {
this.visible = false;
},
}
}
</script>
Modal.js (plugin)
import AppModal from 'AppModal.vue'
const Modal = {
install(Vue, options) {
this.EventBus = new Vue()
Vue.component('app-modal', AppModal)
Vue.prototype.$modal = {
show(params) {
Modal.EventBus.$emit('show', params)
}
}
}
}
export default Modal
main.js
import Modal from 'plugin.js'
// ...
Vue.use(Modal)
App.vue
<template>
<div id="app">
// ...
<app-modal/>
</div>
</template>
This looks pretty complicated. Why don't you use a ready-to-use popup component like this one? https://www.npmjs.com/package/#soldeplata/popper-vue

Synchronize result with value changed in vue.js

I wrote .vue file like below to change h1#msg after 100ms.
<template>
<div id="main">
<h1 id="msg">{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'Top',
data () {
let a=['TEST']
setTimeout((function(a){a[0]='test'}),100)
return {
msg: a
}
}
}
</script>
<style>
</style>
However I cannot change state by this code. I tried to use Array to pass value by reference.
I don't like to use querySelector(), because it forces me to add attitude in HTML and arguments for methods.
Dont write javascript inside data(), the correct is this code:
<script>
export default {
name: 'top',
data () {
return {
msg: 'test'
}
}
mounted() {
setTimeout(() => this.msg = 'Bu!', 100)
}
}
</script>
Try this code snippets
<template>
<div id="main">
<h1 id="msg">{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'Top',
data () {
return {
msg: 'a'
}
},
created() {
setTimeout(() => this.msg = 'Hello World!', 100)
}
}
</script>
Your data should just declare the variable to whatever you want it to be before the change. Then do the timeout in mounted.

Categories

Resources