From 37042573b82e1c56ffabf80a505de80dee12c553 Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Wed, 2 Dec 2015 07:11:20 -0800 Subject: [PATCH] Added blurOnSubmit support to multine TextInput (aka RCTTextView) Summary: public Setting `blurOnSubmit=true` on a multiline `` now causes it to behave like a single-line input with respect to the return key: With the default value of `false`, pressing return will enter a newline character into the field. If you set the value to `true`, pressing return will now blur the field and trigger the onSubmitEditing event. The newline character will *not* be added to the text. (See associated github task for dicussion: https://github.com/facebook/react-native/pull/2149) Reviewed By: javache Differential Revision: D2710448 fb-gh-sync-id: c9706ae11f8b399932d3400ceb4c7558e455570d --- Examples/UIExplorer/TextInputExample.ios.js | 17 +++++++++++++ Libraries/Components/TextInput/TextInput.js | 28 ++++----------------- Libraries/Text/RCTTextField.m | 1 + Libraries/Text/RCTTextView.h | 1 + Libraries/Text/RCTTextView.m | 25 ++++++++++++++++++ Libraries/Text/RCTTextViewManager.m | 1 + 6 files changed, 50 insertions(+), 23 deletions(-) diff --git a/Examples/UIExplorer/TextInputExample.ios.js b/Examples/UIExplorer/TextInputExample.ios.js index 826139048c..9efde2ea0a 100644 --- a/Examples/UIExplorer/TextInputExample.ios.js +++ b/Examples/UIExplorer/TextInputExample.ios.js @@ -548,6 +548,23 @@ exports.examples = [ title: 'Blur on submit', render: function(): ReactElement { return ; }, }, + { + title: 'Multiline blur on submit', + render: function() { + return ( + + alert(event.nativeEvent.text)} + /> + + ); + } + }, { title: 'Multiline', render: function() { diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index e7049d2e07..9f8f44ed75 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -37,7 +37,7 @@ var onlyMultiline = { }; var notMultiline = { - onSubmitEditing: true, + // nothing yet }; if (Platform.OS === 'android') { @@ -47,10 +47,6 @@ if (Platform.OS === 'android') { var RCTTextField = requireNativeComponent('RCTTextField', null); } -type DefaultProps = { - blurOnSubmit: boolean; -}; - type Event = Object; /** @@ -73,17 +69,6 @@ type Event = Object; * ``` * * Note that some props are only available with `multiline={true/false}`: - * ``` - * var onlyMultiline = { - * onSelectionChange: true, // not supported in Open Source yet - * onTextInput: true, // not supported in Open Source yet - * children: true, - * }; - * - * var notMultiline = { - * onSubmitEditing: true, - * }; - * ``` */ var TextInput = React.createClass({ statics: { @@ -304,7 +289,10 @@ var TextInput = React.createClass({ selectTextOnFocus: PropTypes.bool, /** * If true, the text field will blur when submitted. - * The default value is true. + * The default value is true for single-line fields and false for + * multiline fields. Note that 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. * @platform ios */ blurOnSubmit: PropTypes.bool, @@ -323,12 +311,6 @@ var TextInput = React.createClass({ underlineColorAndroid: PropTypes.string, }, - getDefaultProps: function(): DefaultProps { - return { - blurOnSubmit: true, - }; - }, - /** * `NativeMethodsMixin` will look for this when invoking `setNativeProps`. We * make `this` look like an actual native component class. diff --git a/Libraries/Text/RCTTextField.m b/Libraries/Text/RCTTextField.m index 8a2bbb5a67..b8d172cc28 100644 --- a/Libraries/Text/RCTTextField.m +++ b/Libraries/Text/RCTTextField.m @@ -36,6 +36,7 @@ [self addTarget:self action:@selector(textFieldSubmitEditing) forControlEvents:UIControlEventEditingDidEndOnExit]; [self addObserver:self forKeyPath:@"selectedTextRange" options:0 context:nil]; _reactSubviews = [NSMutableArray new]; + _blurOnSubmit = YES; } return self; } diff --git a/Libraries/Text/RCTTextView.h b/Libraries/Text/RCTTextView.h index 9305442abe..5279eafb67 100644 --- a/Libraries/Text/RCTTextView.h +++ b/Libraries/Text/RCTTextView.h @@ -17,6 +17,7 @@ @interface RCTTextView : RCTView @property (nonatomic, assign) BOOL autoCorrect; +@property (nonatomic, assign) BOOL blurOnSubmit; @property (nonatomic, assign) BOOL clearTextOnFocus; @property (nonatomic, assign) BOOL selectTextOnFocus; @property (nonatomic, assign) UIEdgeInsets contentInset; diff --git a/Libraries/Text/RCTTextView.m b/Libraries/Text/RCTTextView.m index e7cf180d49..9a33f7e469 100644 --- a/Libraries/Text/RCTTextView.m +++ b/Libraries/Text/RCTTextView.m @@ -72,6 +72,7 @@ _contentInset = UIEdgeInsetsZero; _eventDispatcher = eventDispatcher; _placeholderTextColor = [self defaultPlaceholderTextColor]; + _blurOnSubmit = NO; _textView = [[RCTUITextView alloc] initWithFrame:CGRectZero]; _textView.backgroundColor = [UIColor clearColor]; @@ -276,11 +277,35 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) if (textView.textWasPasted) { textView.textWasPasted = NO; } else { + [_eventDispatcher sendTextEventWithType:RCTTextEventTypeKeyPress reactTag:self.reactTag text:nil key:text eventCount:_nativeEventCount]; + + if (_blurOnSubmit && [text isEqualToString:@"\n"]) { + + // TODO: the purpose of blurOnSubmit on RCTextField is to decide if the + // field should lose focus when return is pressed or not. We're cheating a + // bit here by using it on RCTextView to decide if return character should + // submit the form, or be entered into the field. + // + // The reason this is cheating is because there's no way to specify that + // you want the return key to be swallowed *and* have the field retain + // focus (which was what blurOnSubmit was originally for). For the case + // where _blurOnSubmit = YES, this is still the correct and expected + // behavior though, so we'll leave the don't-blur-or-add-newline problem + // to be solved another day. + + [_eventDispatcher sendTextEventWithType:RCTTextEventTypeSubmit + reactTag:self.reactTag + text:self.text + key:nil + eventCount:_nativeEventCount]; + [self resignFirstResponder]; + return NO; + } } if (_maxLength == nil) { diff --git a/Libraries/Text/RCTTextViewManager.m b/Libraries/Text/RCTTextViewManager.m index 94ba4609c9..f32369c4a3 100644 --- a/Libraries/Text/RCTTextViewManager.m +++ b/Libraries/Text/RCTTextViewManager.m @@ -25,6 +25,7 @@ RCT_EXPORT_MODULE() RCT_REMAP_VIEW_PROPERTY(autoCapitalize, textView.autocapitalizationType, UITextAutocapitalizationType) RCT_EXPORT_VIEW_PROPERTY(autoCorrect, BOOL) +RCT_EXPORT_VIEW_PROPERTY(blurOnSubmit, BOOL) RCT_EXPORT_VIEW_PROPERTY(clearTextOnFocus, BOOL) RCT_REMAP_VIEW_PROPERTY(color, textView.textColor, UIColor) RCT_REMAP_VIEW_PROPERTY(editable, textView.editable, BOOL)