我需要通过单击Bootstrap导航栏和其他位置的按钮打开Bootstrap Modal(显示组件实例的数据,即提供“编辑”功能),但我不喜欢我不知道如何做到这一点。这是我的代码:
编辑:代码更新。
ApplicationContainer = React.createClass({
render: function() {
return (
<div className="container-fluid">
<NavBar />
<div className="row">
<div className="col-md-2">
<ScheduleEntryList />
</div>
<div className="col-md-10">
</div>
</div>
<ScheduleEntryModal />
</div>
);
}
});
NavBar = React.createClass({
render: function() {
return (
<nav className="navbar navbar-default navbar-fixed-top">
<div className="container-fluid">
<div className="navbar-header">
<a className="navbar-brand" href="#">
<span className="glyphicon glyphicon-eye-open"></span>
</a>
</div>
<form className="navbar-form navbar-left">
<button className="btn btn-primary" type="button" data-toggle="modal" data-target="#scheduleentry-modal">
<span className="glyphicon glyphicon-plus">
</span>
</button>
</form>
<ul className="nav navbar-nav navbar-right">
<li><a href="#"><span className="glyphicon glyphicon-user"></span> Username</a></li>
</ul>
</div>
</nav>
);
}
});
ScheduleEntryList = React.createClass({
getInitialState: function() {
return {data: []}
},
loadData: function() {
$.ajax({
url: "/api/tasks",
dataType: "json",
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, error) {
console.error("/api/tasks", status, error.toString());
}.bind(this)
});
},
componentWillMount: function() {
this.loadData();
setInterval(this.loadData, 20000);
},
render: function() {
items = this.state.data.map(function(item) {
return <ScheduleEntryListItem item={item}></ScheduleEntryListItem>;
});
return (
<div className="list-group">
<a className="list-group-item active">
<h5 className="list-group-item-heading">Upcoming</h5>
</a>
{items}
</div>
);
}
});
ScheduleEntryListItem = React.createClass({
openModal: function() {
$("#scheduleentry-modal").modal("show");
},
render: function() {
deadline = moment(this.props.item.deadline).format("MMM Do YYYY, h:mm A");
return (
<a className="list-group-item" href="#" onClick={this.openModal}>
<h5 className="list-group-item-heading">
{this.props.item.title}
</h5>
<small className="list-group-item-text">
{deadline}
</small>
</a>
);
}
});
Modal = React.createClass({
componentDidMount: function() {
$(this.getDOMNode())
.modal({backdrop: "static", keyboard: true, show: false});
},
componentWillUnmount: function() {
$(this.getDOMNode())
.off("hidden", this.handleHidden);
},
open: function() {
$(this.getDOMNode()).modal("show");
},
close: function() {
$(this.getDOMNode()).modal("hide");
},
render: function() {
return (
<div id="scheduleentry-modal" className="modal fade" tabIndex="-1">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal">
<span>×</span>
</button>
<h4 className="modal-title">{this.props.title}</h4>
</div>
<div className="modal-body">
{this.props.children}
</div>
<div className="modal-footer">
<button type="button" className="btn btn-danger pull-left" data-dismiss="modal">Delete</button>
<button type="button" className="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
)
}
});
ScheduleEntryModal = React.createClass({
render: function() {
var modal = null;
modal = (
<Modal title="Add Schedule Entry">
<form className="form-horizontal">
<div className="form-group">
<label htmlFor="title" className="col-sm-2 control-label">Title</label>
<div className="col-sm-10">
<input id="title" className="form-control" type="text" placeholder="Title" ref="title" name="title"/>
</div>
</div>
<div className="form-group">
<label htmlFor="deadline" className="col-sm-2 control-label">Deadline</label>
<div className="col-sm-10">
<input id="deadline" className="form-control" type="datetime-local" ref="deadline" name="deadline"/>
</div>
</div>
<div className="form-group">
<label htmlFor="completed" className="col-sm-2 control-label">Completed</label>
<div className="col-sm-10">
<input id="completed" className="form-control" type="checkbox" placeholder="completed" ref="completed" name="completed"/>
</div>
</div>
<div className="form-group">
<label htmlFor="description" className="col-sm-2 control-label">Description</label>
<div className="col-sm-10">
<textarea id="description" className="form-control" placeholder="Description" ref="description" name="description"/>
</div>
</div>
</form>
</Modal>
);
return (
<div className="scheduleentry-modal">
{modal}
</div>
);
}
});
对代码的其他评论和改进表示赞赏。
答案 0 :(得分:88)
我最近在寻找一个很好的解决方案,而不是在我的项目中添加React-Bootstrap(因为Bootstrap 4即将发布)。
这是我的解决方案:https://jsfiddle.net/16j1se1q/1/
let Modal = React.createClass({
componentDidMount(){
$(this.getDOMNode()).modal('show');
$(this.getDOMNode()).on('hidden.bs.modal', this.props.handleHideModal);
},
render(){
return (
<div className="modal fade">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 className="modal-title">Modal title</h4>
</div>
<div className="modal-body">
<p>One fine body…</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" className="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
)
},
propTypes:{
handleHideModal: React.PropTypes.func.isRequired
}
});
let App = React.createClass({
getInitialState(){
return {view: {showModal: false}}
},
handleHideModal(){
this.setState({view: {showModal: false}})
},
handleShowModal(){
this.setState({view: {showModal: true}})
},
render(){
return(
<div className="row">
<button className="btn btn-default btn-block" onClick={this.handleShowModal}>Open Modal</button>
{this.state.view.showModal ? <Modal handleHideModal={this.handleHideModal}/> : null}
</div>
);
}
});
React.render(
<App />,
document.getElementById('container')
);
主要思想是仅在显示时将模态组件呈现到React DOM中(在App组件呈现函数中)。我保留了一些“查看”状态,表明模态当前是否显示。
'componentDidMount'和'componentWillUnmount'回调通过Bootstrap javascript函数隐藏或显示模态(一旦它被渲染到React DOM中)。
我认为这个解决方案很好地遵循了React的精神,但欢迎提出建议!
答案 1 :(得分:52)
您可以使用React-Bootstrap(https://react-bootstrap.github.io/components/modal)。该链接有一个模态示例。一旦加载了react-bootstrap,模态组件就可以用作反应组件:
var Modal = ReactBootstrap.Modal;
然后可以用作反应组分
<Modal/>
。
对于Bootstrap 4,有反应带(https://reactstrap.github.io)。 React-Bootstrap仅支持Bootstrap 3。
答案 2 :(得分:9)
getDOMNode()
已弃用。而是使用ref
来访问DOM元素。这是工作模态组件(Bootstrap 4)。
决定是否显示父组件中的模态组件。
示例:https://jsfiddle.net/sqfhkdcy/
class Modal extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
$(this.modal).modal('show');
$(this.modal).on('hidden.bs.modal', handleModalCloseClick);
}
render() {
return (
<div>
<div className="modal fade" ref={modal=> this.modal = modal} id="exampleModal" 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" className="close" data- dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div className="modal-body">
...
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" data- dismiss="modal">Close</button>
<button type="button" className="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
修改强>
以下是使其有效的必要导入:
import $ from 'jquery';
window.jQuery = $;
window.$ = $;
global.jQuery = $;
答案 3 :(得分:6)
我创建了这个功能:
onAddListItem: function () {
var Modal = ReactBootstrap.Modal;
React.render((
<Modal title='Modal title' onRequestHide={this.hideListItem}>
<ul class="list-group">
<li class="list-group-item">Cras justo odio</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
<li class="list-group-item">Morbi leo risus</li>
<li class="list-group-item">Porta ac consectetur ac</li>
<li class="list-group-item">Vestibulum at eros</li>
</ul>
</Modal>
), document.querySelector('#modal-wrapper'));
}
然后在我的按钮触发器上使用它。
隐藏&#39;模态:
hideListItem: function () {
React.unmountComponentAtNode(document.querySelector('#modal-wrapper'));
},
答案 4 :(得分:5)
您可以使用link的react-bootstrap中的模型,它基本上是基于函数的
function Example() {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<Button variant="primary" onClick={handleShow}>
Launch demo modal
</Button>
<Modal show={show} onHide={handleClose} animation={false}>
<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={handleClose}>
Close
</Button>
<Button variant="primary" onClick={handleClose}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
</>
);
}
您可以将其转换为类组件
import React, { Component } from "react";
import { Button, Modal } from "react-bootstrap";
export default class exampleextends Component {
constructor(props) {
super(props);
this.state = {
show: false,
close: false,
};
}
render() {
return (
<div>
<Button
variant="none"
onClick={() => this.setState({ show: true })}
>
Choose Profile
</Button>
<Modal
show={this.state.show}
animation={true}
size="md" className="" shadow-lg border">
<Modal.Header className="bg-danger text-white text-center py-1">
<Modal.Title className="text-center">
<h5>Delete</h5>
</Modal.Title>
</Modal.Header>
<Modal.Body className="py-0 border">
body
</Modal.Body>
<Modal.Footer className="py-1 d-flex justify-content-center">
<div>
<Button
variant="outline-dark" onClick={() => this.setState({ show: false })}>Cancel</Button>
</div>
<div>
<Button variant="outline-danger" className="mx-2 px-3">Delete</Button>
</div>
</Modal.Footer>
</Modal>
</div>
);
}
}
答案 5 :(得分:4)
您可以尝试以下模式:https://github.com/xue2han/react-dynamic-modal 它是无状态的,只有在需要时才能呈现。所以它很容易使用。就像这样:
class MyModal extends Component{
render(){
const { text } = this.props;
return (
<Modal
onRequestClose={this.props.onRequestClose}
openTimeoutMS={150}
closeTimeoutMS={150}
style={customStyle}>
<h1>What you input : {text}</h1>
<button onClick={ModalManager.close}>Close Modal</button>
</Modal>
);
}
}
class App extends Component{
openModal(){
const text = this.refs.input.value;
ModalManager.open(<MyModal text={text} onRequestClose={() => true}/>);
}
render(){
return (
<div>
<div><input type="text" placeholder="input something" ref="input" /></div>
<div><button type="button" onClick={this.openModal.bind(this)}>Open Modal </button> </div>
</div>
);
}
}
ReactDOM.render(<App />,document.getElementById('main'));
答案 6 :(得分:4)
感谢@tgrrr提供了一个简单的解决方案,特别是当不需要第三方库时(例如React-Bootstrap)。但是,这个解决方案存在一个问题:模态容器嵌入在反应组件内部,当外部反应组件(或其父元素)的位置样式为固定/相对/绝对时,导致modal-under-background issue。我遇到了这个问题并提出了一个新的解决方案:
"use strict";
var React = require('react');
var ReactDOM = require('react-dom');
var SampleModal = React.createClass({
render: function() {
return (
<div className="modal fade" tabindex="-1" role="dialog">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 className="modal-title">Title</h4>
</div>
<div className="modal-body">
<p>Modal content</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" className="btn btn-primary">OK</button>
</div>
</div>
</div>
</div>
);
}
});
var sampleModalId = 'sample-modal-container';
var SampleApp = React.createClass({
handleShowSampleModal: function() {
var modal = React.cloneElement(<SampleModal></SampleModal>);
var modalContainer = document.createElement('div');
modalContainer.id = sampleModalId;
document.body.appendChild(modalContainer);
ReactDOM.render(modal, modalContainer, function() {
var modalObj = $('#'+sampleModalId+'>.modal');
modalObj.modal('show');
modalObj.on('hidden.bs.modal', this.handleHideSampleModal);
}.bind(this));
},
handleHideSampleModal: function() {
$('#'+sampleModalId).remove();
},
render: function(){
return (
<div>
<a href="javascript:;" onClick={this.handleShowSampleModal}>show modal</a>
</div>
)
}
});
module.exports = SampleApp;
主要思想是:
答案 7 :(得分:4)
Reactstrap也有implementation of Bootstrap Modals in React。该库针对Bootstrap版本4,而react-bootstrap针对版本3.X。
答案 8 :(得分:2)
我只使用bootstrap cdn(css + js)来实现类似“ reactstrap”的解决方案。我使用props.children将动态数据从父组件传递到子组件。您可以找到有关此here的更多信息。这样,您具有模态头,模态主体和模态页脚三个独立的组件,它们彼此完全独立。
//Modal component
import React, { Component } from 'react';
export const ModalHeader = props => {
return <div className="modal-header">{props.children}</div>;
};
export const ModalBody = props => {
return <div className="modal-body">{props.children}</div>;
};
export const ModalFooter = props => {
return <div className="modal-footer">{props.children}</div>;
};
class Modal extends Component {
constructor(props) {
super(props);
this.state = {
modalShow: '',
display: 'none'
};
this.openModal = this.openModal.bind(this);
this.closeModal = this.closeModal.bind(this);
}
openModal() {
this.setState({
modalShow: 'show',
display: 'block'
});
}
closeModal() {
this.setState({
modalShow: '',
display: 'none'
});
}
componentDidMount() {
this.props.isOpen ? this.openModal() : this.closeModal();
}
componentDidUpdate(prevProps) {
if (prevProps.isOpen !== this.props.isOpen) {
this.props.isOpen ? this.openModal() : this.closeModal();
}
}
render() {
return (
<div
className={'modal fade ' + this.state.modalShow}
tabIndex="-1"
role="dialog"
aria-hidden="true"
style={{ display: this.state.display }}
>
<div className="modal-dialog" role="document">
<div className="modal-content">{this.props.children}</div>
</div>
</div>
);
}
}
export default Modal;
//App component
import React, { Component } from 'react';
import Modal, { ModalHeader, ModalBody, ModalFooter } from './components/Modal';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
modal: false
};
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState({ modal: !this.state.modal });
}
render() {
return (
<div className="App">
<h1>Bootstrap Components</h1>
<button
type="button"
className="btn btn-secondary"
onClick={this.toggle}
>
Modal
</button>
<Modal isOpen={this.state.modal}>
<ModalHeader>
<h3>This is modal header</h3>
<button
type="button"
className="close"
aria-label="Close"
onClick={this.toggle}
>
<span aria-hidden="true">×</span>
</button>
</ModalHeader>
<ModalBody>
<p>This is modal body</p>
</ModalBody>
<ModalFooter>
<button
type="button"
className="btn btn-secondary"
onClick={this.toggle}
>
Close
</button>
<button
type="button"
className="btn btn-primary"
onClick={this.toggle}
>
Save changes
</button>
</ModalFooter>
</Modal>
</div>
);
}
}
export default App;
答案 9 :(得分:1)
使用React功能组件的解决方案。
import React, { useState, useRef, useEffect } from 'react'
const Modal = ({ title, show, onButtonClick }) => {
const dialog = useRef({})
useEffect(() => { $(dialog.current).modal(show ? 'show' : 'hide') }, [show])
useEffect(() => { $(dialog.current).on('hide.bs.modal', () =>
onButtonClick('close')) }, [])
return (
<div className="modal fade" ref={dialog}
id="modalDialog" tabIndex="-1" role="dialog"
aria-labelledby="modalDialogLabel" aria-hidden="true"
>
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="modalDialogLabel">{title}</h5>
<button type="button" className="close" aria-label="Close"
onClick={() => onButtonClick('close')}
>
<span aria-hidden="true">×</span>
</button>
</div>
<div className="modal-body">
...
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary"
onClick={() => onButtonClick('close')}>Close</button>
<button type="button" className="btn btn-primary"
onClick={() => onButtonClick('save')}>Save</button>
</div>
</div>
</div>
</div>
)
}
const App = () => {
const [ showDialog, setShowDialog ] = useState(false)
return (
<div className="container">
<Modal
title="Modal Title"
show={showDialog}
onButtonClick={button => {
if(button == 'close') setShowDialog(false)
if(button == 'save') console.log('save button clicked')
}}
/>
<button className="btn btn-primary" onClick={() => {
setShowDialog(true)
}}>Show Dialog</button>
</div>
)
}
答案 10 :(得分:0)
最快的解决方法是从全局上下文中显式使用jQuery $(由于您在script标记中引用了$ .modal(),因此已在$ .modal()中进行了扩展):
window.$('#scheduleentry-modal').modal('show') // to show
window.$('#scheduleentry-modal').modal('hide') // to hide
所以这就是您如何在反应上解决
import React, { Component } from 'react';
export default Modal extends Component {
componentDidMount() {
window.$('#Modal').modal('show');
}
handleClose() {
window.$('#Modal').modal('hide');
}
render() {
<
div className = 'modal fade'
id = 'ModalCenter'
tabIndex = '-1'
role = 'dialog'
aria - labelledby = 'ModalCenterTitle'
data - backdrop = 'static'
aria - hidden = 'true' >
<
div className = 'modal-dialog modal-dialog-centered'
role = 'document' >
<
div className = 'modal-content' >
// ...your modal body
<
button
type = 'button'
className = 'btn btn-secondary'
onClick = {
this.handleClose
} >
Close <
/button> < /
div > <
/div> < /
div >
}
}
答案 11 :(得分:-18)
只需将href='#scheduleentry-modal'
添加到要使用
或者使用jQuery:$('#scheduleentry-modal').modal('show');