refactor(searchbar): fixing event emitters, outputs and inputs, removing ngControl requirement from Searchbar

This commit is contained in:
Brandy Carney
2015-12-18 18:04:15 -05:00
parent 20585106ff
commit 53dd312b39
4 changed files with 39 additions and 62 deletions

View File

@ -1,5 +1,4 @@
import {ElementRef, Renderer, Component, Directive} from 'angular2/core'; import {ElementRef, Component, Directive, Host, HostBinding, HostListener, ViewChild, Input, Output, EventEmitter} from 'angular2/core';
import {Host, HostBinding, HostListener, ViewChild, Input, Output, EventEmitter, Optional} from 'angular2/core';
import {NgIf, NgClass, NgControl, FORM_DIRECTIVES} from 'angular2/common'; import {NgIf, NgClass, NgControl, FORM_DIRECTIVES} from 'angular2/common';
import {Ion} from '../ion'; import {Ion} from '../ion';
@ -25,14 +24,7 @@ export class SearchbarInput {
this.onChange(ev.target.value); this.onChange(ev.target.value);
} }
constructor( constructor(ngControl: NgControl) {
@Optional ngControl: NgControl,
elementRef: ElementRef,
renderer: Renderer
) {
this.renderer = renderer;
this.elementRef = elementRef;
if (!ngControl) return; if (!ngControl) return;
this.ngControl = ngControl; this.ngControl = ngControl;
@ -77,7 +69,7 @@ export class SearchbarInput {
* *
* @usage * @usage
* ```html * ```html
* <ion-searchbar [(ngModel)]="defaultSearch" (cancel)="onCancelSearchbar(ev, value)"></ion-searchbar> * <ion-searchbar [(ngModel)]="defaultSearch" (input)="triggerInput($event)" (cancel)="onCancelSearchbar($event)" (clear)="onClearSearchbar($event)"></ion-searchbar>
* ``` * ```
* *
* @property {string} [cancelButtonText=Cancel] - Sets the cancel button text to the value passed in * @property {string} [cancelButtonText=Cancel] - Sets the cancel button text to the value passed in
@ -86,6 +78,7 @@ export class SearchbarInput {
* *
* @property {Any} [input] - Expression to evaluate when the Searchbar input has changed * @property {Any} [input] - Expression to evaluate when the Searchbar input has changed
* @property {Any} [cancel] - Expression to evaluate when the cancel button is clicked. * @property {Any} [cancel] - Expression to evaluate when the cancel button is clicked.
* @property {Any} [clear] - Expression to evaluate when the clear input button is clicked.
* *
* @see {@link /docs/v2/components#search Search Component Docs} * @see {@link /docs/v2/components#search Search Component Docs}
*/ */
@ -93,23 +86,27 @@ export class SearchbarInput {
selector: 'ion-searchbar', selector: 'ion-searchbar',
template: template:
'<div class="searchbar-input-container">' + '<div class="searchbar-input-container">' +
'<button (click)="cancelSearchbar($event, query)" (mousedown)="cancelSearchbar($event, query)" clear dark class="searchbar-md-cancel">' + '<button (click)="cancelSearchbar()" (mousedown)="cancelSearchbar()" clear dark class="searchbar-md-cancel">' +
'<icon arrow-back></icon>' + '<icon arrow-back></icon>' +
'</button>' + '</button>' +
'<div class="searchbar-search-icon"></div>' + '<div class="searchbar-search-icon"></div>' +
'<input [value]="query" (blur)="inputBlurred($event)" (focus)="inputFocused()" class="searchbar-input" type="search" [attr.placeholder]="placeholder">' + '<input (blur)="inputBlurred()" (focus)="inputFocused()" class="searchbar-input" type="search" [attr.placeholder]="placeholder">' +
'<button clear *ngIf="query" class="searchbar-clear-icon" (click)="clearInput()" (mousedown)="clearInput()"></button>' + '<button clear *ngIf="query" class="searchbar-clear-icon" (click)="clearInput()" (mousedown)="clearInput()"></button>' +
'</div>' + '</div>' +
'<button clear (click)="cancelSearchbar($event)" (mousedown)="cancelSearchbar($event)" [hidden]="hideCancelButton" class="searchbar-ios-cancel">{{cancelButtonText}}</button>', '<button clear (click)="cancelSearchbar()" (mousedown)="cancelSearchbar()" [hidden]="hideCancelButton" class="searchbar-ios-cancel">{{cancelButtonText}}</button>',
directives: [FORM_DIRECTIVES, NgIf, NgClass, Icon, Button, SearchbarInput] directives: [FORM_DIRECTIVES, NgIf, NgClass, Icon, Button, SearchbarInput]
}) })
export class Searchbar extends Ion { export class Searchbar extends Ion {
@Input cancelButtonText: string; @ViewChild(SearchbarInput) searchbarInput;
@Input hideCancelButton: any;
@Input placeholder: string;
// @Output input: EventEmitter<any> = new EventEmitter(); @Input() cancelButtonText: string;
@Output cancel: EventEmitter<any> = new EventEmitter(); @Input() hideCancelButton: any;
@Input() placeholder: string;
@Input() ngModel: any;
@Output() input: EventEmitter<Searchbar> = new EventEmitter();
@Output() cancel: EventEmitter<Searchbar> = new EventEmitter();
@Output() clear: EventEmitter<Searchbar> = new EventEmitter();
@HostBinding('class.searchbar-focused') isFocused; @HostBinding('class.searchbar-focused') isFocused;
@ -118,30 +115,19 @@ export class Searchbar extends Ion {
* @private * @private
* Check if the Searchbar has a value and left align if so * Check if the Searchbar has a value and left align if so
*/ */
private shouldLeftAlign() { private get shouldLeftAlign() {
return this.searchbarInput && this.searchbarInput.value && this.searchbarInput.value.trim() != ''; return this.value && this.value.trim() != '';
} };
@ViewChild(SearchbarInput) searchbarInput; value: string = '';
query: string = '';
blurInput = true; blurInput = true;
constructor( constructor(
elementRef: ElementRef, elementRef: ElementRef,
config: Config, config: Config,
ngControl: NgControl,
renderer: Renderer
) { ) {
super(elementRef, config); super(elementRef, config);
this.renderer = renderer;
this.elementRef = elementRef; this.elementRef = elementRef;
// If there is no control then we shouldn't do anything
if (!ngControl) return;
this.ngControl = ngControl;
this.ngControl.valueAccessor = this;
} }
/** /**
@ -156,6 +142,9 @@ export class Searchbar extends Ion {
this.cancelButtonText = this.cancelButtonText || 'Cancel'; this.cancelButtonText = this.cancelButtonText || 'Cancel';
this.placeholder = this.placeholder || 'Search'; this.placeholder = this.placeholder || 'Search';
if (this.ngModel) this.value = this.ngModel;
console.log(this.value);
} }
/** /**
@ -187,9 +176,9 @@ export class Searchbar extends Ion {
* Clears the input field and triggers the control change. * Clears the input field and triggers the control change.
*/ */
clearInput() { clearInput() {
this.searchbarInput.writeValue(''); this.value = '';
this.searchbarInput.onChange('');
this.blurInput = false; this.blurInput = false;
this.clear.emit(this);
} }
/** /**
@ -198,19 +187,9 @@ export class Searchbar extends Ion {
* the clearInput function doesn't want the input to blur * the clearInput function doesn't want the input to blur
* then calls the custom cancel function if the user passed one in. * then calls the custom cancel function if the user passed one in.
*/ */
cancelSearchbar(ev, value) { cancelSearchbar() {
this.clearInput(); this.clearInput();
this.blurInput = true; this.blurInput = true;
console.log("should cancel"); this.cancel.emit(this);
this.cancel.next();
}
/**
* @private
* Updates the value of query
*/
updateQuery(value) {
this.query = value;
this.input.emit();
} }
} }

View File

@ -18,15 +18,15 @@ class E2EApp {
} }
onCancelSearchbar(ev) { onClearSearchbar(searchbar) {
console.log("Clicked cancel action with", ev); // console.log("Clicked clear input on", searchbar.value);
} }
triggerInput(ev) { onCancelSearchbar(searchbar) {
// The defaultSearch doesn't get updated before this function is called console.log("Clicked cancel button with", searchbar.value);
// so we have to wrap it in a timeout }
setTimeout(() => {
console.log("Triggered input", ev); triggerInput(searchbar) {
}); // console.log("Triggered input", searchbar.value);
} }
} }

View File

@ -1,17 +1,17 @@
<ion-content> <ion-content>
<h5 padding-left> Search - Default </h5> <h5 padding-left> Search - Default </h5>
<ion-searchbar [(ngModel)]="defaultSearch" (input)="triggerInput($event)" (cancel)="onCancelSearchbar($event)" class="e2eDefaultFloatingSearchbar"></ion-searchbar> <ion-searchbar [(ngModel)]="defaultSearch" (input)="triggerInput($event)" (cancel)="onCancelSearchbar($event)" (clear)="onClearSearchbar($event)" class="e2eDefaultFloatingSearchbar"></ion-searchbar>
<p padding-left> <p padding-left>
Default Search: <b>{{ defaultSearch }}</b> Default Search: <b>{{ defaultSearch }}</b>
</p> </p>
<h5 padding-left> Search - Custom Placeholder </h5> <h5 padding-left> Search - Custom Placeholder </h5>
<ion-searchbar [(ngModel)]="customPlaceholder" placeholder="Filter Schedules" class="e2eCustomPlaceholderFloatingSearchbar"></ion-searchbar> <ion-searchbar [(ngModel)]="customPlaceholder" (cancel)="onCancelSearchbar($event)" (clear)="onClearSearchbar($event)" placeholder="Filter Schedules" class="e2eCustomPlaceholderFloatingSearchbar"></ion-searchbar>
<h5 padding-left> Search - Hide Cancel Button </h5> <h5 padding-left> Search - Hide Cancel Button </h5>
<ion-searchbar [(ngModel)]="defaultCancel" hideCancelButton class="e2eDefaultCancelButtonFloatingSearchbar"></ion-searchbar> <ion-searchbar [(ngModel)]="defaultCancel" (cancel)="onCancelSearchbar($event)" (clear)="onClearSearchbar($event)" hideCancelButton class="e2eDefaultCancelButtonFloatingSearchbar"></ion-searchbar>
<h5 padding-left> Search - Custom Cancel Button Danger </h5> <h5 padding-left> Search - Custom Cancel Button Danger </h5>
<ion-searchbar [(ngModel)]="customCancel" cancelButtonText="Really Long Cancel" class="e2eCustomCancelButtonFloatingSearchbar" danger></ion-searchbar> <ion-searchbar [(ngModel)]="customCancel" (cancel)="onCancelSearchbar($event)" (clear)="onClearSearchbar($event)" cancelButtonText="Really Long Cancel" class="e2eCustomCancelButtonFloatingSearchbar" danger></ion-searchbar>
</ion-content> </ion-content>

View File

@ -489,10 +489,8 @@ export class TextInputElement {
} }
ngOnInit() { ngOnInit() {
if (this.ngModel) console.log("Value", this.ngModel);
if (this.ngModel) this.value = this.ngModel; if (this.ngModel) this.value = this.ngModel;
this.wrapper && this.wrapper.hasValue(this.value); this.wrapper && this.wrapper.hasValue(this.value);
console.log(this.value);
} }
focusChange(changed) { focusChange(changed) {