Converting keyCode to actual key and code values - javascript

Background: I have stored a key modifier and a keycode value, like so ["shiftKey", 32] (=> shift+space), or [undefined, 32] (=> space) on the user's machine. This array that I have stored acts as a "hotkey", i.e., I'm supposed to detect when user presses any key that matches with the hotkey. So, I'm supposed to do something when user presses Shift+Space, for example. Functionality wise it is working fine so far, as the keyCode's still match. The only problem is that...
Problem: I cannot properly display the keyCode in text form. ("?" key has keyCode=191 on my system, but it does not display correctly on doing String.fromCharCode, obviously)
My proposed solution: convert the [key modifier, keyCode] array to [key modifier, key, code] (since key and code properties can easily be displayed as text). The conversion code that I will write will run on the user's machine (it's a Chrome extension), so there is no worry of not having the locale information of the user. The problem is: how exactly to perform this conversion?
My attempt: dispatch programmatic keyboard events to a fake textbox based on the keyCode, and using the key and code values generated from there as the conversion result. However, the only properly working fiddle I could find required me to actually supply the key and code values, otherwise they would be undefined.
Final question: how else to perform this conversion? Or is there any other workaround to achieve what I want to?

Related

Is there a way to distinguish selecting from a datalist vs typing the same string manually?

As far as I can tell there isn't, but I figured I'd ask.
I have a text input. Autocomplete suggestions are fetched dynamically as you type and fill a datalist attached to the input. Normally, typing something and pressing the "search" button brings up a table of search results to select from.
Since the datalist is basically the exact same thing, but simplified, and selecting an option from it is unambiguous, I'd like it to just carry on with my selection handlers without having to bring up the list for selection a second time. When the person manually types something though, I still want them to explicitly pick from the list, especially since some options may be substrings of the others, so I don't want it to auto-select a result for you if it matches halfway through.
I ended up not reimplementing it like ControlAltDel suggested in his comment and instead went with the following slightly hacky but functional solution:
Since I am refetching the search results as you type, if only 1 search result is returned (ie. it's unambiguous) and the current string is a case-insensitive exact match to that result, then select it. It works well for what I need it for, but I could imagine this not working for everyone.
The JS is roughly as follows:
if (searchResults.length === 1
&& searchString.toLowerCase() === searchResults[0].toLowerCase()
) {
selectResult(searchResults[0]);
}
I'm calling this in my handler for when the search results list changes, not the input's handler, since the results are only re-fetched after the input has already been changed.

CodeMirror test whether value has changed

This question has a JSFiddle: jsfiddle.net/redmeat/L6p85fjc.
I'm attempting to make a server call when CodeMirror loses focus, but I first want to check if the value has changed.
CodeMirror provides an API for testing whether a value has changed, including whether the value was undone:
doc.changeGeneration(?closeEvent: boolean) → integer
doc.isClean(?generation: integer) → boolean
From the documentation: changeGeneration returns a number that can later be passed to isClean to test whether any edits were made (and not undone) in the meantime.
However if changes are reverted using the backspace or delete keys rather than undo and redo shortcuts, the form is considered not clean even if a change generation number is provided to isClean and the value is back where it started.
This JSFidlde shows that the values can match, but unless undo or redo shortcuts (ctrl+z and ctrl+y) are used, the form is considered dirty.
Open the JSFiddle.
Add a character to the end of foo.
Next, either:
Use the backspace key to remove the character.
OR
Use the Ctrl+z shortcut to remove the character.
In both scenarios the final value is the same as the original value. But it is only in the second scenario where isClean is true.
Question: Is there any way to check if the value is different? I naively expected isClean + changeGeneration to help here :/

Reading a barcode with javascript

I have a barcode gun scanner reading, barcodes, of course, into input fields. At the moment, I am able to read the barcode but it is returning every digit separately. I need it as a whole string. I have been breaking my skull about this.
For example, I read a bottle of water's barcode, the input field catches the number correctly (i.e. 688267022760). When I console log it, I get independent instances for each digit.
My template (VueJS) triggers the scanner event on input. Which I am not entirely sure if that is the correct event. I tried keydown and keyup as well. Not exactly sure which is the recommended event listener for a scan gun. Anyway this is what I have in my template:
<input id="packageInput" type="text" #input="onBarcodeScanned" />
And in my script:
onBarcodeScanned(barcode) {
let numbers = barcode.data; //data is the object property I need
console.log(numbers); //this shows me values I need
let newarr = []; //creating an emprty array where I assume I need to push data to
// looping through the data and pushing it to the new array, which does not do what I want but it was my logic
for (var i = 0; i < numbers; i++) {
newarr.push(numbers);
}
},
The desired effect would be to get those independent values in an array and then joined as a string.
P.S.
Reading the barcode property returns a series of objects with lots of handlers for several functions. The property of interest is data. See below an example of the barcode objects
How can I do this? I'm stumped
P.P.S
I understand the scanner itself comes with a series of instructions to program it. Some of which I don't understand too well. Perhaps there is a type of barcode that returns as a string instead of each digit as an object? The scanner I am using is a Wasp CCDScanner WCS3900
onInput runs every time the value changes. Most barcode scanners will simulate keypresses to enter the values they scan, so as far as your app is aware, each digit is a keypress that's changing the value and so it reports each as an input event. An input event's data property is just the part of the input that's changed -- so you're getting one at a time.
You need a way to determine when the input is finished, not whenever it happens. I believe most barcode scanners will simulate pressing ENTER or TAB after a full scan is complete, so that might be what you want to detect, not with an input event, but with a keypress or keyup event.

Ngx-Bootstrap Typeahead retaining dropdown values on input clear

I've recently upgraded the ngx-bootstrap from 1.8.1 to 3.0.1 . After the upgrade type ahead doesn't seem to work as expected. I'm using this example :
https://valor-software.com/ngx-bootstrap/#/typeahead#async-data
with [typeaheadMinLength]="3"
Now , if I search, lets say "abcdef" then it starts searching after 3 characters have been typed that is abc and then abcd, abcde, abcdef and so on which is fine.
But now if I delete everything in input textbox using backspace in one go, that is if I make abcdef to empty by pressing backspace in one go, then once input is empty, it shows drop down values again which correspond to min length which is abc.
Ideally it should clear drop down values but looks like when you delete it very fast using backspace, it retains the values corresponding to min length token string.
It is more visible when data is fetched from a service and the data is huge, so it takes some time to load and clear.
Delay in service response can be emulated using typeaheadWaitMs and this issue can be replicated using this example : https://valor-software.com/ngx-bootstrap/#/typeahead#delay
https://github.com/valor-software/ngx-bootstrap/issues/4412
Could someone please help on this?
You have to put a check if search field is empty then clear the list holding values. When pressing backspace what happens is that when search length reaches threshold value i.e abc it fetches the result and stores it after that no operation is performed hence the search results for abc are persisted. Add (keyup)="onKey($event.target.value)" if value is empty clear the list holding your dropdown data.
As a workaround, I removed [typeaheadMinLength]="3" and instead checked the length on server. If length of prefix token is less than 3 , server doesn't do anything and instead returns empty array. This isn't the optimal solution ofcourse because even for length less than 3, requests will go to the server.
Although, I didn't feel any visible performance impact but still it could be better if done on UI rather than server.

Format input data using YUI 3

Is there a way to apply a mask in a input using yui3 ?
Is it possible to have a field where the user can only enter a phone number?
And if so, how?
Thx a lot
I would say that your best bet is to have an onChange or onKeyup (or even onValuechange - a YUI construct) handler listening on that input. Whenever it detected a change, you would run a formatting function on the current value of the input, which formatted it in the way you wanted.
if you want to be light-handed about it, just put the dashes in where they go, for example :
"1105551212" --> "110-555-1212"
if you want to be heavy-handed about it, the event handler could literally strip out any non-numeric, or non-dash characters, which effectively prevents the user from entering bad input, though they could of course put in a non-existent phone number.
one step further: do both. strip out invalid characters, and do auto-formatting.

Categories