Skip to content

Commit

Permalink
fix(searchbar): fix input bluring
Browse files Browse the repository at this point in the history
fixes #14916
  • Loading branch information
manucorporat committed Jul 29, 2018
1 parent a62759c commit d65174b
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 45 deletions.
54 changes: 13 additions & 41 deletions core/src/components/searchbar/searchbar.tsx
Expand Up @@ -14,17 +14,15 @@ import { createColorClasses } from '../../utils/theme';
scoped: true
})
export class Searchbar {

private nativeInput!: HTMLInputElement;
private isCancelVisible = false;
private shouldBlur = true;
private shouldAlignLeft = true;

@Element() el!: HTMLElement;

@Prop({ context: 'document' }) doc!: Document;

@State() activated = false;

@State() focused = false;

/**
Expand Down Expand Up @@ -158,9 +156,14 @@ export class Searchbar {
/**
* Clears the input field and triggers the control change.
*/
private clearInput() {
private clearInput(ev?: Event) {
this.ionClear.emit();

if (ev) {
ev.preventDefault();
ev.stopPropagation();
}

// setTimeout() fixes https://github.com/ionic-team/ionic/issues/7527
// wait for 4 frames
setTimeout(() => {
Expand All @@ -170,7 +173,6 @@ export class Searchbar {
this.ionInput.emit();
}
}, 16 * 4);
this.shouldBlur = false;
}

/**
Expand All @@ -180,10 +182,7 @@ export class Searchbar {
*/
private cancelSearchbar() {
this.ionCancel.emit();

this.clearInput();
this.shouldBlur = true;
this.activated = false;
}

/**
Expand All @@ -197,49 +196,22 @@ export class Searchbar {
this.ionInput.emit(ev);
}

private inputUpdated() {
// const inputEl = (this.el.shadowRoot || this.el).querySelector('.searchbar-input') as HTMLInputElment;
// It is important not to re-assign the value if it is the same, because,
// otherwise, the caret is moved to the end of the input
// if (inputEl && inputEl.value !== this.value) {
// // inputEl.value = this.value;
// this.value = inputEl.value;
// }

this.positionElements();
}

/**
* Sets the Searchbar to not focused and checks if it should align left
* based on whether there is a value in the searchbar or not.
*/
private onBlur() {
const inputEl = (this.el.shadowRoot || this.el).querySelector('.searchbar-input') as HTMLInputElement;

// shouldBlur determines if it should blur
// if we are clearing the input we still want to stay focused in the input
if (this.shouldBlur === false) {
inputEl.focus();
this.shouldBlur = true;
this.ionBlur.emit();
this.inputUpdated();
return;
}

this.focused = false;
this.ionBlur.emit();
this.positionElements();
}

/**
* Sets the Searchbar to focused and active on input focus.
*/
private onFocus() {
this.activated = true;

this.focused = true;
this.ionFocus.emit();
this.inputUpdated();

this.positionElements();
}

Expand Down Expand Up @@ -270,7 +242,7 @@ export class Searchbar {
*/
private positionPlaceholder() {
const isRTL = this.doc.dir === 'rtl';
const inputEl = (this.el.shadowRoot || this.el).querySelector('.searchbar-input') as HTMLInputElement;
const inputEl = this.nativeInput;
const iconEl = (this.el.shadowRoot || this.el).querySelector('.searchbar-search-icon') as HTMLElement;

if (this.shouldAlignLeft) {
Expand Down Expand Up @@ -339,7 +311,6 @@ export class Searchbar {
return {
class: {
...createColorClasses(this.color),
'searchbar-active': this.activated,
'searchbar-animated': this.animated,
'searchbar-has-value': (this.value !== ''),
'searchbar-show-cancel': this.showCancelButton,
Expand All @@ -356,9 +327,8 @@ export class Searchbar {
const cancelButton = (this.showCancelButton)
? <button
type="button"
tabIndex={this.mode === 'ios' && !this.activated ? -1 : undefined}
tabIndex={this.mode === 'ios' && !this.focused ? -1 : undefined}
onClick={this.cancelSearchbar.bind(this)}
onMouseDown={this.cancelSearchbar.bind(this)}
class="searchbar-cancel-button">
{ this.mode === 'md'
? <ion-icon mode={this.mode} icon={this.cancelButtonIcon}></ion-icon>
Expand All @@ -385,9 +355,11 @@ export class Searchbar {

<button
type="button"
no-blur={true}
class="searchbar-clear-button"
onClick={this.clearInput.bind(this)}
onMouseDown={this.clearInput.bind(this)}>
onMouseDown={this.clearInput.bind(this)}
onTouchStart={this.clearInput.bind(this)}>
<ion-icon mode={this.mode} icon={clearIcon} class="searchbar-clear-icon"></ion-icon>
</button>
</div>,
Expand Down
9 changes: 5 additions & 4 deletions core/src/utils/input-shims/hacks/input-blurring.ts
@@ -1,5 +1,5 @@

const SKIP_BLURRING = ['INPUT', 'TEXTAREA', 'ION-INPUT', 'ION-TEXTAREA'];
const SKIP_SELECTOR = 'input, textarea, [no-blur]';

export function enableInputBlurring(doc: Document) {
console.debug('Input: enableInputBlurring');
Expand All @@ -25,17 +25,18 @@ export function enableInputBlurring(doc: Document) {
if (!active) {
return;
}

// only blur if the active element is a text-input or a textarea
if (SKIP_BLURRING.indexOf(active.tagName) === -1) {
if (active.matches(SKIP_SELECTOR)) {
return;
}

// if the selected target is the active element, do not blur
const tapped = ev.target;
const tapped = ev.target as HTMLElement;
if (tapped === active) {
return;
}
if (SKIP_BLURRING.indexOf(tapped.tagName) >= 0) {
if (tapped.matches(SKIP_SELECTOR) || tapped.closest(SKIP_SELECTOR)) {
return;
}

Expand Down

0 comments on commit d65174b

Please sign in to comment.