UNPKG

ssc-grid

Version:

React grid component for SSC 3.0

521 lines (439 loc) 14.8 kB
'use strict'; exports.__esModule = true; var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _elementType = require('react-prop-types/lib/elementType'); var _elementType2 = _interopRequireDefault(_elementType); var _moment = require('moment'); var _moment2 = _interopRequireDefault(_moment); require('moment/locale/zh-cn'); var _numeral = require('numeral'); var _numeral2 = _interopRequireDefault(_numeral); require('core-js/fn/array/find'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } // 对MouseEvent进行定义,需要放在全局环境中,方便形成jsdoc文档 /** * @typedef {Object} MouseEvent */ // load a locale // 使用numeral对单元格中的数字进行格式化 // 使用moment对单元格中的日期进行格式化 /* eslint-disable no-unused-vars */ _numeral2['default'].register('locale', 'chs', { delimiters: { thousands: ',', decimal: '.' }, abbreviations: { thousand: '千', million: '百万', billion: '十亿', trillion: '兆' }, ordinal: function ordinal() /* number */{ return '.'; }, currency: { symbol: '¥' } }); // switch between locales // YBZSAAS-461 // IE11不支持Array.prototype.find() _numeral2['default'].locale('chs'); var propTypes = { className: _propTypes2['default'].string, /** * 用于指定列模型,比如每个字段的类型是什么,字段类型决定了单元格的样式。 */ columnsModel: _propTypes2['default'].oneOfType([_propTypes2['default'].array, // 默认类型应该是数组,但是为了支持mobx传入observable object... _propTypes2['default'].object]).isRequired, /** * 单元格单击事件 */ onCellClick: _propTypes2['default'].func, /** * 单元格双击事件 */ onCellDoubleClick: _propTypes2['default'].func, /** * 行单击事件 */ onRowClick: _propTypes2['default'].func, /** * 行双击事件 */ onRowDoubleClick: _propTypes2['default'].func, onSelect: _propTypes2['default'].func, /** * 每一行是否显示操作按钮列<br> * 默认的操作按钮在最右侧的列中,如果需要指定在左侧,可以通过 * <code>align</code>参数来设置<br> * <pre><code>{ * align: 'left' * }</code></pre> * 注意:当操作列和选择列同时存在的时候,选择列会显示在操作列的左侧 */ operationColumn: _propTypes2['default'].object, /** * 自定义的操作列组件<br> * 除非指定了<code>operationColumn</code>参数,否则操作列不会显示出来 */ operationColumnClass: _elementType2['default'], /** * 表格中本行的index,从0开始,等同于key */ rowIdx: _propTypes2['default'].number.isRequired, /** * 本行中每一列的数据 * <pre><code>{ * id: '11', * danjuleixing: '123' * }</code></pre> */ rowObj: _propTypes2['default'].object.isRequired, /** * 该行是否被选择(单选框/复选框) * 默认未被选中 * TODO 需要和selectRow属性合并 */ selected: _propTypes2['default'].bool, selectionMode: _propTypes2['default'].string, /** * 显示行选择复选框/单选框<br> * mode 默认是checkbox,也可以是radio * onSelect 当点击行最左侧的复选框/单选框的时候 */ selectRow: _propTypes2['default'].object }; var defaultProps = { className: '', selectable: true, selectRow: null, selectionMode: 'checkbox', selected: false, operationColumn: null }; /** * GridRow组件 */ var GridRow = function (_Component) { (0, _inherits3['default'])(GridRow, _Component); function GridRow(props) { (0, _classCallCheck3['default'])(this, GridRow); var _this = (0, _possibleConstructorReturn3['default'])(this, _Component.call(this, props)); _this.renderCells = function () { var _this$props = _this.props, rowIdx = _this$props.rowIdx, rowObj = _this$props.rowObj, columnsModel = _this$props.columnsModel; return columnsModel.map(function (columnModel, colIdx) { // 隐藏列 if (columnModel.hidden === true) { return null; } var className = ''; var cellContent = ''; // value的可能不是string,比如参照类型,value的类型是object var value = rowObj[columnModel.id]; // 如果用户提供了自定义格式化方式,首选指定方法 if (columnModel.formatter && columnModel.formatter.type === 'custom') { cellContent = columnModel.formatter.callback(value, rowObj); } else { // 根据不同类型,渲染成不同值 switch (columnModel.type) { default: case 'string': // 0 if (value === null || value === undefined) { cellContent = ''; } else { cellContent = value; } break; case 'double': // 2 之前的金额类型 if (value === null || value === undefined) { cellContent = ''; } else { cellContent = _this.getNumberFormat(columnModel, value); } break; case 'date': // 3 // 传入的数据为空的时候,UI上直接显示空字符串就行 if (value === '' || value === null || value === undefined) { cellContent = ''; } else { cellContent = _this.getDateFormat(columnModel, value); } break; case 'boolean': // 4 if (value === null || value === undefined) { cellContent = ''; } else { cellContent = value; } break; case 'ref': // 5 if (columnModel.multiple) { cellContent = value.map(function (val) { return val.name || val.id || ''; }); cellContent = cellContent.join(); } else { cellContent = value && value.name ? value.name : ''; } break; case 'enum': // 6 if (columnModel.data) { var foundEnumItem = columnModel.data.find(function (enumItem) { return enumItem.key === value; }); if (typeof foundEnumItem !== 'undefined') { cellContent = foundEnumItem.value; } } break; } } // 如果用户提供的数据有问题,比如columnModel.type是string,但是value却是 // 一个Object,那么这里只能强制类型转换了。 // TODO 需要给用户提示数据错误问题。 cellContent = String(cellContent); // The default align rule for double type is RIGHT if (columnModel.type === 'double') { className = 'text-right'; } // User can override the default align rule if (columnModel.align) { className = 'text-' + columnModel.align; } // 添加列类名 className = (0, _classnames2['default'])(className, columnModel.columnClassName); var tdInner = cellContent; // 该列是否有悬浮按钮(一个奇葩需求) if (columnModel.floatOperationComponent) { tdInner = _react2['default'].createElement( 'div', { style: { position: 'relative' } }, _react2['default'].createElement( 'div', { style: { position: 'relative', top: '0px', left: '0px' } }, cellContent ), _react2['default'].createElement( 'div', { id: 'curtain', style: { position: 'absolute', top: '0px', right: '0px' } }, _react2['default'].createElement(columnModel.floatOperationComponent, { rowIdx: rowIdx, rowObj: rowObj }) ) ); } var _this$props2 = _this.props, onCellClick = _this$props2.onCellClick, onCellDoubleClick = _this$props2.onCellDoubleClick; return _react2['default'].createElement( 'td', { key: colIdx, className: className, title: cellContent, onClick: function onClick(event) { if (onCellClick) { onCellClick(event, colIdx, columnModel, rowIdx, rowObj); } }, onDoubleClick: function onDoubleClick(event) { if (onCellDoubleClick) { onCellDoubleClick(event, colIdx, columnModel, rowIdx, rowObj); } } }, tdInner ); }); }; return _this; } /** * @param {MouseEvent} event * @memberof GridRow */ GridRow.prototype.handleCheckboxChange = function handleCheckboxChange(event) { var onSelect = this.props.onSelect; var checked = event.target.checked; if (onSelect) { onSelect(checked, event); } }; /** * 鼠标单击当前行时候触发 * @param {Object} rowObj * @param {MouseEvent} event * @memberof GridRow */ GridRow.prototype.handleRowClick = function handleRowClick(rowObj, event) { var onRowClick = this.props.onRowClick; if (onRowClick) { onRowClick(event, rowObj); } }; /** * 鼠标双击当前行时候触发 * @param {Object} rowObj * @param {MouseEvent} event * @memberof GridRow */ GridRow.prototype.handleRowDoubleClick = function handleRowDoubleClick(rowObj, event) { var onRowDoubleClick = this.props.onRowDoubleClick; if (onRowDoubleClick) { onRowDoubleClick(event, rowObj); } }; /** * 日期类型格式化 * @param {Object} columnModel * columnModel.formatter: * - undefined - 不进行格式化 * - {} - 进行格式化,使用默认格式化模板 * - { format: 'yy/mm/dd' } - 按照指定的模板进行格式化 * @param {String} value 必须是非空的字符串 */ GridRow.prototype.getDateFormat = function getDateFormat(columnModel, value) { var dateFormat = null; var cellContent = ''; if (columnModel.formatter) { dateFormat = columnModel.formatter.format || 'YYYY-MM-DD'; cellContent = (0, _moment2['default'])(value).format(dateFormat); } else { cellContent = value; } return cellContent; }; /** * 数字类型格式化 * columnModel.formatter: * undefined - 不进行格式化 * {} - 进行格式化,使用默认格式化模板 * { format: '$0,0.00' } - 按照指定的模板进行格式化 */ GridRow.prototype.getNumberFormat = function getNumberFormat(columnModel, value) { var numFormat = null; var cellContent = ''; if (columnModel.formatter) { numFormat = columnModel.formatter.format || '0,0.00'; cellContent = (0, _numeral2['default'])(value).format(numFormat); } else { cellContent = value; } return cellContent; }; // 渲染操作列,比如修改和删除按钮 GridRow.prototype.renderOperationColumn = function renderOperationColumn() { var _props = this.props, rowIdx = _props.rowIdx, rowObj = _props.rowObj, CustomComponent = _props.operationColumnClass, operationColumn = _props.operationColumn; if (!operationColumn) { return null; } return _react2['default'].createElement(CustomComponent, { rowIdx: rowIdx, rowObj: rowObj }); }; GridRow.prototype.renderSelectionColumn = function renderSelectionColumn() { var _props2 = this.props, rowIdx = _props2.rowIdx, rowObj = _props2.rowObj, selectRow = _props2.selectRow, selectionMode = _props2.selectionMode, selected = _props2.selected; if (!selectRow) { return null; } return _react2['default'].createElement( 'td', null, _react2['default'].createElement('input', { type: selectionMode, checked: selected, onChange: this.handleCheckboxChange.bind(this) }) ); }; GridRow.prototype.render = function render() { var _props3 = this.props, columnsModel = _props3.columnsModel, rowObj = _props3.rowObj, operationColumn = _props3.operationColumn; var _props4 = this.props, onRowClick = _props4.onRowClick, onRowDoubleClick = _props4.onRowDoubleClick; var trProps = { className: (0, _classnames2['default'])(this.props.className, { 'selected': this.props.selected }), 'data-row-index': this.props.rowIdx, onClick: function onClick(event) { if (onRowClick) { onRowClick(event, rowObj); } }, onDoubleClick: function onDoubleClick(event) { if (onRowDoubleClick) { onRowDoubleClick(event, rowObj); } } }; // 默认操作列在右侧,除非用户专门指定在左侧 var row = void 0; if (operationColumn && operationColumn.align === 'left') { row = _react2['default'].createElement( 'tr', trProps, this.renderSelectionColumn(), this.renderOperationColumn(), this.renderCells() ); } else { row = _react2['default'].createElement( 'tr', trProps, this.renderSelectionColumn(), this.renderCells(), this.renderOperationColumn() ); } return row; }; return GridRow; }(_react.Component); GridRow.displayName = 'GridRow'; exports['default'] = GridRow; GridRow.propTypes = propTypes; GridRow.defaultProps = defaultProps; module.exports = exports['default'];