Skip to content

Instantly share code, notes, and snippets.

@gjbagrowski
Forked from insin/BootstrapModalMixin.js
Created July 30, 2014 09:23
Show Gist options
  • Save gjbagrowski/c7c038c5d5625fa4b2b2 to your computer and use it in GitHub Desktop.
Save gjbagrowski/c7c038c5d5625fa4b2b2 to your computer and use it in GitHub Desktop.
/** @jsx React.DOM */
var BootstrapModalMixin = function() {
var handlerProps =
['handleShow', 'handleShown', 'handleHide', 'handleHidden']
var bsModalEvents = {
handleShow: 'show.bs.modal'
, handleShown: 'shown.bs.modal'
, handleHide: 'hide.bs.modal'
, handleHidden: 'hidden.bs.modal'
}
return {
propTypes: {
handleShow: React.PropTypes.func
, handleShown: React.PropTypes.func
, handleHide: React.PropTypes.func
, handleHidden: React.PropTypes.func
, backdrop: React.PropTypes.bool
, keyboard: React.PropTypes.bool
, show: React.PropTypes.bool
, remote: React.PropTypes.string
}
, getDefaultProps: function() {
return {
backdrop: true
, keyboard: true
, show: true
, remote: ''
}
}
, componentDidMount: function() {
var $modal = $(this.getDOMNode()).modal({
backdrop: this.props.backdrop
, keyboard: this.props.keyboard
, show: this.props.show
, remote: this.props.remote
})
handlerProps.forEach(function(prop) {
if (this[prop]) {
$modal.on(bsModalEvents[prop], this[prop])
}
if (this.props[prop]) {
$modal.on(bsModalEvents[prop], this.props[prop])
}
}.bind(this))
}
, componentWillUnmount: function() {
var $modal = $(this.getDOMNode())
handlerProps.forEach(function(prop) {
if (this[prop]) {
$modal.off(bsModalEvents[prop], this[prop])
}
if (this.props[prop]) {
$modal.off(bsModalEvents[prop], this.props[prop])
}
}.bind(this))
}
, hide: function() {
$(this.getDOMNode()).modal('hide')
}
, show: function() {
$(this.getDOMNode()).modal('show')
}
, toggle: function() {
$(this.getDOMNode()).modal('toggle')
}
, renderCloseButton: function() {
return <button
type="button"
className="close"
onClick={this.hide}
dangerouslySetInnerHTML={{__html: '&times'}}
/>
}
}
}()
/** @jsx React.DOM */
var ExampleModal = React.createClass({
mixins: [BootstrapModalMixin]
, render: function() {
var buttons = this.props.buttons.map(function(button) {
return <button type="button" className={'btn btn-' + button.type} onClick={button.handler}>
{button.text}
</button>
})
return <div className="modal fade">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
{this.renderCloseButton()}
<strong>{this.props.header}</strong>
</div>
<div className="modal-body">
{this.props.children}
</div>
<div className="modal-footer">
{buttons}
</div>
</div>
</div>
</div>
}
})
var ExampleApp = React.createClass({
getInitialState: function() {
return {
logs: []
}
}
, render: function() {
var buttons = [
{type: 'danger', text: 'Hide Modal', handler: this.handleExternalHide}
, {type: 'primary', text: 'Do Nothing', handler: this.handleDoingNothing}
]
var logs = this.state.logs.map(function(log) {
return <div className={'alert alert-' + log.type}>
[<strong>{log.time}</strong>] {log.message}
</div>
})
return <div className="panel panel-default">
<div className="panel-heading">
<h3 className="panel-title">Demo</h3>
</div>
<div className="panel-body">
<button type="button" className="btn btn-primary btn-lg btn-block" onClick={this.handleShowModal}>Show Modal</button>
<h3>Logs</h3>
{logs}
</div>
<ExampleModal ref="modal"
show={false}
header="Example Modal"
buttons={buttons}
handleShow={this.handleLog.bind(this, 'Modal about to show', 'info')}
handleShown={this.handleLog.bind(this, 'Modal showing', 'success')}
handleHide={this.handleLog.bind(this, 'Modal about to hide', 'warning')}
handleHidden={this.handleLog.bind(this, 'Modal hidden', 'danger')}
>
<p>I'm the content.</p>
<p>That's about it, really.</p>
</ExampleModal>
</div>
}
, handleShowModal: function() {
this.refs.modal.show()
}
, handleExternalHide: function() {
this.refs.modal.hide()
}
, handleDoingNothing: function() {
this.handleLog("Remember I said I'd do nothing? ...I lied!", 'danger')
}
, handleLog: function(message, type) {
this.setState({
logs: [{ type: type
, time: new Date().toLocaleTimeString()
, message: message}].concat(this.state.logs.slice(0, 3))
})
}
})
React.renderComponent(<ExampleApp/>, document.getElementById('example'))
<!DOCTYPE html>
<html>
<head>
<title>BootstrapModalMixin for React components</title>
<script src="http://fb.me/react-0.8.0.js"></script>
<script src="http://fb.me/JSXTransformer-0.8.0.js"></script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap-theme.min.css">
</head>
<body>
<div class="container">
<div class="page-header">
<h1>BootstrapModalMixin for <a href="http://facebook.github.io/react/">React components</a></h1>
<p>A <a href="http://facebook.github.io/react/docs/reusable-components.html">mixin for components</a> which act as <a href="http://getbootstrap.com/javascript/#modals">Bootstrap modals</a>, providing:</p>
<ul>
<li>Registration of the component as a modal at the appropriate point in the component lifecycle
<ul>
<li>Components are responsible for providing full modal contents in their own <code>render</code> method</lI>
</ul>
</li>
<li>Properties for modal configuration, with default values as per Bootstrap's defaults
<ul>
<li><code>backdrop</code></li>
<li><code>keyboard</code></li>
<li><code>show</code></li>
<li><code>remote</code></li>
</ul>
</li>
<li>Registration and removal of event handlers with React-style naming conventions when any of the following properties are part of the modal component's prototype or are passed in as component props (in that order)
<ul>
<li><code>handleShow</code></li>
<li><code>handleShown</code></li>
<li><code>handleHide</code></li>
<li><code>handleHidden</code></li>
</ul>
</li>
<li>A convenience method for rendering a <span style="font-size: 21px">&times;</span> close button: <code>renderCloseButton()</code></li>
</ul>
</div>
<div id="example"></div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Code</h3>
</div>
<div class="panel-body">
<script src="https://gist.github.com/insin/8449696.js"></script>
</div>
</div>
</div>
<script type="text/jsx" src="BootstrapModalMixin.js"></script>
<script type="text/jsx" src="example.js"></script>
<a href="https://gist.github.com/insin/8449696"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment