Bootstrap's modal.toggle is not working in react component - javascript

I wanted to toggle modal after a promise is resolved, which is triggered on button click. As per official doc modal.toggle() should do the magic but it is not working. I am using bootstrap's version 5.2.2. I can't use react-bootstrap.
import React from "react";
import { Modal } from "bootstrap";
const ExampleModal = () => {
const toggleModal = () => {
const myModalEl = document.getElementById('exampleModalToggle')
const modal = new Modal(myModalEl);
modal.toggle();
};
return (
<>
<div
className="modal fade"
id="exampleModalToggle"
aria-hidden="true"
aria-labelledby="exampleModalToggleLabel"
tabindex="-1"
>
<div className="modal-dialog modal-dialog-centered">
<div className="modal-content">
<div className="modal-header">
<h1 className="modal-title fs-5" id="exampleModalToggleLabel">
Modal 1
</h1>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body">
Show a second modal and hide this one with the button below.
</div>
<div className="modal-footer">
<button
onClick={toggleModal}
className="btn btn-primary"
data-bs-target="#exampleModalToggle2"
// data-bs-toggle="modal" // wanted to toggle after a promise is resolved
>
Open second modal
</button>
</div>
</div>
</div>
</div>
<div
className="modal fade"
id="exampleModalToggle2"
aria-hidden="true"
aria-labelledby="exampleModalToggleLabel2"
tabindex="-1"
>
<div className="modal-dialog modal-dialog-centered">
<div className="modal-content">
<div className="modal-header">
<h1 className="modal-title fs-5" id="exampleModalToggleLabel2">
Modal 2
</h1>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body">
Hide this modal and show the first with the button below.
</div>
<div className="modal-footer">
<button
className="btn btn-primary"
data-bs-target="#exampleModalToggle"
data-bs-toggle="modal"
>
Back to first
</button>
</div>
</div>
</div>
</div>
<a
className="btn btn-primary"
data-bs-toggle="modal"
href="#exampleModalToggle"
role="button"
>
Open first modal
</a>
</>
);
};
export default ExampleModal;
I have prepared above sample code and ran this code on sandbox. This is also unable to toggle the modal. Also the background shadow is getting darker after each button click. This is same behaviour i am experiencing in my project.

Here is the updated code which worked for me.
import React, { useRef } from "react";
import { Modal } from "bootstrap";
const ExampleModal = () => {
const myModalEl1 = useRef(null);
const myModalEl2 = useRef(null);
const toggleModal = () => {
// const myModalEl1 = document.getElementById("exampleModalToggle");
const modal = Modal.getInstance(myModalEl1.current, {});
modal.toggle();
// const myModalEl2 = document.getElementById("exampleModalToggle2");
const modal2 = Modal.getOrCreateInstance(myModalEl2.current, {});
modal2.toggle();
};
return (
<>
<div
className="modal fade"
id="exampleModalToggle"
ref={myModalEl1}
aria-hidden="true"
aria-labelledby="exampleModalToggleLabel"
tabindex="-1"
>
<div className="modal-dialog modal-dialog-centered">
<div className="modal-content">
<div className="modal-header">
<h1 className="modal-title fs-5" id="exampleModalToggleLabel">
Modal 1
</h1>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body">
Show a second modal and hide this one with the button below.
</div>
<div className="modal-footer">
<button
onClick={toggleModal}
className="btn btn-primary"
data-bs-target="#exampleModalToggle2"
// data-bs-toggle="modal" // wanted to toggle after a promise is resolved
>
Open second modal
</button>
</div>
</div>
</div>
</div>
<div
className="modal fade"
id="exampleModalToggle2"
aria-hidden="true"
ref={myModalEl2}
aria-labelledby="exampleModalToggleLabel2"
tabindex="-1"
>
<div className="modal-dialog modal-dialog-centered">
<div className="modal-content">
<div className="modal-header">
<h1 className="modal-title fs-5" id="exampleModalToggleLabel2">
Modal 2
</h1>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body">
Hide this modal and show the first with the button below.
</div>
<div className="modal-footer">
<button
className="btn btn-primary"
data-bs-target="#exampleModalToggle"
data-bs-toggle="modal"
>
Back to first
</button>
</div>
</div>
</div>
</div>
<a
className="btn btn-primary"
data-bs-toggle="modal"
href="#exampleModalToggle"
role="button"
>
Open first modal
</a>
</>
);
};
export default ExampleModal;

Related

How do I close a bootstrap (5.2) Modal from Javascript?

For a school project's sake, I created a modal using bootstrap in html, inside of it there is a prompt that I must check from javascript, how do I close the Modal from javascript, so that in case the prompt is valid I can just save the changes and if it isn't I throw an exception?
small note (Please without jQuery, I've seen a similar thread that had as a reply using this library, it's forbidden for the assignment)
this is my html code :
<div class="modal fade" id="bidModal" tabindex="-1" aria-labelledby="bidModal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="bidModalLabel">Bid amount</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p class="text" id="prompted">How much do you want to bet?</p>
<div class="input-group mb-2">
<input id="bAmount" type="text" class="form-control text" aria-label="Amount of bet">
<span class="input-group-text">€</span>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-bs-dismiss="modal">Cancel bid</button>
<button type="button" onClick="bid()" class="btn btn-success">Save bid</button>
</div>
</div>
</div>
</div>
this is my javascript code :
function bid(){
let valueOfBid = document.getElementById("bAmount").value;
if(isNaN(valueOfBid)){
//Cancel the prompt
}
players[realPlayer].bet=valueOfBid;
changeButtonState(false);
theTimer();
}
Please try like this. I suggest that you change isNaN(valueOfBid) to valueOfBid == "" before you add my code on your codebase.
function bid(){
let valueOfBid = document.getElementById("bAmount").value;
if(valueOfBid == ""){
alert(1)
//Cancel the prompt
var myModalEl = document.getElementById('bidModal');
var modal = bootstrap.Modal.getInstance(myModalEl)
modal.hide();
}
// players[realPlayer].bet=valueOfBid;
// changeButtonState(false);
}
you can add this to the element that should close the modal...
data-bs-dismiss="modal"
the following modal generates a list of links based off of a search term and user matches.
when they click one of the router links it will close the modal because of the line
<router-link :to="{ name: 'user', params: {user: user }}"
data-bs-dismiss="modal"
>{{ user }}
</router-link
>
the above code is generated INSIDE the modal -> here is the entire thing
<div class="full-page">
<div
class="modal fade"
id="findUser"
data-bs-backdrop="static"
data-bs-keyboard="false"
tabindex="-1"
aria-labelledby="staticBackdropLabel"
aria-hidden="true"
>
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Find User</h5>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
<label for="recipient-name" class="col-form-label"
>Steem Username:</label
>
<input
type="text"
v-model="userField"
class="form-control"
id="recipient-name"
/>
</div>
<div v-if="userField"></div>
<ul v-for="(user, index) in userMatches" :key="index">
<li>
<router-link
:to="{ name: 'user', params: { user: user } }"
data-bs-dismiss="modal"
>{{ user }}</router-link
>
</li>
</ul>
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal"
>
Close
</button>
</div>
</div>
</div>
</div>
</div>

How do have modal pop up when hovering over bootstrap 5 card?

I was following a template I found online to have a modal pop up when hovering over my cards with bootstrap 5.
This is my code so far:
class SavedEpisodes extends Component {
$(function() {
$('[data-toggle="modal"]').hover(function() {
var modalId = $(this).data('target');
$(modalId).modal('show');
});
});
render() {
const { userId, savedEpisodes, deleteSavedEpisode } = this.props;
console.log(savedEpisodes, "saved episodes-----");
return (
<>
<h1>Saved Episodes:</h1>
<div className="row p-5 m-2">
{savedEpisodes?.map((saved) => {
return (
<div className="col-md-2" key={saved.episode.id}>
<div
className="card"
data-toggle="modal"
data-target="#basicExampleModal"
>
<img
src={saved.episode.images[1].url}
alt="podcastimg"
className="card-img-top"
/>
<div className="card-body">
<h5 className="card-title" style={{ textAlign: "center" }}>
<Link
to={`/episode/${saved.episode.id}`}
className="stretched-link"
>
<span style={{ fontWeight: "bold", color: "white" }}>
{saved.episode.name}
</span>
</Link>
</h5>
</div>
</div>
</div>
);
})}
<div
className="modal fade"
id="basicExampleModal"
tabIndex="-1"
role="dialog"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<h5 className="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">...</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>
</div>
</>
);
}
}
I never used jQuery before so I'm not sure where to put that function for hovering, inside my class or not. I also tried to remove the $ because I was getting an error but that didn't seem to fix it either.
How do I get a modal to pop up only when hovering over my cards?
Thanks in advance!
This way of coding is not correct.React js is completely different from jquery
You can use React-bootstrap if you want to use bootstrap in react component. On the other hand, Modal should triggered with click event.you should use popover,tooltip,.. which hovered on cart element.
This resources can help you:
https://react-bootstrap.netlify.app/components/overlays/
https://react-bootstrap.netlify.app/components/modal/
If you do not want to use external libraries, you can use portal in react:
https://reactjs.org/docs/portals.html
This is not so react way. I would recommend to you using states and control your modal with this state. You can use onMouseEnter event and can set your boolean state inside. Also you should set your state again in onClick event of button to close modal

Closing a pop-up component and setting state to False after clicking outside the component in the background

Here is my Search.js component.
class Search extends Component {
state = {
doctors: [],
showTab: false
}
openTab = () => {
this.setState({showTab: true});
console.log('openTab state', this.state);
}
render() {
let advancedSearch = null;
if (this.state.showTab===true) {
advancedSearch = (<AdvancedSearch />)
}
return (
<div class="row">
<div class="col-md-2">
<div class="form-group">
<button class="btn btn-md btn-primary" data-toggle="modal" data-target="#myModal" onClick={this.openTab}>Advanced Search</button>
</div>
</div>
{advancedSearch}
</div>
)
}
}
And this is my Advanced Search component. No need to look at the code in depth.
const advancedSearch = (props) => {
return (
<div class="modal inmodal" id="myModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content animated bounceInRight">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title"> Advanced Search <i class="fa fa-search"></i> </h4>
</div>
<div class="modal-body">
<div class="row">
{searchFieldsInner.map((field, idx) => (
<SearchField
key={idx}
colWidth={field.colWidth}
placeholder={field.placeholder}
formControl={field.formControl} />
))}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Search</button>
</div>
</div>
</div>
</div>
)
Basically, when I click on the advancedSearch, I want the state to turn to true, which I am doing with the if statement. However, once the component opens (basically a pop-up view that slides down), and when I click on the background after which the pop-up closes, I want to turn the showTab state to false. Any suggestions on how to do it?
Advance search should be opened anyway as it needs to be clicked. The things you should control is the content inside advance search. Therefore, the state should be passed into AdvanceSearch as props.
//Search.js
closeTab = () => {
this.setState({showTab: false});
console.log('closeTab state', this.state.showTab);
}
render() {
return (
<div class="row">
<div class="col-md-2" onClick={this.closeTab}>
//skipped code
</div>
<AdvancedSearch isOpen={this.state.showTab} onClick={this.openTab}/>
</div>
)
}
//advanceSearch.js
const advancedSearch = ({isOpen, open}) => {
return (
{isOpen && (
<div class="modal inmodal" id="myModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
//skipped code
</div>
</div>
</div>
)}
)

How to access map data in modal button in react

upgrademodalPlan(el){
let data = {
subscription_plan_id: el.subscription_plan_id,
recurrence_time: el.payment_frequency,
}
}
Here I can able to access the el but in model button how to access this el
{ el.is_subscribed ? <button element={el} className="btn btn-success waves-effect waves-light m-t-20" data-toggle="modal" data-target="#upgradePlan" onClick=
{this.upgrademodalPlan.bind(this, el)}>Upgrade Plan</button> : null }
makePayment(el){
the same data what i was accessing in upgrademodalPlan should be accessed here, but i cannot able to access
}
<div id="upgradePlan" className="modal fade emp-add-list" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style={{display: "none"}}>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h6 className="modal-title">Upgrade Plan</h6>
<button type="button" className="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div className="modal-body">
<div className="form-group row m-b-0">
<div className="col-md-12 col-sm-6 col-xs-6">
<div className="">
<div className="row">
<div className="col-md-12">
<form>
<div className="form-group">
</div>
<div className="form-group">
<div className="checkbox">
<button type="button" className="btn btn-danger" onClick={this.makePayment.bind(this, this.props)}>Make Payment</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I am not sure to understand your question, but if you want pass el in model button you can use props maybe
{ el.is_subscribed ? <button element={el} className="btn btn-success waves-effect waves-light m-t-20" data-toggle="modal" data-target="#upgradePlan" onClick=
{this.upgrademodalPlan.bind(this, el)}>Upgrade Plan</button> : null }

React Bootstrap modal appearing under background

In my render function I have the following code for a modal
<div id="newListModal" className="modal fade" role="dialog">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal">×</button>
<h4 className="modal-title">Create new list</h4>
</div>
<div className="modal-body">
<p>Select category</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
All of the containing tags are positioned in the default way.
However, when I click on the button which triggers the modal, the modal appears under the background.
Since I have no special positioning of tags, I am assuming that this is a React issue.
Any ideas about why this is happening?
The problem is your background and modal both are located under root div. So you can overcome this problem by creating another div separately.
index.html
<html>
<body>
<div id="root"></div>
<div id="list-modal"></div>
</body>
</html>
ListModal.js (component)
return ReactDOM.createPortal(<div id="newListModal" className="modal fade" role="dialog">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal">×</button>
<h4 className="modal-title">Create new list</h4>
</div>
<div className="modal-body">
<p>Select category</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>,document.getElementById("list-modal"));

Categories