How to customize react-bootstrap modal - reactjs

Suppose I have a modal like as follows and I would like it such that, when the modal is showing at that time I also want to work on the background.
In the following code, there is a textbox. I want to work with the textbox(or an audio) when the model is appearing.
import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { Modal, Button } from 'react-bootstrap';
import './GenericModal.scss';
class GenericModal extends Component {
constructor(props, context) {
super(props, context);
this.state = {
showModal: false
};
this.open = this.open.bind(this);
this.close = this.close.bind(this);
}
open() {
this.setState({showModal: true});
}
close() {
this.setState({showModal: false});
}
render() {
return(
<div>
<div>I am a Bootstrap Modal</div>
<Button onClick={this.open}>Show Modal</Button>
<div>
<Modal className="modal-container" id="demo-class" ref={node => this.chart = node}
show={this.state.showModal}
onHide={this.close}
bsSize="small" backdrop={false}
>
<Modal.Header closeButton>
<Modal.Title>Modal title</Modal.Title>
</Modal.Header>
<Modal.Body>
One of fine body.........
</Modal.Body>
<Modal.Footer>
<Button onClick={this.close}>Close</Button>
<Button bsStyle="primary">Save changes</Button>
</Modal.Footer>
</Modal>
<Button onClick={this.open}>Show Modal</Button>
<input type="text" />
</div>
</div>
);
}
}
export default GenericModal;

I hope the below example flow addresses your requirement.
More form the comments in code.
i.e onClick calls wrapper function which has open method for modal together with your customizations.
import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { Modal, Button } from 'react-bootstrap';
import './GenericModal.scss';
class GenericModal extends Component {
constructor(props, context) {
super(props, context);
this.state = {
showModal: false
};
this.open = this.open.bind(this);
this.close = this.close.bind(this);
}
open() {
let _this = this;
this.setState({showModal: true}, function(){
//state is set, i.e modal is loaded in view
//here you can do whatever like stopping audio
//_this.stopAudio();
});
}
close() {
this.setState({showModal: false});
}
playSomeAudio(){
//playAudio();
}
stopAudio(){
//stop the audio
}
doSomethingBeforeOpen(){
var _this = this;
//do whatever you want before opening model. i.e palying audio
//1. in sync:
this.playSomeAudio(); //audio starts palying before modal starts triggered
//2. in async
setTimeOut(() => {_this.playSomeAudio()}, 1); //async by setTimeout, keep your own time
//Or any
this.open(); //opens modal
}
render() {
return(
<div>
<div>I am a Bootstrap Modal</div>
<Button onClick={this.doSomethingBeforeOpen.bind(this)}>Show Modal</Button>
<div>
<Modal className="modal-container" id="demo-class" ref={node => this.chart = node}
show={this.state.showModal}
onHide={this.close}
bsSize="small" backdrop={false}
>
<Modal.Header closeButton>
<Modal.Title>Modal title</Modal.Title>
</Modal.Header>
<Modal.Body>
One of fine body.........
</Modal.Body>
<Modal.Footer>
<Button onClick={this.close}>Close</Button>
<Button bsStyle="primary">Save changes</Button>
</Modal.Footer>
</Modal>
<Button onClick={this.doSomethingBeforeOpen.bind(this)}>Show Modal</Button>
<input type="text" />
</div>
</div>
);
}
}
export default GenericModal;

Related

Opening a Modal in React with an ID passed to the component

I have an application which prompts a user to add an entry via a modal. However, I can't figure out how to call the modal from the function and neither can I figure out how to pass the id to the modal.
So far I've been able to get the two parts written up and compiled but not working together
'Add Entry' button
import React from 'react';
import '../../App.css'
import VideoModal from '../components/VideoModal'
function NewEntry ({event}){
return (
<span><i class="fa fa-plus-circle" aria-hidden="true"></i></span>
<VideoModal entry={event}
);
}
export default NewEntry;
Note that this doesn't call the modal component. I've attempted variations of onClick={this.closeModal} for the <I> tag to no avail, but this obviously won't work. And I've included the modal as a component.
I know, I know this isn't the right way of doing this, I just haven't yet found examples I can wrap my head around.
The Modal
import React, { Component } from "react";
import { Modal, Button } from "react-bootstrap";
import '../../App.css'
class VideoModal extends Component {
state = {
isOpen: false
};
openModal = () => this.setState({ isOpen: true });
closeModal = () => this.setState({ isOpen: false });
render() {
return (
<>
<Modal show={this.state.isOpen} onHide={this.closeModal}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={this.closeModal}>
Close
</Button>
</Modal.Footer>
</Modal>
</>
);
}
}
export default VideoModal;
First of all, the VideoModal tag is not closed, pay attention to it.
Then you can move the open/close logic outside the modal, inside NewEntry:
import React, { Component } from 'react';
import '../../App.css'
import VideoModal from '../components/VideoModal'
class NewEntry extends Component {
state = {
isModalOpen: false
};
openModal = () => this.setState({ isModalOpen: true });
closeModal = () => this.setState({ isModalOpen: false });
render() {
return (
<span onClick={() => this.openModal()}><i class="fa fa-plus-circle" aria-hidden="true"></i></span>
<VideoModal closeModal={() => this.closeModal()} isOpen={this.state.isOpen} />
);
}
}
export default NewEntry;
And use VideoModal as a pure component:
import React from "react";
import { Modal, Button } from "react-bootstrap";
import '../../App.css'
function VideoModal (props) {
const { isOpen, closeModal } = props;
return (
<>
<Modal show={isOpen} onHide={closeModal}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={closeModal}>
Close
</Button>
</Modal.Footer>
</Modal>
</>
);
}
export default VideoModal;

How implementing a modal with reactjs

i have a modal, but dont recognize their styles, what is the matter?, why dont recognize the styles? i need to import an other dependecy?
import React,{Component} from 'react'
import Modal from 'react-bootstrap/Modal'
import Button from 'react-bootstrap/Button';
class CustomModal extends Component{
constructor(props) {
super(props);
this.state = {
show: false
};
this.handleClose = this.handleClose.bind(this);
this.handleShow = this.handleShow.bind(this);
}
handleClose (){
this.setState({ show: false });
};
handleShow (){
this.setState({ show: true });
};
render() {
return(
<div>
<Button variant="primary" onClick={this.handleShow}>Update</Button>
<Modal show={this.state.show} onHide={this.handleClose}>
<Modal.Header closeButton>
<Modal.Title>Update</Modal.Title>
</Modal.Header>
<Modal.Body>...</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={this.handleClose}>Close</Button>
<Button variant="primary">Save</Button>
</Modal.Footer>
</Modal>
</div>
);
}
}
export default CustomModal;
i am using Button but my button never is painting
I simply changed the way you have imported the Components and it started working.
Changed the import to
import { Modal, Button } from "react-bootstrap";
From
import Modal from 'react-bootstrap/Modal'
import Button from 'react-bootstrap/Button';
Live demo here
https://codesandbox.io/s/react-bootstrap-x0ix0?fontsize=14&hidenavigation=1&theme=dark

Modal Component - How to include and open/close from another component

I'm just starting to learn React. I've got a modal component (that's basically a wrapper for react-bootstrap's Modal component). The idea is to have a "Feedback" modal that I can include in various places. This approach isn't working, and I don't know what I don't know :/
Below is a quick example of what I mean / how I'm trying to display my modal component
import React, { Component } from 'react'
import Modal from 'react-bootstrap/Modal'
import Button from "components/button/button"
export class BaseModal extends Component {
constructor(props) {
super(props);
this.state = { show: false };
}
toggleModal() {
this.setState({ show: !this.state.show })
}
render() {
if (!this.props.show) {
return null;
};
return (
<>
<Modal show={this.state.show}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={this.toggleModal}>
Close
</Button>
<Button variant="primary" onClick={this.toggleModal}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
</>
)
}
}
A simple page like this - clicking this button doesn't do anything (React dev tools show no BaseModal node in the vdom)
import React, { Component } from 'react'
import Button from "components/button/button"
import BaseModal from "components/modals/baseModal"
export class ButtonDocs extends Component {
render() {
<Button value="Open Modal" onClick={BaseModal.toggleModal} />
}
}
You can't just import a Component and then call a method on it, because you aren't actually rendering it anywhere.
What you need to do is render the Component, and then if you want to control the state of one component from another you need to "lift state up" and pass the state and any methods needed to the modal component as props. Something like this:
Modal Component
import React, { Component } from 'react'
import Modal from 'react-bootstrap/Modal'
import Button from "components/button/button"
export class BaseModal extends Component {
render() {
if (!this.props.show) {
return null;
};
return (
<>
<Modal show={this.state.show}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={this.props.toggleModal}>
Close
</Button>
<Button variant="primary" onClick={this.props.toggleModal}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
</>
)
}
}
Button Docs
import React, { Component } from 'react'
import Button from "components/button/button"
import BaseModal from "components/modals/baseModal"
export class ButtonDocs extends Component {
constructor(props) {
super(props);
this.state = { show: false };
}
toggleModal() {
this.setState({ show: !this.state.show })
}
render() {
<Button value="Open Modal" onClick={this.toggleModal} />
<BaseModal show={this.state.show} toggleModal={this.toggleModal} />
}
}

Create Modal with reactjs bootstrap

I am getting kind of desperated. I want to make an modal dialog in reactjs using bootstrap. I have installed the module with npm and imported it in my code. I tried a simple example:
import React from 'react';
import {Modal, Button } from 'react-bootstrap';
class Config extends React.Component {
constructor(){
super();
this.state = {
show: false
}
this.handleHide = this.handleHide.bind(this);
}
handleHide() {
this.setState({ show: false });
}
render(){
return ( <div>
<Button
bsStyle="primary"
bsSize="large"
onClick={() => this.setState({ show: true })}
>
Launch modal
</Button>
<Modal show={this.state.show} onHide={this.handleHide}>
<Modal.Header >
Header
</Modal.Header>
<Modal.Body>
Text
</Modal.Body>
<Modal.Footer>
<Button onClick={this.handleHide}>Close</Button>
</Modal.Footer>
</Modal>
</div>)
}
}
export default Config;
I dont get any error, but I also cant see anything, if I click on the button. I looked with the Chrome developer tool through the Elements and I can see the modal there, which is confusing.
Does someone has an idea what is wrong?
This worked for me it's almost identical to your example. However, instead of using one function to handle the state by itself, I used 2 functions for the handleClose and HandleShow.
import React from 'react';
import { Link } from 'react-router-dom';
import { Modal, Button } from 'react-bootstrap';
class Header extends React.Component {
constructor(props){
super(props);
this.handleClose = this.handleClose.bind(this);
this.handleShow = this.handleShow.bind(this);
this.state = {
show: false
}
}
handleClose(){
this.setState({
show:false
});
}
handleShow(){
this.setState({
show:true
});
}
render(){
// console.log(this.state);
return (
<div className="header-container">
<nav className="navbar navbar-dark bg-dark">
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/Contact">Contact</Link></li>
<li><Button className="login-button" onClick={this.handleShow}>LOGIN</Button></li>
</ul>
<Modal show={this.state.show} onHide={this.handleClose}>
<Modal.Header closeButton>
<Modal.Title>Modal Header</Modal.Title>
</Modal.Header>
<Modal.Body>
Modal Body
</Modal.Body>
</Modal>
</nav>
</div>
)
}
}
export default Header;

Testing React with Boostrap Modal on click

I've got this simple code from react bootstrap website...
import {Modal} from 'react-bootstrap';
import React from 'react';
export default class ModalExperiment extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false
}
}
render(){
let openModal = () => this.setState({open: true});
let closeModal = () => this.setState({ open: false });
return (
<div>
<button type='button' onClick={openModal} className='launch'>Launch modal</button>
<Modal
show={this.state.open}
onHide={closeModal}
aria-labelledby="ModalHeader" className='modalClass'
>
<Modal.Header closeButton>
<Modal.Title id='ModalHeader'>A Title Goes here</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>Some Content here</p>
</Modal.Body>
<Modal.Footer>
// If you don't have anything fancy to do you can use
// the convenient `Dismiss` component, it will
// trigger `onHide` when clicked
<Modal.Dismiss className='dismiss btn btn-default'>Cancel</Modal.Dismiss>
// Or you can create your own dismiss buttons
<button className='btn btn-primary' onClick={closeModal}>
Close
</button>
</Modal.Footer>
</Modal>
</div>
)
}
}
And here is my test... simple I want to click the launch button, verify the Modal opens, and then click on the Cancel button to verify the Modal is no longer opened.
'use strict';
import React from 'react';
import ReactAddons from 'react/addons';
import {Modal} from 'react-bootstrap';
import ModalExperiment from '../ModalExperiment';
import ReactDOM from 'react-dom';
let TestUtils = React.addons.TestUtils;
fdescribe('ModalExperimentFunctional', function() {
let page;
fit("click the ok button should open the modal", () => {
page = TestUtils.renderIntoDocument(<ModalExperiment/>);
let launch = TestUtils.findRenderedDOMComponentWithClass(page, 'launch');
let openButton = React.findDOMNode(launch);
openButton.click(); // work till here
//let modal = TestUtils.findRenderedComponentWithType(page, Modal);// this managed to find Modal type
let modal = TestUtils.findRenderedDOMComponentWithClass(page, 'modalClass'); // this fails to find the modalClass..
});
});
How can I find the Cancel button please? I tried all sort of things, nothing seems to have worked for me.
I finally got it working using jquery selector..
import {Modal} from 'react-bootstrap';
import React from 'react';
export default class ModalExperiment extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false
}
}
openModal() {
this.setState({open: true});
}
closeModal() {
this.setState({open: false });
}
render(){
return (
<div>
<button type='button' onClick={this.openModal.bind(this)} className='openButton'>Launch modal</button>
{this.state.open?
<Modal
show={this.state.open}
onHide={this.closeModal.bind(this)}
aria-labelledby="ModalHeader" className='modalClass'
>
<Modal.Header closeButton>
<Modal.Title id='ModalHeader'>A Title Goes here</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>Some Content here</p>
</Modal.Body>
<Modal.Footer>
<button className='closeButton btn btn-primary' onClick={this.closeModal.bind(this)}>
Close
</button>
</Modal.Footer>
</Modal> : ''}
</div>
)
}
}
And here is the test...
'use strict';
import React from 'react';
import ReactAddons from 'react/addons';
import {Modal} from 'react-bootstrap';
import ModalExperiment from '../ModalExperiment';
import $ from 'jquery';
let TestUtils = React.addons.TestUtils;
describe('ModalExperimentFunctional', function() {
let page;
beforeEach(() => {
document.body.innerHTML = '';
page = TestUtils.renderIntoDocument(<ModalExperiment/>);
});
fit("click the ok button should open the modal", () => {
expect($('.closeButton').length).toBe(0);
let openButton = React.findDOMNode(TestUtils.findRenderedDOMComponentWithClass(page, 'openButton'));
TestUtils.Simulate.click(openButton);
expect($('.closeButton').length).toBe(1);
$('.closeButton').click();
expect($('.closeButton').length).toBe(0);
});
});
In test use:
const component = ReactTestUtils.renderIntoDocument(<Modal />);
ReactTestUtils.Simulate.click(document.body.getElementsByClassName("close")[0]);

Resources