react-form-controlled
Version:
Intuitive react forms for building powerful applications
206 lines (167 loc) • 5.18 kB
JavaScript
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; };
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; }
import React from 'react';
import PropTypes from 'prop-types';
import Element from './Element';
function fixUncontrolledValue(value) {
return typeof value === 'undefined' || value === null ? '' : value;
}
export default class Input extends Element {
constructor(...args) {
var _temp;
return _temp = super(...args), _initialiseProps.call(this), _temp;
}
getValue() {
return fixUncontrolledValue(super.getValue());
}
onChange(evn) {
const { target } = evn;
let value = target.value;
if (target.type === 'checkbox') {
value = !!target.checked;
} else if (target.type === 'radio' && target.checked) {
value = this.props.value;
} else if (target.type === 'number') {
const fixedValue = value.replace(',', '.').replace(' ', '');
// fix decimal numbers
const numberValue = Number(fixedValue);
if (numberValue.toString() === fixedValue) {
value = numberValue;
}
}
const { type } = this.props;
if (type === 'checkbox' || type === 'radio') {
setTimeout(() => {
this.setValue(value);
const { onChange } = this.props;
if (typeof onChange === 'function') {
onChange(evn);
}
}, 0);
} else {
this.setValue(value);
const { onChange } = this.props;
if (typeof onChange === 'function') {
onChange(evn);
}
}
}
componentWillReceiveProps() {
this.clearTimeout();
}
clearTimeout(sendValue) {
if (this.timeoutId) {
clearTimeout(this.timeoutId);
this.timeoutId = null;
}
// TODO validate this
if (sendValue && this.props.value !== this.getValue()) {
this.notifyParent(this.getValue(), this, sendValue);
}
}
componentWillUnmount() {
super.componentWillUnmount();
this.clearTimeout();
}
notifyParent(value, component, force) {
const { type } = this.props;
const debounce = this.getDebounce();
if (!this.focused || !debounce || type === 'checkbox' || type === 'radio') {
super.notifyParent(value, component);
return;
}
this.clearTimeout();
if (force) {
super.notifyParent(value, component, force);
return;
}
this.timeoutId = setTimeout(() => {
this.timeoutId = null;
super.notifyParent(value, component);
}, debounce);
}
getClassName() {
return this.props.className;
}
getDebounce() {
const { debounce } = this.props;
if (typeof debounce !== 'undefined') {
return debounce;
}
return this.getForm().props.debounce;
}
getGroupName(group) {
if (!group) {
return undefined;
}
return this.getPathByName(group);
}
render() {
const _props = this.props,
{
name, // radio button must be without name
group, // group name of the radio button
type,
debounce,
value: originalValue
} = _props,
rest = _objectWithoutProperties(_props, ['name', 'group', 'type', 'debounce', 'value']);
let value = this.getValue();
const checked = type === 'checkbox' && value || type === 'radio' && value === originalValue;
if (type === 'radio' && originalValue) {
value = originalValue;
}
const isCheckbox = type === 'checkbox' || type === 'radio';
const isRadio = type === 'radio';
const newName = isRadio ? this.getGroupName(group) : undefined;
return React.createElement('input', _extends({}, rest, {
name: newName,
className: this.getClassName(),
type: type,
value: value,
checked: isCheckbox ? checked : undefined,
onChange: (...args) => this.onChange(...args),
onFocus: this.onFocus,
onBlur: this.onBlur,
onKeyPress: this.onKeyPress
}));
}
}
Input.propTypes = _extends({}, Element.propTypes, {
className: PropTypes.string,
style: PropTypes.object,
autoComplete: PropTypes.string.isRequired,
type: PropTypes.string.isRequired,
disabled: PropTypes.bool,
debounce: PropTypes.number,
group: PropTypes.string
});
Input.defaultProps = {
autoComplete: 'off',
type: 'text',
group: undefined
};
Input.contextTypes = _extends({}, Element.contextTypes);
var _initialiseProps = function () {
this.onKeyPress = evn => {
if (evn.key === 'Enter') {
this.clearTimeout(true);
}
};
this.onFocus = (...args) => {
const { onFocus } = this.props;
this.focused = true;
if (onFocus) {
onFocus(...args);
}
};
this.onBlur = (...args) => {
const { onBlur } = this.props;
this.focused = false;
this.clearTimeout(true);
if (onBlur) {
onBlur(...args);
}
};
};
//# sourceMappingURL=Input.js.map