[add] TextInput support for blurOnSubmit and onSubmitEditing

This commit is contained in:
Nicolas Gallagher
2016-10-28 21:15:35 -07:00
parent 44e60d12e3
commit 5a03cb25cb
2 changed files with 51 additions and 31 deletions
+13 -1
View File
@@ -43,6 +43,14 @@ Automatically correct spelling mistakes (only available in iOS Safari).
If `true`, focuses the input on `componentDidMount`. Only the first form element If `true`, focuses the input on `componentDidMount`. Only the first form element
in a document with `autofocus` is focused. in a document with `autofocus` is focused.
**blurOnSubmit**: bool
If `true`, the text field will blur when submitted. The default value is `true`
for single-line fields and `false` for multiline fields. Note, for multiline
fields setting `blurOnSubmit` to `true` means that pressing return will blur
the field and trigger the `onSubmitEditing` event instead of inserting a
newline into the field.
**clearTextOnFocus**: bool = false **clearTextOnFocus**: bool = false
If `true`, clears the text field automatically when focused. If `true`, clears the text field automatically when focused.
@@ -106,11 +114,15 @@ Callback that is called when the text input is focused.
Callback that is called when a key is pressed. Pressed key value is passed as Callback that is called when a key is pressed. Pressed key value is passed as
an argument to the callback handler. Fires before `onChange` callbacks. an argument to the callback handler. Fires before `onChange` callbacks.
(web) **onSelectionChange**: function **onSelectionChange**: function
Callback that is called when the text input's selection changes. The following Callback that is called when the text input's selection changes. The following
object is passed as an argument to the callback handler. object is passed as an argument to the callback handler.
**onSubmitEditing**: function
Callback that is called when the keyboard's submit button is pressed.
```js ```js
{ {
selectionDirection, selectionDirection,
+38 -30
View File
@@ -14,6 +14,13 @@ import React, { Component, PropTypes } from 'react';
const viewStyleProps = Object.keys(ViewStylePropTypes); const viewStyleProps = Object.keys(ViewStylePropTypes);
const normalizeEventHandler = (handler) => (e) => {
if (handler) {
e.nativeEvent.text = e.target.value;
return handler(e);
}
};
class TextInput extends Component { class TextInput extends Component {
static displayName = 'TextInput'; static displayName = 'TextInput';
@@ -23,6 +30,7 @@ class TextInput extends Component {
autoComplete: PropTypes.string, autoComplete: PropTypes.string,
autoCorrect: PropTypes.bool, autoCorrect: PropTypes.bool,
autoFocus: PropTypes.bool, autoFocus: PropTypes.bool,
blurOnSubmit: PropTypes.bool,
clearTextOnFocus: PropTypes.bool, clearTextOnFocus: PropTypes.bool,
defaultValue: PropTypes.string, defaultValue: PropTypes.string,
editable: PropTypes.bool, editable: PropTypes.bool,
@@ -144,37 +152,32 @@ class TextInput extends Component {
const rootStyles = pick(flattenedStyle, viewStyleProps); const rootStyles = pick(flattenedStyle, viewStyleProps);
const textStyles = omit(flattenedStyle, viewStyleProps); const textStyles = omit(flattenedStyle, viewStyleProps);
const propsCommon = { const props = {
autoCapitalize, autoCapitalize,
autoComplete, autoComplete,
autoCorrect: autoCorrect ? 'on' : 'off', autoCorrect: autoCorrect ? 'on' : 'off',
autoFocus, autoFocus,
defaultValue, defaultValue,
maxLength, maxLength,
onBlur: this._handleBlur, onBlur: normalizeEventHandler(this._handleBlur),
onChange: this._handleChange, onChange: normalizeEventHandler(this._handleChange),
onFocus: this._handleFocus, onFocus: normalizeEventHandler(this._handleFocus),
onKeyPress, onKeyPress: normalizeEventHandler(this._handleKeyPress),
onSelect: onSelectionChange && this._handleSelectionChange, onSelect: normalizeEventHandler(this._handleSelectionChange),
readOnly: !editable, readOnly: !editable,
ref: this._setInputRef, ref: this._setInputRef,
style: [ styles.input, textStyles, { outline: style.outline } ], style: [ styles.input, textStyles, { outline: style.outline } ],
value value
}; };
const propsMultiline = { if (multiline) {
...propsCommon, props.maxRows = maxNumberOfLines || numberOfLines;
maxRows: maxNumberOfLines || numberOfLines, props.minRows = numberOfLines;
minRows: numberOfLines } else {
}; props.type = type;
}
const propsSingleline = {
...propsCommon,
type
};
const component = multiline ? TextareaAutosize : 'input'; const component = multiline ? TextareaAutosize : 'input';
const props = multiline ? propsMultiline : propsSingleline;
const optionalPlaceholder = placeholder && this.state.showPlaceholder && ( const optionalPlaceholder = placeholder && this.state.showPlaceholder && (
<View pointerEvents='none' style={styles.placeholder}> <View pointerEvents='none' style={styles.placeholder}>
@@ -207,40 +210,46 @@ class TextInput extends Component {
_handleBlur = (e) => { _handleBlur = (e) => {
const { onBlur } = this.props; const { onBlur } = this.props;
const text = e.target.value; const { text } = e.nativeEvent;
this.setState({ showPlaceholder: text === '' }); this.setState({ showPlaceholder: text === '' });
this.blur();
if (onBlur) { onBlur(e); } if (onBlur) { onBlur(e); }
} }
_handleChange = (e) => { _handleChange = (e) => {
const { onChange, onChangeText } = this.props; const { onChange, onChangeText } = this.props;
const text = e.target.value; const { text } = e.nativeEvent;
e.nativeEvent.text = text;
this.setState({ showPlaceholder: text === '' }); this.setState({ showPlaceholder: text === '' });
if (onChange) { onChange(e); } if (onChange) { onChange(e); }
if (onChangeText) { onChangeText(text); } if (onChangeText) { onChangeText(text); }
if (!this._inputRef) {
// calling `this.props.onChange` or `this.props.onChangeText`
// may clean up the input itself. Exits here.
return;
}
} }
_handleClick = (e) => { _handleClick = (e) => {
this.focus(); if (this.props.editable) {
this.focus();
}
} }
_handleFocus = (e) => { _handleFocus = (e) => {
const { clearTextOnFocus, onFocus, selectTextOnFocus } = this.props; const { clearTextOnFocus, onFocus, selectTextOnFocus } = this.props;
const { text } = e.nativeEvent;
const node = ReactDOM.findDOMNode(this._inputRef); const node = ReactDOM.findDOMNode(this._inputRef);
const text = e.target.value;
if (onFocus) { onFocus(e); } if (onFocus) { onFocus(e); }
if (clearTextOnFocus) { this.clear(); } if (clearTextOnFocus) { this.clear(); }
if (selectTextOnFocus) { node.select(); } if (selectTextOnFocus) { node && node.select(); }
this.setState({ showPlaceholder: text === '' }); this.setState({ showPlaceholder: text === '' });
} }
_handleKeyPress = (e) => {
const { blurOnSubmit, multiline, onKeyPress, onSubmitEditing } = this.props;
const blurOnSubmitDefault = !multiline;
const shouldBlurOnSubmit = blurOnSubmit == null ? blurOnSubmitDefault : blurOnSubmit
if (onKeyPress) { onKeyPress(e); }
if (!e.isDefaultPrevented() && e.which === 13) {
if (onSubmitEditing) { onSubmitEditing(e); }
if (shouldBlurOnSubmit) { this.blur(); }
}
}
_handleSelectionChange = (e) => { _handleSelectionChange = (e) => {
const { onSelectionChange } = this.props; const { onSelectionChange } = this.props;
try { try {
@@ -282,7 +291,6 @@ const styles = StyleSheet.create({
}, },
placeholder: { placeholder: {
bottom: 0, bottom: 0,
justifyContent: 'center',
left: 0, left: 0,
position: 'absolute', position: 'absolute',
right: 0, right: 0,