I'm having a few issues getting a keyup event to fire on my iPhone, my code is as follows:
var passwordArray = ["word", "test", "hello", "another", "here"];
var test = document.getElementById('enter-password');
test.addEventListener('keyup', function(e) {
if (jQuery.inArray(this.value, passwordArray) != -1) {
alert("THIS IS WORKING");
} else {}
});
The idea being that as the user is typing into the #enter-password field, as and when they've matched a word in the passwordArray the alert will fire. This works on desktop, e.g. once you've entered word the function will fire straight away as soon as you've typed the d. Is there anyway to get this to work for mobile too?
You can add input event. It is an event that triggers whenever the input changes. Input works both on desktop as well as mobile phones
test.on('keyup input', function(){
//code
});
You can check this answer for more details on jQuery Input Event
There are three events you can use (but you have to be careful on how you "combine" them):
keyup : it works on devices with a keyboard, it's triggered when you release a key (any key, even keys that don't show anything on the screen, like ALT or CTRL);
touchend: it works on touchscreen devices, it's triggered when you remove your finger/pen from the display;
input: it's triggered when you press a key "and the input changes" (if you press keys like ALT or CTRL this event is not fired).
The input event works on keyboard devices and with touchscreen devices, it's important to point this out because in the accepted answer the example is correct but approximative:
test.on('keyup input', function(){
}
On keyboard based devices, this function is called twice because both the events keyup and input will be fired.
The correct answer should be:
test.on('keyup touchend', function(){
}
(the function is called on keyup for desktops/laptops OR on touchend for mobiles)
or you can just simply use
test.on('input', function(){
}
but remember that the input event will not be triggered by all keys (CTRL, ALT & co. will not fire the event).
The touchend event is fired when a touch point is removed from the device.
https://developer.mozilla.org/en-US/docs/Web/Events/touchend
You can pass keyup and touchend events into the .on() jQuery method (instead of the keyup() method) to trigger your code on both of these events.
test.on('keyup touchend', function(){
//code
});
You should add a input event. It works on both mobile and computer devices.
Related
I'm trying to build a shortcut expander, so when a user types a certain sequence of characters, it's replaced with some longer sentence.
I'm currently using 'input' event to capture contenteditable changes. The issue is, pasting also triggers the 'input' event. I only want the event to fire when user types in a character. Is there any way to do this?
The simplest solution would be to detect a keyboard event (keydown, keyup or keypress) instead of oninput, but which to choose, depends on what the handler actually will do.
If you don't want/can't use keyboard detection, there's a back-gate. It looks like onpaste would fire before oninput (Chrome, FF). Hence you could create a flag for paste, and check it in oninput handler. Something like this:
var pasted = false,
pad = document.getElementById('pad'); // The contenteditable
pad.addEventListener('paste', function (e) {
pasted = true;
});
pad.addEventListener('input', function (e) {
if (pasted) {
pasted = false;
return;
}
console.log('keyboard, cut or drop');
});
A live demo at jsFiddle.
Notice, that oninput is fired also ondrop and oncut as well as onpaste and typing in. If you don't want to handle any of these events in oninput handler, you've to listen all these events, and set a flag accordingly.
As a sidenote, IE doesn't fire oninput on contenteditables. If you want to support IEs, you need to use onkeypdown/up-onpaste-oncut-ondrop combination to achieve something similar to oninput.
I am trying to intercept "Hide keyboard button" specific for Ipad in Javascript. I searched everywhere but could not find correct keycode for that.
I pressed any keys and I get a keycode map (for characters, but also for enter, space and delete..).
This is an example of what I want to accomplish
$( "#mydiv" ).on( "keydown", function( event ) {
if (event.which == xx){
//do something
}
}
where xx is my keycode on 'hide keyboard button'. No method is called to the delegate when the button is pressed nor a KeyCode.
I took a look at detect iPad keyboard Hiding button, but I get a solution on a different level (with Xcode), but I need a solution with Javascript.
Hope someone could help.
I found a workaroud for iPad IOS7. I will test on IOS8 to make sure it works. So basically I create a listener on every FOCUSOUT event (for all my texts) and I call my function.
It fires when you have your keyboard open and when you close your "keyboard". It doesn't fire when you select another text field or button, because it targets on null. If you use in combination with keydown, you can save multiple value and call your submit function only when you release your keyboard.
It works for my specific project.
document.addEventListener('focusout', function(e) {
if (e.relatedTarget === null) {
alert("close keyboard without click on something else");
callYourFunction();
}
});
p.s
I'm pretty new here in SO, so I don't know if I can reply myself or I should edit my question or make a comment.
I'm not very satisfied with the key events in javascript. I need to capture both letters for writing (I'm writing text on <canvas>) and functional keys (escape) for other commands.
In Firefox it works, because Firefox fires keypress event for any key. It's very comfortable but specification directly permits it:
If supported by a user agent, this event MUST be dispatched when a key is pressed down, if and only if that key normally produces a character value.
I disagree with that specification as I see no reason for it. But as it is now, I can't do anything about it.
Problem is that Google Chrome follows that specification and doesn't fire keypress for functional keys. It does, however, notmally fire keydown for all keys.
My program has only one key event handler. It expects event containing keyCode (the ID of the physical key and optionally charCode, the equivalent character value (for keys where it makes sense).
keydown event does not contain any character values in neither browser! It only contains the keyCode. So if you define a Ctrl+Z combination and listen for keydown event, your program will be broken for users that have QWERTZ layout - because the physical location of the key (keyCode) is still the same.
If you listen for both keydown and keypress, character events will fire twice (beacuse character first fires keydown and then keypress with proper charCode property)
What I need?
Based on the above, I need to ignore keydown event for keys that will cause keypress. Doing so, I'll be able to capture Esc in keydown and characters in keypress.
How could I possibly do it?
Relevant code:
//Keypress for character codes
div.addEventListener("keypress", function(event) {
console.log(event);
if(_this.editor.event(event)) {
console.log("Event canceled.");
event.preventDefault();
event.cancelBubble = true;
return false;
}
return true;
});
//Keydown for Esc and the likes
div.addEventListener("keydown", function(event) {
//Character events are handled by keypress
if(event.charCode!=0) //Does NOT work - in keydown, charCode is ALLWAYS 0
return true;
console.log(event);
if(_this.editor.event(event)) {
console.log("Event canceled.");
event.preventDefault();
event.cancelBubble = true;
return false;
}
return true;
});
Interactive example
I figured I spend a lot of time making JSFiddles and it doesn't really increase the odds of getting an answer, so I instead uploaded the actual project.
Click into the white square in Firefox, press T, type text, press Esc, press Esc. After seconds Esc, cursor should get back to normal. Try to draw and press Ctrl+Z.
Repeat the process in Google Chrome. The Escape will not work because it doesn't fire keypress. For some reason, the Ctrl+Z fires event with keyCode 26.
From chat and comments:
#someDoge has created a fiddle which I have expanded and which now nicely shows the situation. As you can see, you can know that a key isn't character and ignore it in keypress. But you can't know that tab isn't character and cancel it in keydown (unless you have fixed array of keycode values as #someDoge sugests in comments).
You need to listen for keyup events instead of keydown, this way you won't get two separate events generated.
Then you can handle the 2 event types with the same handler function which will either get a charCode or not, depending on if the particular key generated a 'keypress' event. As long as you prevent bubbling your handler will only be called once.
Regarding the Chrome CTRL+Z problem: I don't see how you can get a charCode if the control key is being pressed, since it seems only to generate a keyup event.
Javascript has three events for key presses, keyup, keypress and keydown.
For some reason Sencha Touch only supports they keyup event. I want to catch the event (probably keydown or keypress) before it changes the value in the textfield. Catching the keydown event would make this possible, also it should be a lot faster. With keyup the effect is a bit slow.
Finally the goal is to allow the user to only enter number and add decimal and thousand separators automatically. That's currently possible with the keyup event, but slow. As a user you can see the text changing and then being changed again.
My code for adding the keydown event to the textfield:
initialize: function()
{
this.down('textfield[name=amountTotal]').onkeydown
= MyApp.app.getController('MyController').handleInput;
}
I've checked that when this code executes the textfield is found and the controller function does hold the correct function that I want to execute. I've also added the function to my view file.
Yet it won't reach my handleInput function.
I know Sencha does not support other events, but this should be possible with just pure Javascript.
You almost got it.
initialize: function() {
var textfield = this.down('textfield[name=amountTotal]');
textfield.bodyElement.dom.onkeydown = MyApp.app.getController('MyController').handleInput;
}
Fiddle: https://fiddle.sencha.com/#fiddle/caj
I have a search field that triggers an autocomplete search while typing. I have it trigger on keyup. This works perfectly in most browsers, but in Firefox on Android, this does not work. It seems like the keyup event is not triggered while typing. This only happens if word suggestions is turned on in the Android keyboard settings.
I see on Google search that the autocomplete search works there for the same setup, so it is obviously possible to do. I wonder how? Is it a special event I need to listen to for this to work?
Additionally I have tried to listen to the events change, keydown and keypress, but none is triggered.
HTML:
<input type="text" id="searchField"
autocomplete="off" spellcheck="false" autocorrect="off" />
jQuery event binding:
$('#searchField').keyup(function (e) {
var searchValue = $(this).val();
searchApi._executeAutocomplete(searchValue);
});
Note:
Sometimes, the key event is triggered, which is typically hitting a key that is not resulting in the process of forming a word. The most obvious here is Enter, which always triggers. Another is Space, which triggers because no word contain a space since space is the definition of a word completed. Backspace triggers if the the last character deleted was not within a word. This means it triggers if you just deleted the last remaining letter of a word (so it is the start of the field, or cursor following a space), but not if you deleted some characters at the end of a word where the cursor is still immediately following a letter. Basically, the key event is not triggered if the key press results in some kind of word suggestion from the keyboard app.
As a side note, I can say that everything works fine in Chrome on the same device.
You can use the input event instead, that worked for me in Firefox on Android.
You could bind event handlers to both input and keyup events for backwards compatibility, but in most modern browsers this will fire both:
$('#searchField').bind('input keyup', function(e){
var searchValue = $(this).val();
searchApi._executeAutocomplete(searchValue);
});
Example here:
http://jsfiddle.net/JQ928/3/
I found a solution in this answer to another question. The question was a basically "duplicate the text I write dynamically into another part of the page". The answer was including support for catching changes by non-keyboard actions, like pasting text using mouse. It was solved by starting a sniffer on focus in the text field that checks if the value has changed using setInterval(...). It clears the timer on blur.
This solved my problem which was basically that the key events didn't trigger, as well as the "paste by mouse" issue that I didn't realize was a problem until I found this answer...!
This works, but I'm not sure I am totally happy with this solution, because it uses a sniffer. I would be more happy with using some sort of event that is triggered on value change no matter what the cause of the change is. Using the change event would not work, as that is not triggered until focus leaves the field.
Trough the fact that Firefox on Android doesn't trigger key-events, but also triggers the input-event some kind of weird, (like if you press one key two events get triggerd, and it also triggers the input-event if you leave the input) I had to write my own event:
(function($){
var $event = $.event,
$special = $event.special.fennecInput = {
setup: function(){
$(this).on('input',$special.handler);
},
teardown: function(){
$(this).off('input',$spceial.handler);
},
handler: function(event) {
var context = this,
args = arguments,
dispatch = function() {
event.type='fennecInput';
$event.dispatch.apply(context,args);
};
if($(context).val() != $(context).attr('data-fennecInput-oldval')){
dispatch();
$(context).attr('data-fennecInput-oldval',$(context).val());
}
}
};
})(jQuery);
this event gets only triggered if an input-event happens that changes the value, so it doesn't execute events unnecessary.