I have a button as follows:
<template>
<button
type="button"
class="btn btn-primary er fs-6 px-8 py-4"
data-bs-toggle="modal"
:data-bs-target="`#${modalId}`"
>
{{ buttonText }}
</button>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "modal-card",
props: {
title: String,
description: String,
buttonText: String,
image: String,
modalId: String,
accountId: String,
},
components: {},
});
</script>
Clicking it opens a Modal component as defined by :data-bs-target="#${modalId}"
How do I set in that Modal Component the value of accountId? I tried through a property but not sure how to set it when using :data-bs-target
thank you so much in advance.
I ended up changing the button to having both the :data-bs-target and the #click as follows (which apparently works)
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#kt_modal_1" #click="settings(item)">
and the modal I just pasted at the top of the page:
<div class="modal fade" tabindex="-1" id="kt_modal_1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title {{ currentItem.id }}</h5>
The settings function sets the currentItem:
settings(item) {
this.currentItem = item;
},
Related
I try to use VUE3 and Bootstrap to open a Modal by clicking one of those two images.
I created 3 Components.
Left DIV (Image)
Right DIV (Image)
Modal to open
Now, i want to click on one of those images and open the modal.
At Singlepage it works. But now i am using Components.
How do i listen in the Component "ModalContact" to the clickevent in other Components?
I uploaded the complete package to github: https://github.com/Gismo1337/wtf-i-am-doing-here
Using Vue 2 and the Vue CLI, I created a couple of Single File Components to demonstrate how to open and close a Bootstrap 4 Modal without jQuery, wrapping the modal in it's own component.
Although this is not using Vue 3, you should be able to port it.
Parent.vue
<template>
<div class="parent">
<h4>Bootstrap Modal Parent</h4>
<div class="row">
<div class="col-md-6">
<button class="btn btn-secondary" #click="showModal">Open Bootstrap Modal</button>
</div>
</div>
<bootstrap-modal-no-jquery v-if="displayModal" #close-modal-event="hideModal" />
</div>
</template>
<script>
import BootstrapModalNoJquery from './BootstrapModalNoJquery.vue'
export default {
components: {
BootstrapModalNoJquery
},
data() {
return {
displayModal: false
}
},
methods: {
showModal() {
this.displayModal = true;
},
hideModal() {
this.displayModal = false;
}
}
}
</script>
BootstrapModalNoJquery.vue
<template>
<div class="bootstrap-modal-no-jquery">
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" #click="saveChanges">Save changes</button>
<button type="button" class="btn btn-secondary" #click="closeModal">Close</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
methods: {
closeModal() {
this.$emit('close-modal-event');
},
saveChanges() {
this.closeModal();
}
}
}
</script>
<style scoped>
/* Override default value of 'none' */
.modal {
display: block;
}
</style>
When I click on the outer area of the modal, I want the same event as the close button of the modal. (Event that closes modal when clicking outside area of modal)
The current progress is that the modal is closed when the close modal button is clicked.
Carousel.vue
<template>
<div>
<div v-for="(item, index) in photos" :key="index">
<div #click="imgClick(item)" style="cursor:pointer;">
<img :src="item.thumbnail" />
</div>
<Modal v-if='item.show' #close="item.show = false">
<div slot='body'>
<img :src="item.thumbnail" :class="`img-index--${index}`"/>
</div>
</Modal>
</div>
</div>
</template>
<script>
import Modal from './Modal.vue'
export default {
props: {
items: { type: Array, default: () => [] }
},
data() {
return {
photos: {}
}
},
created() {
this.photos = this.items.map(item => {
return { ...item, show: false }
})
},
methods: {
imgClick(item) {
item.show = true
}
},
components: {
Modal: Modal
}
}
</script>
Modal.vue
<template>
<transition name="modal">
<div class="modal-mask" #click="$emit('close')">
<div class="modal-wrapper">
<div class="app__phone">
<div class="feed">
<div class="post">
<div class="header headroom">
<div class="level-left">
<img src="../assets/imgs/user.gif" class="modal-header-img"/>
<div class="user">
<span class="username">username</span>
<button class="modal-default-button" #click="$emit('close')">Close</button>
</div>
</div>
</div>
<slot name="modal-img"></slot>
<div class="content">
<div class="content-title">
<slot name="modal-tit"></slot>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</transition>
</template>
When I add a click event to the bottom <div>, it closes when I click outside the modal, but it closes when I click anywhere in the modal.
<div class="modal-mask" #click="$emit('close')">
And this link has a Fiddle example in the accepted answer to the question.
https://stackoverflow.com/a/58023701/12066654
You need to add a handler to the outer modal div like so:
<template id="modal">
<div class="modal" #click.self="close">
<div class="close" #click="close">×</div>
<div class="body">
<slot name="body" />
</div>
</div>
</template>
I know this type of questions are every where, but I am having problem to find a good answer(I am new to VueJS).I am sorry about that.
I am trying to pass data using vform.
What I am trying to do is adding user details through vform to a table.
Here is my Users.vue code
<div class="modal fade" id="addNew" tabindex="-1" role="dialog" aria-labelledby="addNew" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add New</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<input v-model="form.name" type="text" name="name"
class="form-control" :class="{ 'is-invalid': form.errors.has('name') }">
<has-error :form="form" field="name"></has-error>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<script>
export default {
data(){
return{
form: new Form({
name: ''
})
}
},
}
</script>
Here is my app.js
require('./bootstrap');
window.Vue = require('vue');
import { Form, HasError, AlertError } from 'vform';
window.form = Form;
Vue.component(HasError.name, HasError)
Vue.component(AlertError.name, AlertError)
import VueRouter from 'vue-router'
Vue.use(VueRouter)
let routes = [
{ path: '/dashboard', component: require('./components/Dashboard.vue') },
{ path: '/profile', component: require('./components/Profile.vue') },
{ path: '/users', component: require('./components/Users.vue') }
]
const router = new VueRouter({
mode: 'history',
routes // short for `routes: routes`
})
The issue you have is most likely on the line with this:
<input v-model="form.name" type="text" name="name"
You can see it's the only place where .name is called. Which means your form object is undefined and the code is trying to call the attribute name on it which throws you an error.
If you look at the vform README, you will see that the import statement is actually inside the component. The issue with your code is that the import inside app.js doesn't magically appear inside your component so you cannot do new Form() in the Vue component. While you do assign it to the window object in app.js, you don't re-use it later on and IMO, it's better to import your dependencies explicitly.
So in conclusion, what you need to do is: Add this import statement right after the opening <script> tag in your Vue component
import { Form } from 'vform';
i'm having trouble with the data that being passed to the component.
it will only shows as an object, not the item inside the object. i have
read several questions/answers from here, but i still couldn't make it works.
when i try {{ modalData.projectName }} (in child), it will show this error in console " Error in render: "TypeError: _vm.modalData is null" "
here are my codes:
parent
<template>
<section id="portFolio">
<div class="row">
<div
v-for="project in projects"
v-bind:key="project.id"
class="col-xs-12 col-sm-6 col-md-4 col-lg-4 col-xl-3"
>
<a type="button" data-toggle="modal" data-target="#exampleModal" v-on:click="openModal(project)">
<div class="project-block">
<!-- Image -->
<div class="image-preview">
<img src="/dist/img/logo-test.png" class="img-fluid" alt="Twitter">
</div>
<!-- Details -->
<div class="project-details p-t-10 p-b-10 p-l-10 p-r-10">
<div class="">
<h5 class="text-purple m-b-5">{{ project.projectName }}</h5>
<p class="text-dark">{{ project.companyName }}</p>
</div>
<p class="subtext text-dark">{{ project.projectYear }}</p>
</div>
</div>
</a>
</div>
</div>
<app-modal ref="modal" v-bind:modalData="selectedItem"/>
</section>
</template>
<script>
// Component
import modalBlock from "./component/portfolio/portfolioModal.vue";
export default{
name: "portFolio",
components: {
'app-modal': modalBlock
},
data() {
return {
// showModal: false,
selectedItem: null,
projectName: '',
companyName: '',
projectYear: null,
previewPic: '',
testText: '',
modalData: '',
projects: [
{
projectName: 'Project One',
companyName: 'CoolCompany Sdn Bhd',
projectYear: 2019,
previewPic: "/dist/img/logo-test.png",
testText: "First object"
},
{
projectName: 'Project Two',
companyName: 'NotSoCompany Sdn Bhd',
projectYear: 2018,
previewPic: "/dist/img/logo-test.png",
testText: "Second object"
},
{
projectName: 'Project Three',
companyName: 'LameCompany Sdn Bhd',
projectYear: 2017,
previewPic: "/dist/img/logo-test.png",
testText: "Third object"
}
]
}
},
methods: {
openModal(modalData) {
this.selectedItem = modalData
let element = this.$refs.modal.$el
$(element).modal('show')
}
}
}
</script>
Child component:
<template>
<div class="modal fade bd-example-modal-xl" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">The title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<h2>{{ modalData.projectName }}</h2>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default{
name: "modalBlock",
props:['modalData'],
data(){
return {
}
},
methods: {
close() {
this.$emit('close');
},
}
}
</script>
may i know where did i done wrong? or Did i forgot to declare something on the code?
thank you
Hello I have question regarding passing data to modal component using standalone Vue js.
The flow is user click on the button that 'select a country' and modal opens up and user can select a country with slider. once user clicked on confirm, modal closes.
I've tried using for loops to pass the data into modal components but it also prints out many buttons.
Thank you for your help
I have a HTML code that user can select a countries
<div class="select_championship_country" #click="enableCountryModal()">Select a country</div>
<modal v-if="showCountryModal" #close="showModal = false"></modal>
Here is the modal component code:
<!-- countury modal -->
<script type="text/x-template" id="modal-template">
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
select the country you want to support
</slot>
</div>
<div class="modal-body">
<slot name="body">
<div class="country_select_carousel">
<div class="countrySlide">
<!-- <img :src="imgUrl + '/flags/' + item.imgName"> -->
</div>
</div>
</slot>
</div>
<div class="modal-footer">
<slot name="footer">
<div class="modal-default-button" #click="$emit('close')">
confirm
</div>
</slot>
</div>
</div>
</div>
</div>
</transition>
</script>
This is country data array object and modal component
new Vue({
el: '#root',
components: {
modal: {
template: '#modal-template',
}
},
data: {
country_carousel_data: [
{
imgName: 'brasil.svg',
desc: 'brasil',
},
{
imgName: 'canada.svg',
desc: '',
},
{
imgName: 'egypt.svg',
desc: '',
},
{
imgName: 'france.svg',
desc: '',
},
{
imgName: 'germany.svg',
desc: '',
},
{
imgName: 'india.svg',
desc: '',
},
{
imgName: 'poland.svg',
desc: '',
},
{
imgName: 'portugal.svg',
desc: '',
},
{
imgName: 'tunisia.svg',
desc: '',
},
{
imgName: 'turkey.svg',
desc: '',
},
{
imgName: 'uk.svg',
desc: '',
},
{
imgName: 'usa.svg',
desc: '',
},
],
}
Where did you use the for-loop in your modal template? I do not see any v-for.
Your should not be inside for loop. I am guessing since you mentioned it prints out many buttons you had that inside the for loop. the v-for should be on the tag like below
<script type="text/x-template" id="modal-template">
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
select the country you want to support
</slot>
</div>
<div class="modal-body">
<slot name="body">
<div class="country_select_carousel">
<div class="countrySlide">
<img v-for="item in country_carousel_data" :src="imgUrl + '/flags/' + item.imgName">
</div>
</div>
</slot>
</div>
<div class="modal-footer">
<slot name="footer">
<div class="modal-default-button" #click="$emit('close')">
confirm
</div>
</slot>
</div>
</div>
</div>
</div>
</transition>
</script>