nest-parrot
Version:
Parrot built on react
305 lines (304 loc) • 8.35 kB
JSX
/**
* modal confirm dialog
* z-index is 9699 and 9698, less than exception dialog, on request dialog and code search dialog, more than any other.
*
* depends NFormButton
*/
(function (window, $, React, ReactDOM, $pt) {
var NConfirm = React.createClass({
displayName: 'NConfirm',
statics: {
getConfirmModal: function (className) {
if ($pt.confirmDialog === undefined || $pt.confirmDialog === null) {
var confirmContainer = $("#confirm_modal_container");
if (confirmContainer.length == 0) {
$("<div id='confirm_modal_container' />").appendTo($(document.body));
}
$pt.confirmDialog = ReactDOM.render(<$pt.Components.NConfirm className={className}/>,
document.getElementById("confirm_modal_container"));
}
return $pt.confirmDialog;
},
OK_TEXT: 'OK',
OK_ICON: 'check',
CLOSE_TEXT: 'Close',
CLOSE_ICON: 'ban',
CANCEL_TEXT: 'Cancel',
CANCEL_ICON: 'ban',
Z_INDEX: 9698
},
getDefaultProps: function () {
return {};
},
getInitialState: function () {
return {
visible: false
};
},
/**
* set z-index
*/
fixDocumentPadding: function () {
document.body.style.paddingRight = 0;
},
/**
* did update
* @param prevProps
* @param prevState
*/
componentDidUpdate: function (prevProps, prevState) {
this.fixDocumentPadding();
if (this.state.visible) {
$(document).on('keyup', this.onDocumentKeyUp);
} else {
$(document).off('keyup', this.onDocumentKeyUp);
}
},
/**
* did mount
*/
componentDidMount: function () {
this.fixDocumentPadding();
if (this.state.visible) {
$(document).on('keyup', this.onDocumentKeyUp);
} else {
$(document).off('keyup', this.onDocumentKeyUp);
}
},
componentWillUpdate: function() {
$(document).off('keyup', this.onDocumentKeyUp);
},
componentWillUnmount: function() {
$(document).off('keyup', this.onDocumentKeyUp);
},
/**
* render confirm button
* @returns {XML}
*/
renderConfirmButton: function () {
if (this.state.options && this.state.options.disableConfirm) {
return null;
}
var layout = $pt.createCellLayout('pseudo-button', {
label: this.state.options && this.state.options.confirmText ? this.state.options.confirmText : NConfirm.OK_TEXT,
comp: {
type: $pt.ComponentConstants.Button,
icon: this.state.options && this.state.options.confirmIcon ? this.state.options.confirmIcon : NConfirm.OK_ICON,
style: 'primary',
click: this.onConfirmClicked
}
});
return <$pt.Components.NFormButton layout={layout} model={$pt.createModel({})}/>;
},
/**
* render close button
* @returns {XML}
*/
renderCloseButton: function () {
if (this.state.options && this.state.options.disableClose) {
return null;
}
var layout = $pt.createCellLayout('pseudo-button', {
label: (this.state.options && this.state.options.close) ? NConfirm.CLOSE_TEXT : NConfirm.CANCEL_TEXT,
comp: {
type: $pt.ComponentConstants.Button,
icon: (this.state.options && this.state.options.close) ? NConfirm.CLOSE_ICON : NConfirm.CANCEL_ICON,
style: 'danger',
click: this.onCancelClicked
}
});
return <$pt.Components.NFormButton layout={layout} model={$pt.createModel({})}/>;
},
renderDialogCloseButton: function() {
if (this.isDialogCloseShown()) {
return (<button className="close"
onClick={this.onCancelClicked}
aria-label="Close"
style={{marginTop: '-2px'}}>
<span aria-hidden="true">×</span>
</button>);
}
return null;
},
/**
* render footer
* @returns {XML}
*/
renderFooter: function () {
if (this.state.options && this.state.options.disableButtons) {
return <div className='modal-footer-empty'/>;
}
return (<div className="modal-footer">
{this.renderCloseButton()}
{this.renderConfirmButton()}
</div>);
},
/**
* render content
*/
renderContent: function () {
var messages = this.state.options;
if (typeof messages === "string") {
messages = [messages];
}
if (!Array.isArray(messages)) {
messages = messages.messages;
if (typeof messages === "string") {
messages = [messages];
}
}
// string array
return messages.map(function (element, index) {
return <h6 key={index}>{element}</h6>;
});
},
/**
* render
* @returns {XML}
*/
render: function () {
if (!this.state.visible) {
return null;
}
var css = {
'n-confirm': true,
modal: true,
fade: true,
in: true
};
if (this.props.className) {
css[this.props.className] = true;
}
return (<div>
<div className="modal-backdrop fade in" style={{zIndex: NConfirm.Z_INDEX}}></div>
<div className={$pt.LayoutHelper.classSet(css)}
tabIndex="-1"
role="dialog"
ref="container"
style={{display: 'block', zIndex: NConfirm.Z_INDEX + 1}}>
<div className="modal-dialog" tabIndex='0'>
<div className="modal-content" role="document">
<div className="modal-header">
{this.renderDialogCloseButton()}
<h4 className="modal-title">{this.state.title}</h4>
</div>
<div className="modal-body">
{this.renderContent()}
</div>
{this.renderFooter()}
</div>
</div>
</div>
</div>);
},
onDocumentKeyUp: function(evt) {
if (evt.keyCode === 27) { // escape
this.onCancelClicked();
} else if (evt.keyCode === 9) { // tab
// evt.preventDefault();
var target = $(evt.target);
var container = $(this.refs.container);
if (target.closest(container).length == 0) {
container.focus();
}
}
},
/**
* hide dialog
*/
hide: function () {
this.setState({
visible: false,
title: null,
options: null,
onConfirm: null,
onCancel: null
});
},
/**
* on confirm clicked
*/
onConfirmClicked: function () {
if (this.state.onConfirm) {
this.state.onConfirm.call(this);
}
this.hide();
if (this.state.afterClose) {
this.state.afterClose.call(this, 'confirm');
}
},
/**
* on cancel clicked
*/
onCancelClicked: function () {
if (this.state.onCancel) {
this.state.onCancel.call(this);
}
this.hide();
if (this.state.afterClose) {
this.state.afterClose.call(this, 'cancel');
}
},
isDialogCloseShown: function() {
return this.state && this.state.buttons && this.state.buttons.disableDialogClose === true;
},
/**
* show dialog
*
* from 0.0.3
* all parameters should be pass to #show in first as a JSON object
*
* @param title deprecated title of dialog
* @param options string or string array, or object as below.
* {
* disableButtons: true, // hide button bar
* disableConfirm: true, // hide confirm button
* disableClose: true, // hide close button
* messsages: "", // string or string array,
* close: true, // show close button text as "close"
* onConfirm: function,
* onCancel: function,
* afterClose: function,
* title: string
* }
* @param onConfirm deprecated callback function when confirm button clicked
* @param onCancel deprecated callback function when cancel button clicked
*/
show: function (title, options, onConfirm, onCancel) {
$(':focus').blur();
var state;
if (typeof title === 'string') {
state = {
visible: true,
title: title,
options: options,
onConfirm: onConfirm,
onCancel: onCancel,
afterClose: options.afterClose
};
} else {
// for new API
options = title;
state = {
visible: true,
title: options.title,
options: {
disableButtons: options.disableButtons,
disableConfirm: options.disableConfirm,
disableClose: options.disableClose,
disableDialogClose: options.disableDialogClose,
confirmText: options.confirmText,
confirmIcon: options.confirmIcon,
close: options.close,
messages: options.messages
},
onConfirm: options.onConfirm,
onCancel: options.onCancel,
afterClose: options.afterClose
};
}
this.setState(state);
}
});
$pt.Components.NConfirm = NConfirm;
}(window, jQuery, React, ReactDOM, $pt));