Created
February 5, 2018 05:24
-
-
Save watzon/bc13b34065fbedeb1346a750163246b6 to your computer and use it in GitHub Desktop.
Simple input buffer implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const KeyCodeMap = { | |
backspace: 8, | |
tab: 9, | |
return: 13, | |
left_arrow: 37, | |
up_arrow: 38, | |
right_arrow: 39, | |
down_arrow: 40, | |
insert: 45, | |
delete: 46 | |
} | |
class InputBuffer { | |
constructor (element, startingValue) { | |
this.element = document.getElementById(element) | |
this.caret = 0 | |
if (startingValue) { | |
} else { | |
if (this.element.value) { | |
this.buffer = this.element.value.split('') | |
} else { | |
this.buffer = [] | |
} | |
} | |
this.element.value = this.buffer.join('') | |
this.element.onkeydown = this.keyDown.bind(this) | |
this.element.onpointerup = this.pointerUp.bind(this) | |
this.update() | |
} | |
pointerUp (event) { | |
this.caret = this.element.selectionStart | |
this.update() | |
} | |
// This is what you want to pass into the onkeydown event | |
keyDown (event) { | |
switch (event.keyCode) { | |
case KeyCodeMap.backspace: // Backspace | |
this.handleBackspace(event) | |
break | |
case KeyCodeMap.tab: | |
this.handleTab(event) | |
break | |
case KeyCodeMap.return: | |
this.handleReturn(event) | |
break | |
case KeyCodeMap.left_arrow: | |
this.handleArrow(event, 'left') | |
break | |
case KeyCodeMap.right_arrow: | |
this.handleArrow(event, 'right') | |
break | |
case KeyCodeMap.up_arrow: | |
this.handleArrow(event, 'up') | |
break | |
case KeyCodeMap.down_arrow: | |
this.handleArrow(event, 'down') | |
break | |
case KeyCodeMap.insert: | |
this.handleInsert(event) | |
break | |
case KeyCodeMap.delete: | |
this.handleDelete(event) | |
break | |
default: | |
this.handleCharacter(event) | |
break | |
} | |
this.update(event) | |
} | |
update () { | |
this.updateValue() | |
this._setCaretPosition(this.caret) | |
} | |
updateValue () { | |
this.element.value = this.buffer.join('') | |
} | |
handleBackspace (event) { | |
event.preventDefault() | |
if (this.caret === 0) return | |
this.buffer.splice(this.caret - 1, 1) | |
this.caret-- | |
} | |
handleTab (event) {} | |
handleReturn (event) {} | |
handleArrow (event, direction) { | |
event.preventDefault() | |
switch (direction) { | |
case 'left': | |
if (this.caret !== 0) | |
this.caret-- | |
break | |
case 'right': | |
if (this.caret !== this.buffer.length) | |
this.caret++ | |
break | |
} | |
} | |
handleInsert (event) {} | |
handleDelete (event) { | |
event.preventDefault() | |
this.buffer.splice(this.caret, 1) | |
} | |
handleCharacter (event) { | |
event.preventDefault() | |
if (this._isCharacter(event)) { | |
this.buffer.splice(this.caret, 0, event.key) | |
this.caret++ | |
} | |
} | |
// TODO: Make this ignore function keys | |
_isCharacter (event) { | |
const key = String.fromCharCode(event.keyCode || event.charCode) | |
return key.match(/[\w\s\d]/) | |
} | |
_setCaretPosition (position) { | |
const elem = this.element | |
if(elem.createTextRange) { | |
var range = elem.createTextRange(); | |
range.move('character', position); | |
range.select(); | |
} | |
else { | |
if(elem.selectionStart) { | |
elem.focus(); | |
elem.setSelectionRange(position, position); | |
} | |
else | |
elem.focus(); | |
} | |
} | |
} | |
class PasswordMask extends InputBuffer { | |
constructor (element, maskChar = '*') { | |
super(element, '') | |
this.maskChar = maskChar | |
} | |
updateValue () { | |
this.element.value = new Array(this.buffer.length).fill('*').join('') | |
} | |
} | |
// Create a PasswordMask for an element with the id of test | |
// <input type="text" id="test"> | |
const mask = new PasswordMask('test') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment