1 | /** @jsx React.DOM */ |
---|
2 | (function() { |
---|
3 | "use strict"; |
---|
4 | |
---|
5 | var PT = React.PropTypes; |
---|
6 | var ReactCSSTransitionGroup = React.addons.ReactCSSTransitionGroup; |
---|
7 | var ReactTransitionGroup = React.addons.TransitionGroup; |
---|
8 | |
---|
9 | window.MyReact = {}; |
---|
10 | |
---|
11 | var JQuerySlide = React.createClass({ |
---|
12 | componentWillEnter: function(callback){ |
---|
13 | var el = jQuery(this.getDOMNode()); |
---|
14 | el.css("display", "none"); |
---|
15 | el.slideDown(500, callback); |
---|
16 | $el.slideDown(function(){ |
---|
17 | callback(); |
---|
18 | }); |
---|
19 | }, |
---|
20 | componentWillLeave: function(callback){ |
---|
21 | var $el = jQuery(this.getDOMNode()); |
---|
22 | $el.slideUp(function(){ |
---|
23 | callback(); |
---|
24 | }); |
---|
25 | }, |
---|
26 | render: function(){ |
---|
27 | return this.transferPropsTo(this.props.component({style: {display: 'none'}})); |
---|
28 | } |
---|
29 | }); |
---|
30 | window.MyReact.JQuerySlide = JQuerySlide; |
---|
31 | |
---|
32 | var JQueryFade = React.createClass({ |
---|
33 | componentWillEnter: function(callback){ |
---|
34 | var el = jQuery(this.getDOMNode()); |
---|
35 | el.css("display", "none"); |
---|
36 | el.fadeIn(500, callback); |
---|
37 | }, |
---|
38 | componentWillLeave: function(callback){ |
---|
39 | jQuery(this.getDOMNode()).fadeOut(500, callback); |
---|
40 | }, |
---|
41 | render: function() { |
---|
42 | return this.props.children; |
---|
43 | } |
---|
44 | }); |
---|
45 | window.MyReact.JQueryFade = JQueryFade; |
---|
46 | |
---|
47 | window.MyReact.ErrorPane = React.createClass({ |
---|
48 | propTypes: { |
---|
49 | errorMessages: PT.array.isRequired, |
---|
50 | }, |
---|
51 | |
---|
52 | renderErrorMessage: function(errorMessage, index) { |
---|
53 | return errorMessage ? |
---|
54 | <JQueryFade key={index}> |
---|
55 | <div key={index} className="errorMessage">{errorMessage}</div> |
---|
56 | </JQueryFade> : |
---|
57 | false; |
---|
58 | }, |
---|
59 | |
---|
60 | render: function() { |
---|
61 | return <div className="container errorDiv"> |
---|
62 | <div className="row errorRow"> |
---|
63 | <ReactTransitionGroup component="div"> |
---|
64 | {this.props.errorMessages.map(this.renderErrorMessage)} |
---|
65 | </ReactTransitionGroup> |
---|
66 | </div> |
---|
67 | </div>; |
---|
68 | } |
---|
69 | }); |
---|
70 | |
---|
71 | |
---|
72 | window.MyReact.ModalMixin = { |
---|
73 | componentDidMount: function() { |
---|
74 | $(this.getDOMNode()).modal({background: true, keyboard: true, show: false}); |
---|
75 | }, |
---|
76 | componentWillUnmount: function() { |
---|
77 | $(this.getDOMNode()).off('hidden'); |
---|
78 | }, |
---|
79 | handleClick: function(e) { |
---|
80 | e.stopPropagation(); |
---|
81 | }, |
---|
82 | renderModal: function(title, content) { |
---|
83 | return ( |
---|
84 | <div onClick={this.handleClick} className="modal fade" role="dialog" aria-hidden="true"> |
---|
85 | <div className="modal-dialog"> |
---|
86 | <div className="modal-content"> |
---|
87 | <div className="modal-header"> |
---|
88 | <button type="button" className="close" data-dismiss="modal"> |
---|
89 | <span aria-hidden="true">×</span> |
---|
90 | <span className="sr-only">Close</span> |
---|
91 | </button> |
---|
92 | <h2 className="modal-title">{title}</h2> |
---|
93 | </div> |
---|
94 | <div className="modal-body"> |
---|
95 | {content} |
---|
96 | </div> |
---|
97 | <div className="modal-footer"> |
---|
98 | <button type="button" className="btn btn-default" data-dismiss="modal">Close</button> |
---|
99 | </div> |
---|
100 | </div> |
---|
101 | </div> |
---|
102 | </div> |
---|
103 | ); |
---|
104 | } |
---|
105 | }; |
---|
106 | |
---|
107 | |
---|
108 | window.MyReact.Modal = React.createClass({ |
---|
109 | propTypes: { |
---|
110 | title: PT.object.isRequired, |
---|
111 | }, |
---|
112 | componentDidMount: function() { |
---|
113 | $(this.getDOMNode()).modal({background: true, keyboard: true, show: false}); |
---|
114 | }, |
---|
115 | componentWillUnmount: function() { |
---|
116 | $(this.getDOMNode()).off('hidden'); |
---|
117 | }, |
---|
118 | handleClick: function(e) { |
---|
119 | e.stopPropagation(); |
---|
120 | }, |
---|
121 | render: function() { |
---|
122 | return ( |
---|
123 | <div onClick={this.handleClick} className="modal fade" role="dialog" aria-hidden="true"> |
---|
124 | <div className="modal-dialog"> |
---|
125 | <div className="modal-content"> |
---|
126 | <div className="modal-header"> |
---|
127 | <button type="button" className="close" data-dismiss="modal"> |
---|
128 | <span aria-hidden="true">×</span> |
---|
129 | <span className="sr-only">Close</span> |
---|
130 | </button> |
---|
131 | <h2 className="modal-title">{this.props.title}</h2> |
---|
132 | </div> |
---|
133 | <div className="modal-body"> |
---|
134 | {this.props.children} |
---|
135 | </div> |
---|
136 | <div className="modal-footer"> |
---|
137 | <button type="button" className="btn btn-default" data-dismiss="modal">Close</button> |
---|
138 | </div> |
---|
139 | </div> |
---|
140 | </div> |
---|
141 | </div> |
---|
142 | ); |
---|
143 | } |
---|
144 | }); |
---|
145 | |
---|
146 | |
---|
147 | var PopoverMixin = window.MyReact.PopoverMixin = { |
---|
148 | getDefaultProps: function(){ |
---|
149 | return {hasPopover: true}; |
---|
150 | }, |
---|
151 | |
---|
152 | componentDidMount: function() { |
---|
153 | this.refresh(); |
---|
154 | }, |
---|
155 | componentDidUpdate: function() { |
---|
156 | this.refresh(); |
---|
157 | }, |
---|
158 | |
---|
159 | refresh: function() { |
---|
160 | $(this.getDOMNode()).popover('destroy'); |
---|
161 | |
---|
162 | var content; |
---|
163 | if (Array.isArray(this.props.children)) |
---|
164 | content = this.props.children.map(React.renderToString).join(""); |
---|
165 | else |
---|
166 | content = React.renderToString(this.props.children); |
---|
167 | // console.log("children: ", this.props.children); |
---|
168 | // console.log("content: ", content); |
---|
169 | $(this.getDOMNode()).popover({ |
---|
170 | content: content, |
---|
171 | animation: this.props.animation, |
---|
172 | placement: this.props.placement, |
---|
173 | title: this.props.title, |
---|
174 | trigger: 'focus', |
---|
175 | html: true, |
---|
176 | }); |
---|
177 | }, |
---|
178 | |
---|
179 | componentWillUnmount: function() { |
---|
180 | $(this.getDOMNode()).popover('destroy'); |
---|
181 | }, |
---|
182 | }; |
---|
183 | |
---|
184 | window.MyReact.Popover = React.createClass({ |
---|
185 | propTypes: { |
---|
186 | placement: PT.string, |
---|
187 | title: PT.string, |
---|
188 | triggerButtonClass: PT.string, |
---|
189 | triggerButtonContent: PT.element.isRequired |
---|
190 | }, |
---|
191 | mixins: [PopoverMixin], |
---|
192 | |
---|
193 | handleClick: function(e) { |
---|
194 | e.stopPropagation(); |
---|
195 | }, |
---|
196 | |
---|
197 | render: function() { |
---|
198 | return <button className={this.props.triggerButtonClass} onClick={this.handleClick}> |
---|
199 | {this.props.triggerButtonContent} |
---|
200 | </button>; |
---|
201 | } |
---|
202 | }); |
---|
203 | |
---|
204 | window.MyReact.InfoPopover = React.createClass({ |
---|
205 | propTypes: { |
---|
206 | title: PT.string.isRequired, |
---|
207 | }, |
---|
208 | mixins: [PopoverMixin], |
---|
209 | |
---|
210 | handleClick: function(e) { |
---|
211 | e.stopPropagation(); |
---|
212 | }, |
---|
213 | |
---|
214 | render: function() { |
---|
215 | var inline = {display:"inline-block"}; |
---|
216 | return <button style={inline} className="btn btn-default btn-xs" onClick={this.handleClick}> |
---|
217 | <span className="glyphicon glyphicon-info-sign"/> |
---|
218 | </button>; |
---|
219 | } |
---|
220 | }); |
---|
221 | |
---|
222 | |
---|
223 | window.MyReact.Panel = React.createClass({ |
---|
224 | propTypes: { |
---|
225 | title:PT.object.isRequired, |
---|
226 | info:PT.object.isRequired, |
---|
227 | }, |
---|
228 | |
---|
229 | getInitialState: function() { |
---|
230 | return { |
---|
231 | open: true, |
---|
232 | }; |
---|
233 | }, |
---|
234 | |
---|
235 | toggleState: function(e) { |
---|
236 | this.setState({open: !this.state.open}); |
---|
237 | }, |
---|
238 | |
---|
239 | render: function() { |
---|
240 | var chevron = "glyphicon glyphicon-chevron-" + (this.state.open ? "down":"right"); |
---|
241 | return <div className="bs-callout bs-callout-info"> |
---|
242 | <div className="panel"> |
---|
243 | <div className="panel-heading unselectable row" onClick={this.toggleState}> |
---|
244 | <div className="panel-title unselectable col-sm-11"> |
---|
245 | <span className={chevron} style={{fontSize:12}} /> |
---|
246 | {this.props.title} |
---|
247 | </div> |
---|
248 | <div className='float-right'> |
---|
249 | {this.props.info} |
---|
250 | </div> |
---|
251 | </div> |
---|
252 | { this.state.open ? |
---|
253 | <div className="panel-body">{this.props.children}</div> : |
---|
254 | false} |
---|
255 | </div> |
---|
256 | </div>; |
---|
257 | } |
---|
258 | }); |
---|
259 | |
---|
260 | window.MyReact.PanelGroup = React.createClass({ |
---|
261 | render: function() { |
---|
262 | return <div className="panel-group"> {this.props.children} </div>; |
---|
263 | }, |
---|
264 | }); |
---|
265 | |
---|
266 | })(); |
---|