Reconcile Firefox slash handling and key codes - javascript

I have a webpage where users should be able to type anywhere and have their input tracked. One problem is that the slash key, "/," in firefox is a shortcut for opening the search. This is undesirable for me. I have not found a way to trap the search functionality and still add the input to my tracking. I add the input to the stack on keypress.
keydown...preventDefault works best in FireFox, but the problem is that in Chrome, keypress does not fire for some reason (not sure why preventDefault would stop that, but it does). This would be okay if I could add the slash on my own to the input stack..but Firefox is already adding it because keypress is still triggered. stopPropagation does not prevent keypress from triggering in FireFox either. $(document).keypress(e) in the keydown method also does nothing.
Another issue I have is that "backspace" is supposed to remove from the stack, but I add to the stack with String.fromCharCode(e.which) and add the data to an input type="text" field that the user can see. In Chrome this works perfectly, but in FireFox, it adds a character representing the backspace and then immediately removes it, preventing another character from being removed. Having "backspace" and "f5," etc. characters in the input is also undesirable. Is there a way to tell if the fromCharCode value is valid for a text field? I think what's happening is that Chrome just does that automatically.
EDIT: This may help, but FireFox apparently triggers keypress before keydown (Chrome does the opposite) on my webpage. This is unusual.

Solved this with a bit of a kludge. I have a noslash variable that triggers capturing the slash:
else if (e.which == '191' && !noslash) {
e.preventDefault();
$typing.val($typing.val() + '/');
}
As for the second part of the question, I simply reject any character in
[^-a-z0-9`~!##$%^&*()_+=\\|/'";:,<.>?\[\]{}]

Related

JavaScript: block backspace on text input on Android

I'm trying to block all input on an html text field with jQuery. The following solution works on desktop browsers:
that.input.keydown(function (e) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
return false;
});
However, while it blocks regular input it fails to block backspace on Android (Chrome). I've also tried blocking the keyup and keypress events, but that didn't help. I don't want to set the readonly attribute, because I intend to allow the input in certain situations.
Is there any clean solution for this? Thanks in advance!
The reality is that android keyboards are not keyboards. When a text field is opened in android the text-field-owner application and the keyboard application, speaking simply, come to share a resource which is the text field contents. The keyboard app receives the entire contents of the text field and then edits - including deletions - are made locally and pushed to the app via calls like DeleteSurroundingText (for simple deletions of non-text content i.e. whitespace) or setComposingRegion/setComposingText for changes to words. This means that autocorrect can work on already-existing words.
Some android keyboards generate keypress events which reach Chrome, some do not. Sometimes it makes no sense to generate keypress events - if a word is autocorrected what keypresses should be sent?
As you are looking for the keyboard and cursor to be displayed but the field to remain uneditable until later I would suggest you implement some sort of onChange/Revert loop.
Detect all changes to a <input type="text"> (immediately) using JQuery
Apparently android keyboards have a strange bug with the keyboard so instead of attaching to the keydown event maybe try the oninput event.
I found more info on this issue here Capture keys typed on android virtual keyboard using javascript

iOS 7 safari possible javascript/dojo trim bug

Since the launch of iOS 7 we are getting orders through that have one character missing from the end of inputted data.
For example, if I enter Tanveer b Bal into the name field, it would return Tanveer b Ba. See screenshot below:
I believe the bug may be due to a trim filter we use on inputs to remove whitespace. We use the dojo/_base/lang trim function: https://github.com/dojo/dojo/blob/1.9/_base/lang.js#L510
String.prototype.trim ? function(str){ return str.trim(); } : function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); }
Has anyone else experienced this issue?
Instructions to reproduce
Visit http://demo.zoopcommerce.com
Add to cart
Checkout
Enter email address and name then click next
The email address may now be missing the last character
UPDATE:
I created a trim tester here: http://jsfiddle.net/QJFBL/embedded/result/ but it seems to work fine on iOS 7. (Created another one with more of my dependencies: http://jsfiddle.net/qmKvZ/8/)
I also tried my implementation on an iOS 7 VM on http://crossbrowsertesting.com/ and again, it worked.
UPDATE 2:
http://www.browserstack.com/ release an iOS7 VM today. I've tried my checkout with mixed results. Sometimes the bug happens and sometimes not. However, the bug still doesn't appear at all on a simple stripped back version http://jsfiddle.net/qmKvZ/9/embedded/result/, which makes me think there may be a deeper issue?
I can't 100% confirm why this is happening on the iOS side, but I can confirm a fix.
From what I can tell (with a very limited ability to debug), when autocomplete displays over an input, it does not propagate the last keypress event. Since dijit only watches keydown, keypress, paste, cut, input, compositionend events, the last character of an input can sometimes be missed.
To fix this bug, amend this line: https://github.com/dojo/dijit/blob/1.9/form/_TextBoxMixin.js#L347 from:
this.own(on(this.textbox, "keydown, keypress, paste, cut, input, compositionend", lang.hitch(this, handleEvent)));
to
this.own(on(this.textbox, "keydown, keypress, keyup, paste, cut, input, compositionend", lang.hitch(this, handleEvent)));
Basically you are just adding the keyup event. Be sure not to handle it in a similar way it handles keypress and keydown eg. https://github.com/dojo/dijit/blob/1.9/form/_TextBoxMixin.js#L238
I will submit a bug fix / issue to the dojo team as well.
I see the same problem on a non-dojo app. It seems like something about the keypress / keydown/ keyup handlers changed in iOS7 because the code works in iOS6 but gets trimmed in iOS7
I definitely see the same problem with our dojo app. Removing trim:true from the data-dojo-props solves the problem, although this can only be a temporary solution.

Detecting IME input before enter pressed in Javascript

I'm not even sure if this is possible, so apologies if it's a stupid question.
I've set up an keyup callback through jQuery to run a function when a user types in an input box. It works fine for English.
However when inputting text in Japanese/Korean/Chinese, the function isn't called until the user confirms their text.
Is it possible to detect that they've started typing, and access their as-yet unfinished text?
I'm thinking maybe it's an OS-level thing so Javascript doesn't have access to it.
Edit: I just realised that this works in Chrome and Safari, but not in Firefox (not had a chance to try it on Windows yet). So Chrome calls keyup and it's possible to get the text. But I'm still having the above problem in Firefox.
The compositionstart, compositionupdate and compositionend events might be helpful.
They help you detect when IME input is being used.
For example, consider using an IME to type か (ka) in Japanese.
The following events (in the order shown) would be fired:
k (IME visible) keydown, compositionstart, compositionupdate, compositionend, input
a (IME visible), compositionstart, compositionupdate, compositionend, input
enter (IME closed) keydown, input
Notice that the compositon events are only fired when the IME is visible (before enter is pressed). Also notice that the keypress event is not fired. This is only fired for non-IME input.
To access the user's unfinished text, you can use the data property of the event.
$('#input').on('compositionupdate', function(e) {
console.log(e.data);
});
For more info see MDN: compositionstart, compositionupdate, compositionend, InputEvent.
This is a known issue in Firefox, and what browsers should be doing isn't clear.
A possible method for working around this problem is demonstrated here, where the text field is polled for changes to the text (rather than relying on events).

Why isn't backspace being detected using jQuery keypress event?

Why isn't backspace being detected using jQuery keypress event?
$("#field").keypress(function(event){alert(event.which);});
Try using keydownand keyupfunctions instead for IE.
Javascript e.keyCode doesn't catch Backspace/Del in IE
The "keypress" event is (in its original IE form, and in Safari/Chrome) about an actual character being added to a text field. The backspace key clearly does not add a new character to the field value, so it causes no keypress event.
Firefox and Opera are a little more willy-nilly about generating typing events.
PPK (quirksmode) considers the IE and Webkit behaviors to be the sensible ones, and I pretty much agree.
The onKeyUp alone will do all the keyboard key detection in chrome..

IE, textarea value is not changed when pressing buttons

I have a really nasty problem with focus in Internet Explorer.
I have a textarea for inputting text. This textarea is not visible for the user and is only used to provide robust text input for a more advanced view.
As the textarea isn't visible and shouldn't be I use textarea.focus() in the JavaScript to activate text-input. This has worked fine until now where I get really weird results.
For the textinput I basically use this event plus an exact copy for onkeypress.
textarea.onkeyup = function (e) {
//textarea.value contains the full text
//Update the view with this value
};
The problem is that sometimes textarea.value is not updated. I can even see the button in e.keyCode on the keyup event above but the value isn't changed.
This seems to happen after I have clicked somewhere on the page, but this does not trigger a blur-event. I'm logging the onfocus- and onblur-events so I can see when the textarea loses focus but it doesn't. And i still receive the keyup/press/down events.
If I try to refocus the textarea with textarea.focus() the problem remains. A workaround I found though is to focus the window with window.focus() and right after call textarea.focus().
The problem with this is that focus is a really expensive operation in IE (no kidding) and since I cannot detect when this problem will happen I have to keep doing it with certain interval which seriously affects the performance of my application (involves animation etc).
I use the exact same code for other browsers and do not have this problem there.
Change the identifier to something less generic like "textAreaAdv", IE sometimes get confused with this word.

Categories

Resources