UNPKG

react-material-editlabel

Version:
229 lines (167 loc) 9.58 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _TextField = require('material-ui/TextField'); var _TextField2 = _interopRequireDefault(_TextField); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** @author Maciej Sikora Class creates element with two states - label, and TextField in edit mode **/ var EditLabel = function (_Component) { _inherits(EditLabel, _Component); //edition on double click function EditLabel(props) { _classCallCheck(this, EditLabel); var _this = _possibleConstructorReturn(this, (EditLabel.__proto__ || Object.getPrototypeOf(EditLabel)).call(this, props)); _this.bodyClickEvent = null; //click event on page body _this.changeDeffer = null; _this.state = { edit: false, //edit mode value: _this.props.defValue }; _this.lastValue = _this.props.defValue; return _this; } //input value change handler //edition on single click _createClass(EditLabel, [{ key: 'handleChange', value: function handleChange(e) { var _this2 = this; this.setState({ value: e.target.value }); //deffer to less saving in network if (this.changeDeffer != null) clearTimeout(this.changeDeffer); this.changeDeffer = setTimeout(function () { if (_this2.props.onChange !== null) _this2.props.onChange(_this2.state.value, _this2.props.id); }, 400); } }, { key: 'cancelEditMode', value: function cancelEditMode() { //we clicked ouside current edited element this._removeBodyListener(); this.setState({ edit: false }); //cancel edit if (this.state.value.trim().length === 0 && !this.props.clearEnable) { //value was cleared but it is blocked this.setState({ value: this.lastValue }); //back to last value } else this.lastValue = this.state.value; //save last value; if (this.props.onEditEnd != null) { this.props.onEditEnd(this.state.value, this.props.id); } } }, { key: '_bodyClickHandler', value: function _bodyClickHandler(e) { if (!e.target.dataset || typeof e.target.dataset.id === "undefined" || e.target.dataset.id != this.props.id) { this.cancelEditMode(); } } }, { key: '_removeBodyListener', value: function _removeBodyListener() { if (this.bodyClickEvent !== null) document.removeEventListener("click", this.bodyClickEvent, false); } }, { key: '_addBodyListener', value: function _addBodyListener() { this._removeBodyListener(); this.bodyClickEvent = this._bodyClickHandler.bind(this); document.addEventListener("click", this.bodyClickEvent, false); } }, { key: 'handleLabelClick', value: function handleLabelClick(type, e) { if (this.props.initBy !== type) return; //it is not this event //block propagate e.stopPropagation(); e.preventDefault(); this.setState({ edit: true }); //set binding this._addBodyListener(); if (this.props.onEditStart !== null) this.props.onEditStart(this.state.value, this.props.id); } }, { key: 'handleKeyPress', value: function handleKeyPress(e) { if (e.charCode === 13) { //enter if (this.props.onEnterClick !== null) this.props.onEnterClick(this.state.value, this.props.id); this.cancelEditMode(); } } }, { key: 'handleInputClick', value: function handleInputClick(e) { //block events bubbling e.stopPropagation(); } }, { key: 'getLabelStyle', value: function getLabelStyle() { return { cursor: "pointer" }; } }, { key: 'render', value: function render() { var props = this.props; var tf = _objectWithoutProperties(props.input, []); //textField props var label = _objectWithoutProperties(props.label, []); //label props var inputJSX = void 0; if (this.props.material) inputJSX = _react2.default.createElement(_TextField2.default, _extends({}, tf, { ref: 'input', 'data-id': props.id, name: "input_" + props.id, onClick: this.handleInputClick.bind(this), value: this.state.value, onChange: this.handleChange.bind(this), onKeyPress: this.handleKeyPress.bind(this) }));else //standard input inputJSX = _react2.default.createElement('input', _extends({}, tf, { ref: 'input', 'data-id': props.id, name: "input_" + props.id, onClick: this.handleInputClick.bind(this), value: this.state.value, onChange: this.handleChange.bind(this), onKeyPress: this.handleKeyPress.bind(this) })); var element = void 0; if (this.state.edit) element = inputJSX;else element = _react2.default.createElement( 'label', _extends({ style: this.getLabelStyle(), ref: 'label' }, label, { onDoubleClick: this.handleLabelClick.bind(this, EditLabel.INIT_DBCLICK), onClick: this.handleLabelClick.bind(this, EditLabel.INIT_CLICK) }), this.state.value ); return element; } }]); return EditLabel; }(_react.Component); EditLabel.INIT_CLICK = 1; EditLabel.INIT_DBCLICK = 2; ; EditLabel.propTypes = { input: _react2.default.PropTypes.object, label: _react2.default.PropTypes.object, initBy: _react2.default.PropTypes.number.isRequired, id: _react2.default.PropTypes.number.isRequired, defValue: _react2.default.PropTypes.string, onEditEnd: _react2.default.PropTypes.func, //calls on end of edit onChange: _react2.default.PropTypes.func, //calls on every change onEnterClick: _react2.default.PropTypes.func, //calls after enter click onEditStart: _react2.default.PropTypes.func, //calls when edition starts material: _react2.default.PropTypes.bool, //if true it uses TextField from material if false <input> clearEnable: _react2.default.PropTypes.bool //is possible to remove all text - clear it }; EditLabel.defaultProps = { input: { className: "editlabel-input" }, label: { className: "editlabel-label" }, initBy: EditLabel.INIT_CLICK, //default is single click defValue: "", clearEnable: false, onChange: null, onEditEnd: null, // onEnterClick: null, onEditStart: null, material: true }; exports.default = EditLabel;