UNPKG

nest-parrot

Version:
372 lines (370 loc) 10.7 kB
(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));