Buefy modal Close button in header - javascript

everyone!
I have modal window on Buefy. This modal open when call method:
onEditHandler(selectedPlan) {
const Component = Vue.extend(Plan);
this.$buefy.modal.open({
parent: this,
component: Component,
hasModalCard: true,
trapFocus: true,
scroll: 'keep',
ariaModal: true,
customClass: 'dialog',
canCancel: 'x',
props: {
isActive: true,
plan: selectedPlan,
roles: this.roles,
plans: this.data,
},
events: {
submit() {
},
close() {
},
},
});
}
Plan contains code:
<template>
<validation-observer v-slot="{ handleSubmit }" ref="contactObserver">
<div class="modal-card">
<header class="modal-card-head">
<h2 class="modal-card-title">Name</h2>
</header>
<section class="modal-card-body">
<validation-provider v-slot="{ errors }" rules="required">
<b-field label="Name"
:type="{ 'is-danger': errors.length }"
:message="errors + [ ' ' ]">
<b-input v-model="name"></b-input>
</b-field>
</validation-provider>
</section>
<footer class="modal-card-foot">
<button class="button" type="button" #click="cancel">Cancel</button>
<button class="button is-success"
#click="handleSubmit(submit)">Update</button>
</footer>
</div>
</validation-observer>
</template>
<script>
</script>
In Result open modal who has close button in right top corner (the image pinned in message)
Main question: How do I move the close btn to the modal window?
Thank's for answers
Modal dialog

You can add a close button on the modal's header like this:
...
<header class="modal-card-head">
<h2 class="modal-card-title">Name</h2>
<button type="button" class="delete" #click="handleCancel" />
</header>
...
And there is method handleCancle() for exmaple:
handleCancel: function() {
this.$refs.contactObserver.reset();
this.$parent.close();
},

I solved problem so:
onEditHandler(selectedPlan) {
const Component = Vue.extend(Plan);
this.$buefy.modal.open({
parent: this,
component: Component,
hasModalCard: true,
trapFocus: true,
scroll: 'keep',
ariaModal: true,
customClass: 'card-form-modal',
canCancel: ['outside'],
props: {
plan: selectedPlan,
roles: this.roles,
plans: this.data,
},
events: {
submit() {
},
close() {
}
},
});
this.changeModalPosition();
}
and Plan contains
<template>
<validation-observer v-slot="{ handleSubmit }" ref="contactObserver">
<div class="modal-card">
<header class="modal-card-head">
<h2 class="modal-card-title">Name</h2>
<button class="modal-close is-large" #click="$emit('close')"></button>
</header>
<section class="modal-card-body">
<validation-provider v-slot="{ errors }" rules="required">
<b-field label="Name"
:type="{ 'is-danger': errors.length }"
:message="errors + [ ' ' ]">
<b-input v-model="name"></b-input>
</b-field>
</validation-provider>
</section>
<footer class="modal-card-foot buttons is-right">
<button class="button" type="button" #click="cancel">Cancel</button>
<button class="button is-success"
#click="handleSubmit(submit)">Update</button>
</footer>
</div>
</validation-observer>
And screenshot
a comment that helped to understand
enter link description here

Related

Using t translation on props in Vue with vue i18n

I would like to translate the titles that are passed to my component via props. However I assume because my strings are being passed via props they are not being translated like the rest of my code. Below you will find my current 2 components that I am working with:
Parent Component:
`<setting-section
:title="$t('Random Text 1')"
:description="$t('Random Text 2')"
>`
In the Child:
`<template>
<div class="flex grid w-full">
<div class="divider mr-4 mt-5" />
<div class="header col-2">
<div class="title text-primary">{{ title }}</div>
<div class="description text-xs">{{ description }}</div>
</div>
<div class="flex col-10" v-if="!isLoading">
<slot />
</div>
<div class="flex col-10" v-else>
<Skeleton height="5rem" />
</div>
</div>
</template>
<script>
export default {
name: 'Menu',
props: {
title: {
type: String,
default: '',
},
description: {
type: String,
default: '',
},
},
};
</script>`
How ever if I do add the below variation it obviously wont work.
`<template>
<div class="flex grid w-full">
<div class="header col-2">
<div class="title text-primary">{{ $t('title')}} </div>
<div class="description text-xs">{{ description }}</div>
</div>
</div>
</template>`
Your both the solutions should work as we always configured VueI18n at global level. Hence, translation literals always accessible from any nested component.
Live Demo as per both the use cases :
Vue.component('child-one', {
props: ['childmsg'],
template: '<p>{{ childmsg }}</p>'
});
Vue.component('child-two', {
template: `<p>{{ $t('message') }}</p>`
});
Vue.use(VueI18n);
const i18n = new VueI18n({
locale: 'ja',
fallbackLocale: 'en',
messages: {
"ja": {
"message": "こんにちは、世界"
},
"en": {
"message": "Hello World"
}
}
});
new Vue({
el: "#app",
i18n,
data() {
return {
locale: "ja"
}
},
watch: {
locale(newLocale) {
this.$i18n.locale = newLocale;
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.8/dist/vue.min.js"></script>
<script src="https://unpkg.com/vue-i18n#8.8.2/dist/vue-i18n.min.js"></script>
<main id="app">
<div>
<label><input type="radio" value="ja" v-model="locale" />Japanese</label>
<label><input type="radio" value="en" v-model="locale" />English</label>
</div>
<h3>Passing translated string from parent</h3>
<child-one :childmsg="$t('message')"></child-one>
<h3>Transaltions happens in child component itself</h3>
<child-two></child-two>
</main>

Validate fields Steps Buefy and block next button until completing required

Hello I have a request in vue.js where b-input is required, if not it cannot continue, I've tried
required
validation-message="name required"
in b-step-item, also in the watch event.
watch: {
activeStep(step) {
this.ValidationSteps()
},
},
methods: {
ValidationSteps() {
this.erros = []
if (this.nameField === '') {
this.erros.push({ description: 'Field is required' })
}
},
},
but I still can't get the field to continue.
This is my code, then I'll fix how the error messages appear below the field. (if it is possible to give the solution).
I've searched and I can't find the solution in the documentation
<template>
<section>
<b-steps v-model="activeStep" :has-navigation="false">
<b-step-item step="1" label="Account" :clickable="isStepsClickable">
<h1 class="title has-text-centered">Account</h1>
<b-input
v-model="NombreCampo"
placeholder="Enter field name"
required
validation-message="name required"
></b-input>
<article v-if="erros.length > 0" class="message is-danger">
<div class="message-header">
<p>Error ({{ erros.length }})</p>
</div>
<div class="message-body">
<div class="content">
<ul>
<li v-for="(db, index) in erros" :key="index">
{{ db.description }}
</li>
</ul>
</div>
</div>
</article>
</b-step-item>
<b-step-item
step="2"
label="Profile"
:clickable="true"
:type="{ 'is-success': true }"
>
<h1 class="title has-text-centered">Profile</h1>
</b-step-item>
<template #navigation="{ previous, next }">
<b-button
:disabled="previous.disabled"
#click.prevent="previous.action"
>
Previous
</b-button>
<b-button :disabled="next.disabled" #click.prevent="next.action">
Next
</b-button>
</template>
</b-steps>
</section>
</template>
<script>
export default {
data() {
return {
activeStep: 0,
erros: [],
nameField: '',
}
},
watch: {
activeStep(step) {
this.ValidationSteps()
},
},
methods: {
ValidationSteps() {
this.erros = []
if (this.nameField === '') {
this.erros.push({ description: 'Field is required' })
}
},
},
}
</script>
Any suggestion or solution would be appreciated.

Bootstrap Vue modal causing page jump on close / safari issue

When I close my bootstrap vue modal it causes a page jump to the section that has the open modal triggers which is fine. In Safari it is jumping well above the section where the triggers are. Is there a way to add a prevent default or similiar that will stop the page jumping when the modal is closed?
<template>
<b-modal
:visible="visible"
size="lg"
centered
#hidden="closeModal"
hide-footer
>
<p>
modal body
</p>
<template>
<div class="w-100">
<b-button
class="btn btn-icon"
#click.prevent="closeModal"
>
<span class="l-btn float-left">
<span class="btn-text">Cancel</span>
<i class="btn-icon-symbol"></i>
</span>
</b-button>
<a
:href="$store.state.modals.interstitial.href"
target="_blank"
class="btn btn-icon btn-icon-arrow"
>
<span class="l-btn float-left">
<span class="btn-text text-white">OK</span>
<i class="btn-icon-symbol text-white"></i>
</span>
</a>
</div>
</template>
</b-modal>
</template>
<script>
import { BButton } from 'bootstrap-vue';
export default {
name: 'Modal',
components: {
'b-button': BButton,
},
computed: {
visible() {
return this.$store.state.modals.interstitial.show;
},
},
methods: {
closeModal() {
this.$store.commit('modals/setShowModal', false);
this.$store.commit('modals/setModalHref', '');
},
},
};
</script>

How to toggle between two components by using v-if directives in vue.js?

i have two components Register.vue and Login.vue ,Register.vue is responsible for registration it will contain two headings like Login and Signup ,if the user clicks on Login heading inside the Register page it's automatically hide the Signup(Register.vue) component and it displays the Login.vue , upto this it's working fine[Register.vue page when user clicks on Login thing it should opens Login page ]1.[After clicking Login heading it opens like this ]2in Login page also two headings Login and Signup if the user clicks on the signup heading it will hide the login.vue component and it should display the Register.vue ,it's not working How to fix this thing
Register.vue
<template>
<div class="main">
<div v-if="flag==true" class="container">
<img id="side-img" src="../assets/sideImg.png" alt="notFound" />
<p id="side-content">Online Book Shopping</p>
<div class="box">
<div class="headings">
<h5 class="signin" v-on:click="flip()" id="login" :class="{ active: isLogin }" #click="isLogin = true">Login</h5>
<h5 class="signup" id="signup" :class="{ active: !isLogin }" #click="isLogin = false">signup</h5>
</div>
<form ref="myForm" #submit.prevent="handlesubmit">
<div class="fullname">
<p>FullName</p>
<input type="name" id="name-input" class="namebox" required v-model="fullName" autocomplete="off" pattern="[A-Za-z]{3,12}">
</div>
<div class="username">
<p>EmailID</p>
<input type="email" id="Email-input" class="emailbox" autocomplete="off" required v-model="email" pattern="^[a-z0-9._%+-]+#[a-z0-9.-]+\.[a-z]{2,4}$">
</div>
<div class="password-section">
<p>Password</p>
<input :type="password_type" class="password" :class="{'password-visible': isPasswordVisible }" id="passField" v-model="password" pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$!%*?&])[A-Za-z\d#$!%*?&]{6,}$" required>
<i class="bi bi-eye-slash" id="togglePassword" #click="togglePassword();"></i>
</div>
<div class="mobile">
<p>MobileNumber</p>
<input type="tel" class="telephone" autocomplete="off" v-model="mobile" id="tel" pattern="^\d{10}$" required>
</div>
<button class="btn-section" id="btn" type="submit">Signup</button>
</form>
</div>
</div>
<Login v-if="flag==false" />
</div>
</template>
<script>
import Login from './Login.vue'
import service from '../service/User'
export default {
name: 'Register',
components: {
Login
},
data() {
return {
fullName: '',
email: '',
password: '',
mobile: '',
password_type: "password",
isLogin: false,
isPasswordVisible: false,
flag: true,
title: 'Online Book Shopping'
}
},
methods: {
flip() {
this.flag = !this.flag;
},
togglePassword() {
this.password_type = this.password_type === 'password' ? 'text' : 'password'
this.isPasswordVisible = !this.isPasswordVisible
},
handlesubmit() {
let userData = {
fullName: this.fullName,
email: this.email,
password: this.password,
mobile: this.mobile
}
service.userRegister(userData).then(response => {
if (response.status == 201) {
alert("user registered successfully");
this.$refs.myForm.reset();
this.$router.push('/login');
}
return response;
}).catch(error => {
alert("invalid credentials");
return error;
})
}
}
}
</script>
Login.vue
<template>
<div class="main">
<div v-if="flag" class="container">
<img id="side-img" src="../assets/sideImg.png" alt="notFound" />
<p id="side-content">Online Book Shopping</p>
<div class="box">
<div class="headings">
<h5 class="signin" :class="{ active: !isSignup }" #click="isSignup = false">Login</h5>
<!-- <router-link to="/register">
<h5 class="signup" id="signup" :class="{ active: !isLogin }" #click="isLogin = false">signup</h5>
</router-link> -->
<h5 class="signup" id="signup" v-on:click="flip();" :class="{ active: isSignup }" #click="isSignup = true">signup</h5>
</div>
<form #submit.prevent="">
<div class="username">
<p>EmailID</p>
<input type="email" id="Email-input" class="emailbox" autocomplete="off" required v-model="email" pattern="^[a-z0-9._%+-]+#[a-z0-9.-]+\.[a-z]{2,4}$">
</div>
<div class="password-section">
<p>Password</p>
<input :type="password_type" class="password" :class="{'password-visible': isPasswordVisible}" id="passField" v-model="password" pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$!%*?&])[A-Za-z\d#$!%*?&]{6,}$" required>
<i class="bi bi-eye-slash" id="togglePassword" #click="togglePassword();"></i>
</div>
<div class="forget-section">
Forgot-password
</div>
<div class="btn-section">
<button type="submit" #click="handlesubmit();" class="login-btn">Login</button>
</div>
<div class="seperator">
<h5><span>OR</span></h5>
</div>
<div class="btn-groups">
<button type="button" class="btn btn-primary">Facebook</button>
<button type="button" class="btn btn-light">Google</button>
</div>
</form>
</div>
</div>
<Register v-else />
</div>
</template>
<script>
import Register from './Register.vue'
import service from '../service/User'
export default {
name: 'Login',
components:{Register},
data() {
return {
email: '',
password: '',
password_type: "password",
isPasswordVisible: false,
isSignup: false,
flag:true,
}
},
methods: {
flip() {
this.flag = !this.flag;
},
togglePassword() {
this.password_type = this.password_type === 'password' ? 'text' : 'password'
this.isPasswordVisible = !this.isPasswordVisible
},
handlesubmit() {
let userData = {
email: this.email,
password: this.password,
}
service.userLogin(userData).then(response => {
if(response.status==200){
alert("user logged in... ");
return response;
}
}).catch(error => {
alert("invalid credentials");
return error;
})
}
}
}
</script>
<style lang="scss" scoped>
#import "#/styles/Login.scss";
</style>
console errors
vue.runtime.esm.js?2b0e:619 [Vue warn]: Unknown custom element: <Register> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> <Login> at src/Pages/Login.vue
<Register> at src/Pages/Register.vue
<App> at src/App.vue
<Root>

Vue Js open sketchpad in vue-js-modal

I am new with Vue and trying to open sketchpad inside vue-js-modal.
I am not sure what am I doing wrong here.
I am using VueModal and vue-signature-pad.
It works fine on the page but I could not make it run in the modal.
Here is the link to codesandbox
App.vue code is as follow
<template>
<div id="app">
<v-dialog />
<div class="container">
<div class="row">
<div class="col-12 mt-2">
<div class="col-6 mt-2">
<button class="btn btn-secondary" #click="showButtonsDialog">
Open Dialog
</button>
</div>
</div>
<div class="col-12 mt-2">
<VueSignaturePad
id="signature"
width="100%"
height="100%"
ref="signaturePad"
/>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "App",
methods: {
showButtonsDialog() {
this.$modal.show("dialog", {
title: "Some Title",
text:'<VueSignaturePad id="signature" width="100%" height="200px" ref="signaturePad"/>',
buttons: [
{
title: "CANCEL",
handler: () => {
this.$modal.hide("dialog");
}
}]
});
}
}
};
</script>
What am I doing wrong here?
Thank you
I think text only work with plain text, not Vue component. To include Vue component in your modal, you can declare it in template
<modal name="example"
width="80%"
height="80%">
<VueSignaturePad
id="signature"
width="100%"
height="100%"
ref="signaturePad"
/>
</modal>
and when you want to show it
showButtonsDialog() {
this.$modal.show("example")
}
Demo on Codesandbox

Categories

Resources