Skip to content

Commit 92b5b02

Browse files
MCurran16vtrifonovdtopuzov
authored
feat(text-field): add closeOnReturn property to avoid auto dismissing… (#8347)
* feat(text-field): add closeOnReturn property to avoid auto dismissing input on return press * tslint * Update NS public api Co-authored-by: Vasil Trifonov <v.trifonov@gmail.com> Co-authored-by: Dimitar Topuzov <dtopuzov@gmail.com>
1 parent 8dbb623 commit 92b5b02

8 files changed

Lines changed: 134 additions & 3 deletions

File tree

api-reports/NativeScript.api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,6 +2496,8 @@ export class TextBase extends View implements AddChildFromBuilder {
24962496
export class TextField extends EditableTextBase {
24972497
android: any /* android.widget.EditText */;
24982498

2499+
closeOnReturn: boolean;
2500+
24992501
ios: any /* UITextField */;
25002502

25012503
// (undocumented)

nativescript-core/ui/text-field/text-field-common.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ export * from "../editable-text-base";
77
export class TextFieldBase extends EditableTextBase implements TextFieldDefinition {
88
public static returnPressEvent = "returnPress";
99
public secure: boolean;
10+
public closeOnReturn: boolean;
1011
}
1112

1213
TextFieldBase.prototype.recycleNativeView = "auto";
1314

1415
export const secureProperty = new Property<TextFieldBase, boolean>({ name: "secure", defaultValue: false, valueConverter: booleanConverter });
1516
secureProperty.register(TextFieldBase);
17+
18+
export const closeOnReturnProperty = new Property<TextFieldBase, boolean>({ name: "closeOnReturn", defaultValue: true, valueConverter: booleanConverter });
19+
closeOnReturnProperty.register(TextFieldBase);

nativescript-core/ui/text-field/text-field.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,9 @@ export class TextField extends EditableTextBase {
2727
* Gets or sets if a text field is for password entry.
2828
*/
2929
secure: boolean;
30+
31+
/**
32+
* Gets or sets if a text field should dismiss on return.
33+
*/
34+
closeOnReturn: boolean;
3035
}

nativescript-core/ui/text-field/text-field.ios.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ class UITextFieldDelegateImpl extends NSObject implements UITextFieldDelegate {
6666
// Called when the user presses the return button.
6767
const owner = this._owner.get();
6868
if (owner) {
69-
owner.dismissSoftInput();
69+
if (owner.closeOnReturn) {
70+
owner.dismissSoftInput();
71+
}
7072
owner.notify({ eventName: TextField.returnPressEvent, object: owner });
7173
}
7274

tests/app/ui/text-field/text-field-tests-native.android.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,17 @@ export function getNativeTextAlignment(textField: textFieldModule.TextField): st
5959
return "unexpected value";
6060
}
6161

62+
export function getNativeFocus(textField: textFieldModule.TextField): boolean {
63+
//
64+
return true;
65+
}
66+
6267
export function typeTextNatively(textField: textFieldModule.TextField, text: string): void {
6368
textField.android.requestFocus();
6469
textField.android.setText(text);
6570
textField.android.clearFocus();
6671
}
72+
73+
export function typeTextNativelyWithReturn(textField: textFieldModule.TextField, text: string): void {
74+
//
75+
}

tests/app/ui/text-field/text-field-tests-native.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ export declare function getNativeColor(textField: textFieldModule.TextField): co
1010
export declare function getNativePlaceholderColor(textField: textFieldModule.TextField): colorModule.Color;
1111
export declare function getNativeBackgroundColor(textField: textFieldModule.TextField): colorModule.Color;
1212
export declare function getNativeTextAlignment(textField: textFieldModule.TextField): string;
13+
export declare function getNativeFocus(textField: textFieldModule.TextField): boolean;
1314
export declare function typeTextNatively(textField: textFieldModule.TextField, text: string): void;
15+
export declare function typeTextNativelyWithReturn(textField: textFieldModule.TextField, text: string): void;
16+

tests/app/ui/text-field/text-field-tests-native.ios.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,21 @@ export function getNativeTextAlignment(textField: textFieldModule.TextField): st
4444
}
4545
}
4646

47+
export function getNativeFocus(textField: textFieldModule.TextField): boolean {
48+
return textField.nativeView.isFirstResponder;
49+
}
50+
4751
export function typeTextNatively(textField: textFieldModule.TextField, text: string): void {
4852
textField.ios.text = text;
4953

5054
// Setting the text will not trigger the delegate method, so we have to do it by hand.
5155
textField.ios.delegate.textFieldDidEndEditing(textField.ios);
5256
}
57+
58+
export function typeTextNativelyWithReturn(textField: textFieldModule.TextField, text: string): void {
59+
textField.nativeView.becomeFirstResponder();
60+
61+
textField.ios.text = text;
62+
63+
textField.ios.delegate.textFieldShouldReturn(textField.ios);
64+
}

tests/app/ui/text-field/text-field-tests.ts

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import { Page } from "@nativescript/core/ui/page";
55
import { StackLayout } from "@nativescript/core/ui/layouts/stack-layout";
66
import { Color } from "@nativescript/core/color";
77
import {
8-
getNativeText, getNativeHint, typeTextNatively, getNativeSecure,
8+
getNativeText, getNativeHint, typeTextNatively, typeTextNativelyWithReturn, getNativeSecure,
99
getNativeFontSize, getNativeColor, getNativeBackgroundColor,
10-
getNativeTextAlignment, getNativePlaceholderColor
10+
getNativeTextAlignment, getNativePlaceholderColor, getNativeFocus
1111
} from "./text-field-tests-native";
1212
import { FormattedString } from "@nativescript/core/text/formatted-string";
1313
import { Span } from "@nativescript/core/text/span";
@@ -400,6 +400,100 @@ export var testBindSecureToBindingConext = function () {
400400
});
401401
};
402402

403+
// iOS only
404+
export var testBindCloseOnReturnToBindingConext = function () {
405+
helper.buildUIAndRunTest(_createTextFieldFunc(), function (views: Array<View>) {
406+
if (!isIOS) {
407+
TKUnit.assert(true === true);
408+
409+
return;
410+
}
411+
var textField = <TextField>views[0];
412+
var page = <Page>views[1];
413+
414+
var model = new Observable();
415+
model.set("closeOnReturn", false);
416+
page.bindingContext = model;
417+
418+
var options: BindingOptions = {
419+
sourceProperty: "closeOnReturn",
420+
targetProperty: "closeOnReturn"
421+
};
422+
423+
textField.bind(options);
424+
TKUnit.assert(textField.closeOnReturn === false, "Actual: " + textField.closeOnReturn + "; Expected: " + false);
425+
typeTextNativelyWithReturn(textField, "Should not close textfield");
426+
TKUnit.assert(getNativeFocus(textField) === true, "Actual: " + getNativeFocus(textField) + "; Expected: " + true);
427+
428+
model.set("closeOnReturn", true);
429+
TKUnit.assert(textField.closeOnReturn === true, "Actual: " + textField.closeOnReturn + "; Expected: " + true);
430+
typeTextNativelyWithReturn(textField, "Should close textfield");
431+
TKUnit.assert(getNativeFocus(textField) === false, "Actual: " + getNativeFocus(textField) + "; Expected: " + false);
432+
});
433+
};
434+
435+
// iOS only
436+
export var testDontCloseOnReturn = function () {
437+
helper.buildUIAndRunTest(_createTextFieldFunc(), function (views: Array<View>) {
438+
if (!isIOS) {
439+
TKUnit.assert(true === true);
440+
441+
return;
442+
}
443+
var textField = <TextField>views[0];
444+
445+
// >> setting-closeOnReturn-property
446+
textField.closeOnReturn = false;
447+
// << setting-closeOnReturn-property
448+
449+
typeTextNativelyWithReturn(textField, "Should not close textfield");
450+
451+
var expectedValue = true;
452+
var actualValue = getNativeFocus(textField);
453+
TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue);
454+
});
455+
};
456+
457+
// iOS only
458+
export var testCloseOnReturn = function () {
459+
helper.buildUIAndRunTest(_createTextFieldFunc(), function (views: Array<View>) {
460+
if (!isIOS) {
461+
TKUnit.assert(true === true);
462+
463+
return;
464+
}
465+
var textField = <TextField>views[0];
466+
467+
// >> setting-closeOnReturn-property
468+
textField.closeOnReturn = true;
469+
// << setting-closeOnReturn-property
470+
471+
typeTextNativelyWithReturn(textField, "Should close textfield");
472+
473+
var expectedValue = false;
474+
var actualValue = getNativeFocus(textField);
475+
TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue);
476+
});
477+
};
478+
479+
// iOS only
480+
export var testCloseOnReturnByDefault = function () {
481+
helper.buildUIAndRunTest(_createTextFieldFunc(), function (views: Array<View>) {
482+
if (!isIOS) {
483+
TKUnit.assert(true === true);
484+
485+
return;
486+
}
487+
var textField = <TextField>views[0];
488+
489+
typeTextNativelyWithReturn(textField, "Should close textfield by default");
490+
491+
var expectedValue = false;
492+
var actualValue = getNativeFocus(textField);
493+
TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue);
494+
});
495+
};
496+
403497
var expectedFontSize = 42;
404498
export var testLocalFontSizeFromCss = function () {
405499
helper.buildUIAndRunTest(_createTextFieldFunc(), function (views: Array<View>) {

0 commit comments

Comments
 (0)