nest-parrot
Version:
Parrot built on react
372 lines (370 loc) • 10.7 kB
JSX
(function (window, $, React, ReactDOM, $pt) {
var NPanel = React.createClass($pt.defineCellComponent({
displayName: 'NPanel',
getDefaultProps: function () {
return {
defaultOptions: {
collapsible: false,
expanded: true,
style: 'default'
}
};
},
installMonitors: function() {
if (this.hasCheckInTitle()) {
this.getModel().addPostChangeListener(this.getCheckInTitleDataId(), this.onTitleCheckChanged);
}
},
uninstallMonitors: function() {
if (this.hasCheckInTitle()) {
this.getModel().removePostChangeListener(this.getCheckInTitleDataId(), this.onTitleCheckChanged);
}
},
beforeWillUpdate: function (nextProps) {
this.uninstallMonitors();
},
beforeDidUpdate: function (prevProps, prevState) {
this.installMonitors();
},
beforeDidMount: function () {
this.installMonitors();
},
beforeWillUnmount: function () {
this.uninstallMonitors();
},
getDependencyOptions: function() {
return ['collapsedLabel', 'expandedLabel'];
},
/**
* render check in title
* @returns {XML}
*/
renderCheckInTitle: function () {
if (!this.hasCheckInTitle()) {
return null;
}
var layout = {
label: this.getCheckInTitleLabel(),
dataId: this.getCheckInTitleDataId(),
comp: $.extend({labelAttached: 'left'}, this.getCheckInTitleOption(), {
type: $pt.ComponentConstants.Check,
labelDirection: 'horizontal'
})
};
return (<div>
(<$pt.Components.NCheck model={this.getModel()} layout={$pt.createCellLayout('check', layout)} view={this.isViewMode()}/>)
</div>);
},
renderHeadingButtons: function() {
var headButtons = this.getComponentOption('headerButtons');
if (headButtons) {
headButtons = Array.isArray(headButtons) ? headButtons : [headButtons];
var _this = this;
return (<div className="btn-toolbar pull-right" role='toolbar'>
{headButtons.map(function(button, buttonIndex) {
if (_this.isViewMode() && button.view == 'edit') {
return null;
} else if (!_this.isViewMode() && button.view == 'view') {
return null;
}
var layout = {
label: button.text,
comp: button
};
// delete layout.comp.label;
// console.log(layout);
return <$pt.Components.NFormButton model={_this.getModel()}
layout={$pt.createCellLayout('pseudo-button', layout)}
key={buttonIndex} />;
}).filter(function(button) {
return button != null;
})}
</div>);
} else {
return null;
}
},
renderCustomHeader: function() {
var customHeader = this.getComponentOption('customHeader');
if (typeof customHeader === 'function') {
return customHeader.call(this);
} else {
return customHeader;
}
},
/**
* render heading
* @returns {XML}
*/
renderHeading: function () {
var label = this.getTitle();
var css = {
'panel-title': true
};
if (this.isCollapsible()) {
css['n-collapsible-title-check'] = this.hasCheckInTitle();
return (<div className='panel-heading'>
<h4 className={$pt.LayoutHelper.classSet(css)}>
<a href='javascript:void(0);' onClick={this.onTitleClicked} ref='head'>{label}</a>
{this.renderCheckInTitle()}
</h4>
{this.renderCustomHeader()}
{this.renderHeadingButtons()}
</div>);
} else if (this.hasCheckInTitle()) {
css['n-normal-title-check'] = this.hasCheckInTitle();
return (<div className='panel-heading'>
<h4 className={$pt.LayoutHelper.classSet(css)}>
<span ref='head'>{label}</span>
{this.renderCheckInTitle()}
</h4>
{this.renderCustomHeader()}
{this.renderHeadingButtons()}
</div>);
} else {
return (<div className='panel-heading' ref='head'>
{label}
{this.renderCustomHeader()}
{this.renderHeadingButtons()}
</div>);
}
},
/**
* render row
* @param row {RowLayout}
*/
renderRow: function (row, rowIndex) {
var _this = this;
var cells = row.getCells().map(function (cell, cellIndex) {
return <$pt.Components.NFormCell layout={cell}
model={_this.getModel()}
ref={cell.getId()}
direction={_this.props.direction}
view={_this.isViewMode()}
key={'' + rowIndex + '-' + cellIndex}/>;
});
return (<div className="row" key={rowIndex}>{cells}</div>);
},
/**
* render
* @returns {XML}
*/
render: function () {
var label = this.getLayout().getLabel(this);
if (label == null) {
return (<div ref='panel'>
{this.getInnerLayout().getRows().map(this.renderRow)}
</div>);
}
var expanded = this.canExpanded() && this.isExpanded();
var css = {
panel: true,
'panel-collapsible': this.isCollapsible(),
'panel-expanded': expanded
};
css['panel-' + this.getStyle()] = true;
css[this.getComponentCSS('n-panel')] = true;
var bodyStyle = {
display: expanded ? 'block' : 'none'
};
return (<div className={$pt.LayoutHelper.classSet(css)} ref='panel'>
{this.renderHeading()}
<div className='panel-body' style={bodyStyle} ref='body'>
{this.getInnerLayout().getRows().map(this.renderRow)}
</div>
</div>);
},
/**
* get inner layout
* @returns {SectionLayout}
*/
getInnerLayout: function () {
return $pt.createSectionLayout({layout: this.getComponentOption('editLayout')});
},
/**
* is collapsible or not
* @returns {boolean}
*/
isCollapsible: function () {
return this.getComponentOption('collapsible');
},
/**
* is expanded
* @returns {boolean}
*/
isExpanded: function () {
if (this.state.expanded == null) {
// first equals 'expanded' definition
this.state.expanded = this.getComponentOption('expanded');
if (this.hasCheckInTitle()) {
// when there is a check-box in title
var value = this.getCheckInTitleValue();
var action = this.getCheckInTitleCollapsible();
if (action === 'same') {
// check behavior same as collapsible
// all expanded, finally expanded
this.state.expanded = this.state.expanded && (value === true);
} else if (action === 'reverse') {
// check behavior reversed as collapsible
// all expanded, finally expanded
this.state.expanded = this.state.expanded && (value !== true);
}
}
}
return this.state.expanded;
},
/**
* get style
* @returns {string}
*/
getStyle: function () {
return this.getComponentOption('style');
},
getTitle: function () {
var label = this.getLayout().getLabel(this);
if (this.state.expanded) {
var expandedLabel = this.getExpandedLabelRenderer();
if (expandedLabel) {
if (typeof expandedLabel === 'string') {
label = expandedLabel;
} else {
label = expandedLabel.when.call(this, this.getModel());
}
}
} else {
var collapsedLabel = this.getCollapsedLabelRenderer();
if (collapsedLabel) {
if (typeof collapsedLabel === 'string') {
label = collapsedLabel;
} else {
label = collapsedLabel.when.call(this, this.getModel());
}
}
}
return label;
},
getExpandedLabelRenderer: function () {
return this.getComponentOption('expandedLabel');
},
getCollapsedLabelRenderer: function () {
return this.getComponentOption('collapsedLabel');
},
/**
* has check box in title or not
* @returns {boolean}
*/
hasCheckInTitle: function () {
return this.getComponentOption('checkInTitle') != null;
},
/**
* get check box value of panel title
* @returns {boolean}
*/
getCheckInTitleValue: function () {
var id = this.getCheckInTitleDataId();
return id ? this.getModel().get(id) : null;
},
/**
* get check box data id of panel title
* @returns {string}
*/
getCheckInTitleDataId: function () {
var checkInTitle = this.getComponentOption('checkInTitle');
return checkInTitle ? checkInTitle.data : null;
},
/**
* get check box label of panel title
* @returns {string}
*/
getCheckInTitleLabel: function () {
var checkInTitle = this.getComponentOption('checkInTitle');
return checkInTitle ? checkInTitle.label : null;
},
/**
* get check box value and collapsible is related or not
* @returns {same|reverse}
*/
getCheckInTitleCollapsible: function () {
var checkInTitle = this.getComponentOption('checkInTitle');
return checkInTitle ? checkInTitle.collapsible : null;
},
/**
* get other check in title options
* @returns {null}
*/
getCheckInTitleOption: function () {
var checkInTitle = this.getComponentOption('checkInTitle');
if (checkInTitle) {
var options = $.extend({}, checkInTitle);
delete options.data;
delete options.label;
delete options.collapsible;
return options;
} else {
return null;
}
},
/**
* on title clicked
* @param e
*/
onTitleClicked: function (e) {
e.selected = false;
e.preventDefault();
this.toggleExpanded(!this.state.expanded);
},
/**
* on title check-box value changed
* @param evt
*/
onTitleCheckChanged: function (evt) {
var value = evt.new;
var collapsible = this.getCheckInTitleCollapsible();
if (collapsible === 'same') {
this.toggleExpanded(value);
} else if (collapsible === 'reverse') {
this.toggleExpanded(!value);
}
},
/**
* toggle panel expanded
* @param expanded {boolean}
*/
toggleExpanded: function (expanded) {
if (expanded) {
if (this.canExpanded()) {
// panel can be expanded
$(ReactDOM.findDOMNode(this.refs.body)).slideDown(300, function () {
this.setState({expanded: true});
}.bind(this));
}
} else {
$(ReactDOM.findDOMNode(this.refs.body)).slideUp(300, function () {
this.setState({expanded: false});
}.bind(this));
}
},
/**
* check the panel can expanded or not
* @returns {boolean}
*/
canExpanded: function () {
if (this.hasCheckInTitle()) {
var value = this.getCheckInTitleValue();
var collapsible = this.getCheckInTitleCollapsible();
if (collapsible === 'same') {
// check behavior same as collapsible
return value === true;
} else if (collapsible === 'reverse') {
// check behavior reversed as collapsible
return value !== true;
}
}
return true;
}
}));
$pt.Components.NPanel = NPanel;
$pt.LayoutHelper.registerComponentRenderer($pt.ComponentConstants.Panel, function (model, layout, direction, viewMode) {
return <$pt.Components.NPanel {...$pt.LayoutHelper.transformParameters(model, layout, direction, viewMode)}/>;
});
}(window, jQuery, React, ReactDOM, $pt));