Resolved #184: Hint property for TextView.

This commit is contained in:
Rossen Hristov
2015-05-20 13:15:42 +03:00
parent 44782dd724
commit 1b212bfce5
14 changed files with 194 additions and 45 deletions

View File

@ -16,6 +16,10 @@ export function getNativeEditable(textView: textViewModule.TextView): boolean {
} }
} }
export function getNativeHint(textView: textViewModule.TextView): string {
return textView.android.getHint();
}
export function getNativeFontSize(textView: textViewModule.TextView): number { export function getNativeFontSize(textView: textViewModule.TextView): number {
var density = utilsModule.layout.getDisplayDensity(); var density = utilsModule.layout.getDisplayDensity();
return textView.android.getTextSize() / density; return textView.android.getTextSize() / density;

View File

@ -3,6 +3,7 @@ import textViewModule = require("ui/text-view");
import colorModule = require("color"); import colorModule = require("color");
export declare function getNativeText(textView: textViewModule.TextView): string; export declare function getNativeText(textView: textViewModule.TextView): string;
export declare function getNativeHint(textView: textViewModule.TextView): string;
export declare function getNativeEditable(textView: textViewModule.TextView): boolean; export declare function getNativeEditable(textView: textViewModule.TextView): boolean;
export declare function getNativeFontSize(textView: textViewModule.TextView): number; export declare function getNativeFontSize(textView: textViewModule.TextView): number;
export declare function getNativeColor(textView: textViewModule.TextView): colorModule.Color; export declare function getNativeColor(textView: textViewModule.TextView): colorModule.Color;

View File

@ -7,6 +7,15 @@ export function getNativeText(textView: textViewModule.TextView): string {
return textView.ios.text; return textView.ios.text;
} }
export function getNativeHint(textView: textViewModule.TextView): string {
// There is no native hint
if (textView.hint !== "") {
return textView.ios.text;
}
return "";
}
export function getNativeEditable(textView: textViewModule.TextView): boolean { export function getNativeEditable(textView: textViewModule.TextView): boolean {
return textView.ios.editable; return textView.ios.editable;
} }

View File

@ -135,6 +135,77 @@ export var testTextIsUpdatedWhenUserTypes = function () {
}); });
} }
export var testSetHint = function () {
helper.buildUIAndRunTest(_createTextViewFunc(), function (views: Array<viewModule.View>) {
var textView = <textViewModule.TextView>views[0];
// <snippet module="ui/text-view" title="TextView">
// ### Setting the hint of a TextView
// ``` JavaScript
textView.hint = "type your username here";
// ```
// </snippet>
var expectedValue = "type your username here";
var actualValue = textViewTestsNative.getNativeHint(textView);
TKUnit.assert(actualValue === expectedValue, "Actual: " + actualValue + "; Expected: " + expectedValue);
});
}
export var testBindHintDirectlyToModel = function () {
helper.buildUIAndRunTest(_createTextViewFunc(), function (views: Array<viewModule.View>) {
var textView = <textViewModule.TextView>views[0];
// <snippet module="ui/text-view" title="TextView">
// ### Binding hint property directly to model
// ``` JavaScript
var model = new observable.Observable();
model.set("hint", "type your username here");
var options: bindable.BindingOptions = {
sourceProperty: "hint",
targetProperty: "hint"
}
textView.bind(options, model);
//// TextView.hint is now "type your username here"
// <hide>
TKUnit.assert(textView.hint === "type your username here", "Actual: " + textView.text + "; Expected: " + "type your username here");
TKUnit.assert(textViewTestsNative.getNativeHint(textView) === "type your username here", "Actual: " + textViewTestsNative.getNativeHint(textView) + "; Expected: " + "type your username here");
// </hide>
model.set("hint", "type your password here");
//// TextView.hint is now "type your password here"
// <hide>
TKUnit.assert(textView.hint === "type your password here", "Actual: " + textView.text + "; Expected: " + "type your password here");
TKUnit.assert(textViewTestsNative.getNativeHint(textView) === "type your password here", "Actual: " + textViewTestsNative.getNativeHint(textView) + "; Expected: " + "type your password here");
// </hide>
// ```
// </snippet>
});
}
export var testBindHintToBindingConext = function () {
helper.buildUIAndRunTest(_createTextViewFunc(), function (views: Array<viewModule.View>) {
var textView = <textViewModule.TextView>views[0];
var page = <pagesModule.Page>views[1];
var model = new observable.Observable();
model.set("hint", "type your username here");
page.bindingContext = model;
var options: bindable.BindingOptions = {
sourceProperty: "hint",
targetProperty: "hint"
}
textView.bind(options);
TKUnit.assert(textView.hint === "type your username here", "Actual: " + textView.hint + "; Expected: " + "type your username here");
TKUnit.assert(textViewTestsNative.getNativeHint(textView) === "type your username here", "Actual: " + textViewTestsNative.getNativeHint(textView) + "; Expected: " + "type your username here");
model.set("hint", "type your password here");
TKUnit.assert(textView.hint === "type your password here", "Actual: " + textView.text + "; Expected: " + "type your password here");
TKUnit.assert(textViewTestsNative.getNativeHint(textView) === "type your password here", "Actual: " + textViewTestsNative.getNativeHint(textView) + "; Expected: " + "type your password here");
});
}
export var testSetEditable = function () { export var testSetEditable = function () {
helper.buildUIAndRunTest(_createTextViewFunc(), function (views: Array<viewModule.View>) { helper.buildUIAndRunTest(_createTextViewFunc(), function (views: Array<viewModule.View>) {
var textView = <textViewModule.TextView>views[0]; var textView = <textViewModule.TextView>views[0];

View File

@ -40,6 +40,13 @@ var autocorrectProperty = new dependencyObservable.Property(
new proxy.PropertyMetadata(undefined, dependencyObservable.PropertyMetadataSettings.None) new proxy.PropertyMetadata(undefined, dependencyObservable.PropertyMetadataSettings.None)
); );
export var hintProperty = new dependencyObservable.Property(
"hint",
"EditableTextBase",
new proxy.PropertyMetadata("")
);
function onKeyboardTypePropertyChanged(data: dependencyObservable.PropertyChangeData) { function onKeyboardTypePropertyChanged(data: dependencyObservable.PropertyChangeData) {
var editableTextBase = <EditableTextBase>data.object; var editableTextBase = <EditableTextBase>data.object;
editableTextBase._onKeyboardTypePropertyChanged(data); editableTextBase._onKeyboardTypePropertyChanged(data);
@ -75,6 +82,13 @@ function onAutocorrectPropertyChanged(data: dependencyObservable.PropertyChangeD
(<proxy.PropertyMetadata>autocorrectProperty.metadata).onSetNativeValue = onAutocorrectPropertyChanged; (<proxy.PropertyMetadata>autocorrectProperty.metadata).onSetNativeValue = onAutocorrectPropertyChanged;
function onHintPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var editableTextBase = <EditableTextBase>data.object;
editableTextBase._onHintPropertyChanged(data);
}
(<proxy.PropertyMetadata>hintProperty.metadata).onSetNativeValue = onHintPropertyChanged;
export class EditableTextBase extends textBase.TextBase implements definition.EditableTextBase { export class EditableTextBase extends textBase.TextBase implements definition.EditableTextBase {
public static keyboardTypeProperty = keyboardTypeProperty; public static keyboardTypeProperty = keyboardTypeProperty;
@ -89,6 +103,8 @@ export class EditableTextBase extends textBase.TextBase implements definition.Ed
public static autocorrectProperty = autocorrectProperty; public static autocorrectProperty = autocorrectProperty;
public static hintProperty = hintProperty;
constructor(options?: definition.Options) { constructor(options?: definition.Options) {
super(options); super(options);
} }
@ -141,6 +157,13 @@ export class EditableTextBase extends textBase.TextBase implements definition.Ed
this._setValue(EditableTextBase.autocorrectProperty, value); this._setValue(EditableTextBase.autocorrectProperty, value);
} }
get hint(): string {
return this._getValue(EditableTextBase.hintProperty);
}
set hint(value: string) {
this._setValue(EditableTextBase.hintProperty, value);
}
public dismissSoftInput() { public dismissSoftInput() {
// //
} }
@ -165,4 +188,8 @@ export class EditableTextBase extends textBase.TextBase implements definition.Ed
public _onAutocorrectPropertyChanged(data: dependencyObservable.PropertyChangeData) { public _onAutocorrectPropertyChanged(data: dependencyObservable.PropertyChangeData) {
// //
} }
public _onHintPropertyChanged(data: dependencyObservable.PropertyChangeData) {
//
}
} }

View File

@ -253,4 +253,13 @@ export class EditableTextBase extends common.EditableTextBase {
editableTextBase.android.setInputType(inputType); editableTextBase.android.setInputType(inputType);
} }
public _onHintPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var editableTextBase = <EditableTextBase>data.object;
if (!editableTextBase.android) {
return;
}
editableTextBase.android.setHint(data.newValue);
}
} }

View File

@ -46,6 +46,11 @@
*/ */
autocorrect: boolean; autocorrect: boolean;
/**
* Gets or sets the placeholder text.
*/
hint: string;
/** /**
* Hides the soft input method, ususally a soft keyboard. * Hides the soft input method, ususally a soft keyboard.
*/ */
@ -81,6 +86,11 @@
*/ */
autocapitalizationType?: string; autocapitalizationType?: string;
/**
* Gets or sets the placeholder text.
*/
hint?: string;
/** /**
* Enables or disables autocorrection. * Enables or disables autocorrection.
*/ */

View File

@ -409,21 +409,36 @@ export class TextViewStyler implements definition.stylers.Styler {
private static setColorProperty(view: view.View, newValue: any) { private static setColorProperty(view: view.View, newValue: any) {
var textView: UITextView = <UITextView>view._nativeView; var textView: UITextView = <UITextView>view._nativeView;
if (textView) { if (textView) {
textView.textColor = newValue; TextViewStyler._setTextViewColor(textView, newValue);
} }
} }
private static resetColorProperty(view: view.View, nativeValue: any) { private static resetColorProperty(view: view.View, nativeValue: any) {
var textView: UITextView = <UITextView>view._nativeView; var textView: UITextView = <UITextView>view._nativeView;
if (textView) { if (textView) {
textView.textColor = nativeValue; TextViewStyler._setTextViewColor(textView, nativeValue);
}
}
private static _setTextViewColor(textView: UITextView, newValue: any) {
var color: UIColor = <UIColor>newValue;
if ((<any>textView).isShowingHint && color) {
textView.textColor = (<UIColor>color).colorWithAlphaComponent(0.22);
}
else {
textView.textColor = color;
} }
} }
private static getNativeColorValue(view: view.View): any { private static getNativeColorValue(view: view.View): any {
var textView: UITextView = <UITextView>view._nativeView; var textView: UITextView = <UITextView>view._nativeView;
if (textView) { if (textView) {
return textView.textColor; if ((<any>textView).isShowingHint && textView.textColor) {
return textView.textColor.colorWithAlphaComponent(1);
}
else {
return textView.textColor;
}
} }
} }

View File

@ -39,6 +39,8 @@
* Gets or sets a formatted string. * Gets or sets a formatted string.
*/ */
formattedText: formattedString.FormattedString; formattedText: formattedString.FormattedString;
_onTextPropertyChanged(data: dependencyObservable.PropertyChangeData);
} }
/** /**

View File

@ -4,12 +4,6 @@ import proxy = require("ui/core/proxy");
import textBase = require("ui/text-base"); import textBase = require("ui/text-base");
import editableTextBase = require("ui/editable-text-base"); import editableTextBase = require("ui/editable-text-base");
export var hintProperty = new dependencyObservable.Property(
"hint",
"TextField",
new proxy.PropertyMetadata("")
);
export var secureProperty = new dependencyObservable.Property( export var secureProperty = new dependencyObservable.Property(
"secure", "secure",
"TextField", "TextField",
@ -25,13 +19,6 @@ export class TextField extends editableTextBase.EditableTextBase implements defi
super(options); super(options);
} }
get hint(): string {
return this._getValue(hintProperty);
}
set hint(value: string) {
this._setValue(hintProperty, value);
}
get secure(): boolean { get secure(): boolean {
return this._getValue(secureProperty); return this._getValue(secureProperty);
} }

View File

@ -2,18 +2,6 @@
import dependencyObservable = require("ui/core/dependency-observable"); import dependencyObservable = require("ui/core/dependency-observable");
import proxy = require("ui/core/proxy"); import proxy = require("ui/core/proxy");
function onHintPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var textField = <TextField>data.object;
if (!textField.android) {
return;
}
textField.android.setHint(data.newValue);
}
// register the setNativeValue callbacks
(<proxy.PropertyMetadata>common.hintProperty.metadata).onSetNativeValue = onHintPropertyChanged;
function onSecurePropertyChanged(data: dependencyObservable.PropertyChangeData) { function onSecurePropertyChanged(data: dependencyObservable.PropertyChangeData) {
var textField = <TextField>data.object; var textField = <TextField>data.object;
if (!textField.android) { if (!textField.android) {

View File

@ -20,11 +20,6 @@ declare module "ui/text-field" {
*/ */
ios: UITextField; ios: UITextField;
/**
* Gets or sets the text of a text field hint/placeholder.
*/
hint: string;
/** /**
* Gets or sets if a text field is for password entry. * Gets or sets if a text field is for password entry.
*/ */
@ -35,11 +30,6 @@ declare module "ui/text-field" {
* Defines interface for an optional parameter used to create a editable-text-base component. * Defines interface for an optional parameter used to create a editable-text-base component.
*/ */
export interface Options extends editableTextBase.Options { export interface Options extends editableTextBase.Options {
/**
* Gets or sets the text of a text field hint/placeholder.
*/
hint?: string;
/** /**
* Gets or sets if a text field is for password entry. * Gets or sets if a text field is for password entry.
*/ */

View File

@ -4,13 +4,6 @@ import proxy = require("ui/core/proxy");
import textBase = require("ui/text-base"); import textBase = require("ui/text-base");
import enums = require("ui/enums"); import enums = require("ui/enums");
function onHintPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var textField = <TextField>data.object;
textField.ios.placeholder = data.newValue;
}
(<proxy.PropertyMetadata>common.hintProperty.metadata).onSetNativeValue = onHintPropertyChanged;
function onSecurePropertyChanged(data: dependencyObservable.PropertyChangeData) { function onSecurePropertyChanged(data: dependencyObservable.PropertyChangeData) {
var textField = <TextField>data.object; var textField = <TextField>data.object;
textField.ios.secureTextEntry = data.newValue; textField.ios.secureTextEntry = data.newValue;
@ -89,4 +82,9 @@ export class TextField extends common.TextField {
get ios(): UITextField { get ios(): UITextField {
return this._ios; return this._ios;
} }
public _onHintPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var textField = <TextField>data.object;
textField.ios.placeholder = data.newValue;
}
} }

View File

@ -2,6 +2,7 @@
import dependencyObservable = require("ui/core/dependency-observable"); import dependencyObservable = require("ui/core/dependency-observable");
import textBase = require("ui/text-base"); import textBase = require("ui/text-base");
import enums = require("ui/enums"); import enums = require("ui/enums");
import color = require("color");
// merge the exports of the common file with the exports of this file // merge the exports of the common file with the exports of this file
declare var exports; declare var exports;
@ -21,12 +22,18 @@ class UITextViewDelegateImpl extends NSObject implements UITextViewDelegate {
return this; return this;
} }
public textViewShouldBeginEditing(textView: UITextView): boolean {
this._owner._hideHint();
return true;
}
public textViewDidEndEditing(textView: UITextView) { public textViewDidEndEditing(textView: UITextView) {
if (this._owner.updateTextTrigger === enums.UpdateTextTrigger.focusLost) { if (this._owner.updateTextTrigger === enums.UpdateTextTrigger.focusLost) {
this._owner._onPropertyChangedFromNative(textBase.TextBase.textProperty, textView.text); this._owner._onPropertyChangedFromNative(textBase.TextBase.textProperty, textView.text);
} }
this._owner.dismissSoftInput(); this._owner.dismissSoftInput();
this._owner._refreshHintState(this._owner.hint);
} }
public textViewDidChange(textView: UITextView) { public textViewDidChange(textView: UITextView) {
@ -69,4 +76,35 @@ export class TextView extends common.TextView {
public _onEditablePropertyChanged(data: dependencyObservable.PropertyChangeData) { public _onEditablePropertyChanged(data: dependencyObservable.PropertyChangeData) {
this._ios.editable = data.newValue; this._ios.editable = data.newValue;
} }
public _onHintPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var textView = <TextView>data.object;
this._refreshHintState(data.newValue);
}
public _onTextPropertyChanged(data: dependencyObservable.PropertyChangeData) {
super._onTextPropertyChanged(data);
this._refreshHintState(this.hint);
}
public _refreshHintState(hint: string) {
if (hint && !this.ios.text) {
this._showHint(hint);
}
else {
this._hideHint();
}
}
public _showHint(hint: string) {
this.ios.textColor = this.ios.textColor ? this.ios.textColor.colorWithAlphaComponent(0.22) : UIColor.blackColor().colorWithAlphaComponent(0.22);
this.ios.text = hint + "";
(<any>this.ios).isShowingHint = true;
}
public _hideHint() {
this.ios.textColor = this.color ? this.color.ios : null;
this.ios.text = this.text + "";
(<any>this.ios).isShowingHint = false;
}
} }