diff --git a/Examples/UIExplorer/TextInputExample.ios.js b/Examples/UIExplorer/TextInputExample.ios.js
index 826139048..9efde2ea0 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 e7049d2e0..9f8f44ed7 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 8a2bbb5a6..b8d172cc2 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 9305442ab..5279eafb6 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 e7cf180d4..9a33f7e46 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 94ba4609c..f32369c4a 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)