PDA

View Full Version : [Sencha Touch Android] show and hide keyboard with code ?



Eric Clapton
25 Jul 2011, 3:17 AM
Hello,

I'm developing an app with a screen that has TextAreaField inside.

When user taps on textareafield virtual keyboard opens and if user never hits back button keyboard never hides.So keyboard is still on screen while user is navigating through other screens.

My will is to hide the keyboard when user taps on anywhere outside virtual keyboard.(on the same textarea for instance)

There should be some stable way to do this with Sencha Touch.:-/

Has anybody every used TextArea and faced a "keyboard hide" problem like this before?

Any help will be appreciated.

Philip Murphy
30 Oct 2011, 9:19 AM
Hi,

Was wondering did you ever get a solution to this as I am facing the exact same problem. Seems incredible that such a basic thing is proving very difficult to find a solution to.

Thanks in advance,

Philip

Eric Clapton
30 Oct 2011, 11:06 PM
Hello,

I was using phoneGap with Sencha Touch so I've done it using the following code.Maybe if you are using phoneGap try this:




public enum KeyBoard {


INSTANCE;


private WebView appView;
private DroidGap mGap;


public void showKeyBoard() {
InputMethodManager mgr = (InputMethodManager) mGap
.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.showSoftInput(appView, InputMethodManager.SHOW_IMPLICIT);


}


public void hideKeyBoard() {
InputMethodManager mgr = (InputMethodManager) mGap
.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(appView.getWindowToken(), 0);
}


/**
* @return the appView
*/
public WebView getAppView() {
returnappView;
}


/**
* @param appView
* the appView to set
*/
public void setAppView(WebView appView) {
this.appView = appView;
}


/**
* @return the mGap
*/
public DroidGap getmGap() {
returnmGap;
}


/**
* @param mGap
* the mGap to set
*/
public void setmGap(DroidGap mGap) {
this.mGap = mGap;
}


}

Philip Murphy
3 Nov 2011, 12:51 PM
Hi Eric,

Thanks for the update, however, I'm not using PhoneGap, so I'm afraid I don't have access to it's JS-native bridge API.

I've figured out the main issue I was having. It was very subtle indeed. The set up that I have is a separate panel, which is a child of a card layout component, with a text area field and form, so that a user can post a message. They have the opportunity to submit or cancel the message. It is most probable that the virtual keyboard will be open when the cancel or submit button is pressed. If either button is pressed the panel should disappear, the keyboard should be hidden, and they should be returned to the previous screen.

On closing the panel when tapping the back button (i.e setActiveItem), thinking of being a good memory management citizen, I tried to destroy the panel that I was leaving. However, if you do this straight away the OS gets a bit confused and inadvertently fails to close the open virtual keyboard. The solution is to destroy the panel via a setTimeout call, so that the native OS keyboard code gets a moment to run. I've included an outline of the code I used to solve the problem as I'm sure this has caught a few more developers out (and it certainly took me a long time to figure out what on earth was going on).

I've also included a work-around to the 'after' event on an animation being called twice.


myapp.views.InputPopupView = Ext.extend(Ext.Panel, {


initComponent: function() {
var me = this;


this.dockedItems = [
{
xtype: 'toolbar',
dock: 'top',
defaults: {
scope: this
},
items: [
{
ui: 'default',
text: 'Cancel',
handler: this.showPreviousCard
},
{
xtype: 'spacer'
},
{
ui: 'confirm',
text: 'Save',
id: 'save-button',
handler: function() {
// Do something interesting here

this.showPreviousCard();
}
}
]
}
];


this.items = [
{
xtype : 'form',
itemId: 'myForm',
items: [
{
itemId: 'myTextArea',
xtype: 'textareafield',
name: "myValue",
placeHolder: "Enter your message",
listeners: {
afterrender : function(panel) {
this.el.down('textarea').setHeight((this.ownerCt.ownerCt.getHeight()/100*45)); // Set to 45% of screen height.
},


focus: function() {
window.scrollTo(0,1); // Force top-docked toolbar back into view. (was a problem on iPad)
}
}
}
]
}
];


myapp.views.InputPopupView.superclass.initComponent.apply(this, arguments);
},

showPreviousCard : function() {
this.ownerCt.setActiveItem(this.prevCard, { // Example code assumes that parent is using a card layout.
type: 'slide',
direction: 'down',
scope: this,
after: function() {
if(this.callSetActiveItemOnce === 0) { // Fix to stop method being called twice due to Sencha issue.
this.callSetActiveItemOnce++;


// Required to hide virtual keyboard. Do not do on Android as causes screen to jump after
// slide transition. (In my case the previous screen is a panel with scroll: 'vertical' set)
if(!Ext.is.Android) {
this.down('#myTextArea').blur();
}


// Allow virtual keyboard to disappear before destroying panel.
var me = this;
setTimeout(function() {
me.callSetActiveItemOnce = 0; // Fix to stop method being called twice due to Sencha issue.
me.destroy();
}, 500);
}
}
});
},

callSetActiveItemOnce: 0 // Fix to stop method being called twice due to Sencha issue.
});

Following CSS will ensure textareafield is displayed full width. I'm sure there must be a better way of doing this, but just including for completeness.


.x-form .x-panel-body {
padding: 0;
}

msarath
2 Feb 2012, 9:33 PM
Anybody has similar functional code for iPhone please?
I am using sencha with phonegap. Please advice.

Philip Murphy
3 Feb 2012, 2:21 AM
Here is a snippet that I'm using. The callback and scope are optional and may be omitted. The code assumes that you are in a text field or a text area. Works for web app, so might work for native as well. Let me know if it's of any use.



hideKeyboard: function(callback, scope) {
var activeElement = document.activeElement;
activeElement.setAttribute('readonly', 'readonly'); // Force keyboard to hide on input field.
activeElement.setAttribute('disabled', 'true'); // Force keyboard to hide on textarea field.
Ext.defer(function() {
activeElement.blur();
// Remove readonly attribute after keyboard is hidden.
activeElement.removeAttribute('readonly');
activeElement.removeAttribute('disabled');
if(callback) {
callback.call(scope);
}
}, 100);
}

TDeBailleul
19 Feb 2012, 8:09 AM
Thanks for your answer, it works perfectly

eyepoker
21 Feb 2012, 11:14 AM
have you guys tried just blurring the input element? works for me. Is there a need to do philip's method? seems like a lot if blur does the job.

i.e., Ext.getCmp('componentID').blur();

srikanthkamatam
8 May 2013, 3:01 AM
Thanks eyepoker & Philip...

Both the answers works perfectly fine.

syardumian
30 Oct 2013, 10:23 AM
Thank you! Philip, your answer works. Just what I needed. +1