Reputation: 136
I am using ionic framework 3 ( v 3.9.2). I use the search bar in the top nav and display results in a list below in the content. Pretty standard. However, the keyboard shows until I close it explicitly (using this.keyboard.hide() in my code) as a result of a user action ( e.g. user clicks cancel or clicks the search button on the keyboard). I use the Keyboard Plugin from Ionic.
What I ideally want is to hide the keyboard also when user starts scrolling on the search results, especially when results start showing up as they type in the search input box. Behavior same on Android and iOS - actual devices
Here is what I have tried: 1. On the ion-content, I monitor a scroll start event and then invoke the keyboard hide function. But it is flaky. The keyboard pops up twice sometimes, does not close all the time. 2. I could turn off the "display results while typing" and force the user to explicitly click search or cancel upon which I hide the keyboard which works fine , but that is not the user experience I want. 3. I tried to see if I could hide the keyboard when a blur event ( ionBlur) is triggered as I soon as I start scrolling ,but the blur never gets triggered
Any suggestions?
Upvotes: 0
Views: 2150
Reputation: 695
I am in a situation where my scrollable element is not ion-content
but an inner div. That means the ion events are not available. Also, the native scrollend
event does not work via Safari.
I was running into a situation where the momentum of a scroll could cause the keyboard to not open properly when clicked. I ended up using touch events as listeners instead of scroll events. Ironically, if the scroll continues, the touch event is only considered once. That means the scroll has to come to rest before the Keyboard can be closed by the user. That seems better behavior than closing a keyboard the user is trying to open because scroll continues.
Wish I could get scroll start events :p
html
<div (touchmove)="onTouchMove($event)" role="feed">
component
onTouchMove(event: Event) {
Keyboard.hide()
}
Upvotes: 0
Reputation: 6349
The solution I found was to use the Keyboard plugin
import { Keyboard } from '@ionic-native/keyboard/ngx';
Add to providers for the component
@Component({
selector: 'app-home',
templateUrl: './home.page.html',
styleUrls: ['./home.page.scss'],
providers: [Keyboard] // <-- This line
})
Add to constructor
constructor(private keyboard: Keyboard) {}
Make sure your ion-content is tracking scroll events:
<ion-content [scrollEvents]="true" (ionScroll)="onScroll($event)">
Now simply make the method turn the keyboard off:
onScroll($event) {
this.keyboard.hide();
}
This is probably suboptimal, but I don't see any better solutions around.
Upvotes: 0
Reputation: 53
Ran into this issue myself. Had a searchbar combined with a virtual scroll component. As you menntioned, every time the list changed based on the searchbar input, there was a scroll event triggered, making it hard to hide the keyboard on a scroll event. After a lot of trial and error, I got this to work. For whatever reason, my scroll event triggered by the virtual scroll was null so a simple check to not close the keyboard if it was null fixed the problem for me.
Your HTML:
<ion-content (ionScrollStart)="onScrollStart($event)">
and your .ts:
onScrollStart(event: any) {
if (event === null) {
return;
}
this.closeKeyboard();
}
Upvotes: 1
Reputation: 9235
So my theory would be that the approach "on the ion-content, I monitor a scroll start event and then invoke the keyboard hide function" can still be valid.
The issue with onScroll events is that they are firing in a rapid succession and this can cause issues and flakiness.
Try implementing simple "debounce" strategy:
// have this var in your ts file:
private scrollTriggered: boolean;
// update your onScroll method:
onScroll(event:Event) {
if (!scrollTriggered) {
this.keyboard.hide();
this.scrollTriggered = true;
};
}
// now somewhere in your search input code (like ionInput) you need to reset flag to false:
this.scrollTriggered = false;
Idea is to ensure the keyboard.hide() is only called once on one time scroll event being triggered.
Please let me know if this works for you.
Upvotes: 0