I am trying to use Vue3 (Vite) and Bootstrap 5 to create a modal that is called by code. However, when opening the modal from its parent, an error is thrown.
I have bootstrap installed and included:
import bootstrap (main.js)
import bootstrap/dist/js/bootstrap does not change anything.
I have created a simple modal that listens for a prop and then opens the modal.
When I open it, the error appears:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'backdrop')
<template>
<div class="modal" tabindex="-1" id="errModal" aria-labelledby="ErrorModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Error {{ this.occurred }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="ErrorModalLabel"></button>
</div>
<div class="modal-body">
<p>{{ this.error_message }}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
</template>
<script>
import { Modal } from "bootstrap"
export default {
props: {
occurred: String,
error_message: String,
show: Boolean,
},
components: {
myModal: null
},
data() {
return {
}
},
methods: {
},
mounted() {
this.myModal = new Modal(document.getElementById('errModal'))
},
watch: {
show: function (newVal, oldVal) { // watch it
this.cam_prop = newVal.properties
},
}
};
</script>
Calling from Parent:
<RegIdentErrorModalVue id="#ErrModal" :show="this.error" :occurred="'Identification'" :error_message="this.error_text">
</RegIdentErrorModalVue>
Creating the Modal with new bootstrap.Modal does not work (bootstrap not defined)
I think the error is importing, but the styling works, could it be Vite?
Related
When I try to add a modal in a component, the backdrop is coming to front and modal is behind it as below. I checked all the position css properties in the parent components. I found nowhere that used position: fixed, relative or absolute.
My code is as below,
<template>
<div
class="modal p-4"
id="confirmModal"
tabindex="-1"
data-bs-backdrop="static"
data-bs-keyboard="false"
aria-labelledby="staticBackdropLabel"
aria-hidden="true"
>
<div class="modal-dialog modal-dialog-centered p-4 modal-xl">
<div class="modal-content p-4">
<div class="modal-body text-center">
<p class="my-5">No Images</p>
</div>
</div>
</div>
</div>
</template>
<script>
import bootstrap from "bootstrap/dist/js/bootstrap.min.js";
export default {
name: "ConfirmationDialog",
mounted() {
this.openViewer();
},
methods: {
openViewer() {
var myModal = new bootstrap.Modal(document.getElementById("confirmModal"), {
keyboard: false,
});
myModal.show();
},
},
};
</script>
Please, help me to solve this issue.
I found a solution.
Appending modal to body will solve the problem.
So, change the openViewer method as below,
openViewer() {
const modal = document.getElementById("confirmModal");
document.body.appendChild(modal);
var myModal = new bootstrap.Modal(modal, {
keyboard: false,
});
myModal.show();
},
my comments object's state is fine
but my saveComment() function can't find comments' post_id and makes error ->>
CommentList.vue?6c27:107 Uncaught TypeError: Cannot read properties of undefined (reading 'post_id')
at HTMLButtonElement.eval (CommentList.vue?6c27:107)
at HTMLButtonElement.dispatch (jquery.js?1157:5430)
at HTMLButtonElement.elemData.handle (jquery.js?1157:5234)
how can i use props in vue?? i want to use props like data..
<div>
{{ comments }}
<button #click="getComments()" class="btn btn-primary">
open comments
</button>
<!-- Button trigger modal -->
<button
#click="openWriteComment()"
type="button"
class="btn btn-primary"
id="openModalBtn"
data-bs-toggle="modal"
data-bs-target="#exampleModal"
>
Write Comment
</button>
<!-- Modal -->
<div
class="modal fade"
id="modalBox"
tabindex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
<input type="text" id="commentBody" value="type your comment" />
</div>
<div class="modal-footer">
<button #click="saveComment()" class="btn btn-primary" id="saveBtn">
Save changes
</button>
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal"
>
Close
</button>
</div>
</div>
</div>
</div>
<comment-item
v-for="(comment, index) in commentlist"
:key="index"
:comment="comment"
></comment-item>
</div>
</template>
<script>
import CommentItem from "./CommentItem.vue";
export default {
components: { CommentItem },
data() {
return {
commentlist: [],
};
},
created() {
this.getComments();
},
props: ["post", "loginuser", "comments"],
methods: {
getComments() {
axios
.get("/commentlist")
.then((res) => {
console.log(res.data);
this.commentlist = this.comments;
console.log(this.commentlist);
})
.catch((err) => {
console.log(err);
});
},
openWriteComment() {
$("#openModalBtn").on("click", function () {
$("#modalBox").modal("show");
});
},
saveComment() {
$("#saveBtn").on("click", function () {
console.log(document.getElementById("commentBody").value);
axios
.post("/commentSave/" + this.comments.post_id, {
comment: document.getElementById("commentBody").value,
})
.then((res) => {
console.log(res.data);
})
.catch((err) => {
console.log(err);
});
});
},
},
};
</script>```
I think I sopotted your error.
Your error:
saveComment() {
$("#saveBtn").on("click", function () { // This callback is a regular function
console.log(document.getElementById("commentBody").value);
axios
// when you get here 'this' context from Vue is lost
// "this.comments" doesn't exist in the context of this function.
.post("/commentSave/" + this.comments.post_id, {
comment: document.getElementById("commentBody").value,
})
Solution:
saveComment() {
$('#saveBtn').on('click', () => { // convert this to arrow function.
console.log(document.getElementById('commentBody').value)
axios
.post('/commentSave/' + this.comments.post_id, {
comment: document.getElementById('commentBody').value
})
this is regarding Vue.js question
i'm trying to open bootstrap model form inside the Vue template
i use two vue template components,
this sub component call inside this competence and pass data from this to sub component
this component use for show particular (load one by one products) model data
so i need to show one by one products data on the model form (when product 1 show name 'Abc') like this
but i cant do this.. all implementation are done and working fine
but cant show the particular data on the model form
show it only first loop value (i have 3 products all load in the table,but when click edit button first product show correctly,but click 2nd product show first product data)
but when i call console.log function and view when open the model show particular data in the console, but not showing its on the model form
why it that
i put my code segment in the below
example-component
<tbody >
<tr div v-for="invoices in invoice">
<th class="invoice_name ">{{invoices.p_name}}</th>
<td class="unit">
<sub-com :pID=invoices.p_id :invoice=invoices :invoiceID=invoice_id></sub-com>
</td>
</tr>
</tbody>
sub-com
<template>
<div>
<div class="form-group">
Refund
</div>
<div class="col-md-6">
<div class="modal fade" id="refundModel" tabindex="-1" role="dialog" aria-labelledby="addNewLabel"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<form>
<div class="modal-body">
<div class="form-group">
<input v-model="form.name" type="text" name="name" placeholder="Name" class="form-control">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
this is sub.vue script segment
<script>
export default{
data(){
return{
form: {
name:''
}
}
},
props: {
pID: String,
invoiceID:String,
invoice:{},
}
methods: {
refundMethod(invoices){
this.form.name = invoices.p_name;
console.log(invoices.p_name);
$('#refundModel').modal('show');
}
}
There are a couple of issues that might clear things up.
First you need to add a key to your template v-for loop:
<tr v-for="invoices in invoice" :key="invoices.p_id">
Second you are using jquery to trigger the modal which could work but you will have to generate unique ids for each div:
<div :id="'refundModel_'+pID">
A more Vue way to do this is to use the bootstrap data-show attribute and link it to a Boolean modal property in your data:
<div :data-show="modal" :id="'refundModel_'+pID">
export default {
data(){
return{
modal : false,
form: {
name:''
}
}
},
props: {
pID: String,
invoiceID: String,
invoice: Object,
}
methods: {
refundMethod(invoices){
this.form.name = invoices.p_name;
console.log(invoices.p_name);
this.toggleModal()
}
toggleModal () {
this.modal = !this.modal
}
}
}
I am new in Vue.js. I want to understand on using component. I tried to import my component to another component but it failed. I am using Laravel 5.8. Below are the error that I received.
Module not found: Error: Can't resolve
'./components/modalAlert.vue
Below are my codes.
app.js
Vue.component('form-to-do', require('./components/formToDo.vue').default);
Vue.component('modal-alert', require('./components/modalAlert.vue').default);
const app = new Vue({
el: '#app',
});
formToDo.Vue
<template>
// form
<modal-alert></modal-alert>
</template>
<script>
import modalAlert from './components/modalAlert.vue';
export default {
components: {
'modal-alert': modalAlert
},
data() {
return {
setErrors: [],
tasks: [],
task: {
id: '',
name: '',
completed: '',
date_completed: ''
},
result: '',
input: {
name: ''
}
};
},
}
</script>
modalAlert.vue
<template>
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">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">
Test
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['id'],
data() {
return {
}
},
mounted() {
console.log('Component mounted.')
}
}
</script>
Your components are probably in the same folder. In your component formToDo.vue:
Change this:
import modalAlert from './components/modalAlert.vue';
To this:
import modalAlert from './modalAlert.vue';
To solve the other issue, as #ambianBeing suggested, your component formToDo.vue must have root element to be able to add child component inside it.
<template>
<div> <!-- this is the root -->
<modal-alert></modal-alert>
</div>
</template>
I am getting the error "Make sure that this property is reactive, either in the data option, or for class" in vuejs.
I created a laravel application and wanted to make the user management work in real-time so I deplyed vuejs with the root template being Users.vue. Additionally I created a separate component called AddUserModal for the modal popup and used it in the root template as The popup displays correctly and rendered well in the browser. The problem started when I tried to do model binding and for that, am using vform for the server side validation. After declaring the data in Users.vue(root) I proceeded to AddUserModal to set up my form with v-model but this throws back an error. The code is below
This is the script from Users.vue
<script>
export default {
data() {
return {
form : new Form({
name : '',
email : '',
role : '',
description : '',
password : ''
})
}
},
mounted() {
console.log('Component mounted.')
}
}
AddUserModal
<div class="container">
<div class="modal fade" id="addUserModal" tabindex="-1" role="dialog" aria-labelledby="addUserModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<form>
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addUserModalLabel">Add User</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-sm btn-danger" data-dismiss="modal"><i class="fas fa-times-circle"></i></button>
<button type="button" class="btn btn-sm btn-success"><i class="fas fa-save"></i></button>
</div>
</div>
</form>
</div>
</div>
</div>
app.js
require('./bootstrap');
//vue
vue
window.Vue = require('vue');
//imports
import VueRouter from 'vue-router'
import { Form, HasError, AlertError } from 'vform'
//vue Router
vue router
Vue.use(VueRouter)
//Vform
window.Form = Form
Vue.component(HasError.name, HasError)
Vue.component(AlertError.name, AlertError)
let routes = [
{ path: '/users', component: require('./components/Users.vue')}
]
const router = new VueRouter({
mode: 'history',
routes
})
Vue.component('example-component', require('./components/AddUserModal.vue'));
const app = new Vue({
el: '#app',
router
});
When I placed the scripts in AddUserModal, the model binding works fine but throws up an error when placed in the Users.vue
This is the browser console output
app.js:37116 [Vue warn]: Property or method "form" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.