ssc-grid
Version:
React grid component for SSC 3.0
521 lines (439 loc) • 14.8 kB
JavaScript
'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'];