From d1100cef92bafac403b21a8c4043d74ea24bf818 Mon Sep 17 00:00:00 2001 From: Francisco Hodge Date: Mon, 5 Nov 2018 17:34:16 -0500 Subject: [PATCH] Fixing caret issue when using maxLength --- src/lib/components/Keyboard.js | 8 +++- src/lib/services/Utilities.js | 58 ++++++++++++++---------- src/lib/services/tests/Utilities.test.js | 24 +++++++--- 3 files changed, 57 insertions(+), 33 deletions(-) diff --git a/src/lib/components/Keyboard.js b/src/lib/components/Keyboard.js index f3b60013..f63fa686 100644 --- a/src/lib/components/Keyboard.js +++ b/src/lib/components/Keyboard.js @@ -173,7 +173,9 @@ class SimpleKeyboard { if(!this.input[this.options.inputName]) this.input[this.options.inputName] = ''; - let updatedInput = this.utilities.getUpdatedInput(button, this.input[this.options.inputName], this.options, this.caretPosition); + let updatedInput = this.utilities.getUpdatedInput( + button, this.input[this.options.inputName], this.options, this.caretPosition + ); if(this.input[this.options.inputName] !== updatedInput){ @@ -184,7 +186,9 @@ class SimpleKeyboard { return false; } - this.input[this.options.inputName] = updatedInput; + this.input[this.options.inputName] = this.utilities.getUpdatedInput( + button, this.input[this.options.inputName], this.options, this.caretPosition, true + ); if(debug) console.log('Input changed:', this.input); diff --git a/src/lib/services/Utilities.js b/src/lib/services/Utilities.js index b05a17cf..d49a517d 100644 --- a/src/lib/services/Utilities.js +++ b/src/lib/services/Utilities.js @@ -131,48 +131,51 @@ class Utilities { * @param {string} input The input string * @param {object} options The simple-keyboard options object * @param {number} caretPos The cursor's current position + * @param {boolean} moveCaret Whether to update simple-keyboard's cursor */ - getUpdatedInput(button, input, options, caretPos){ + getUpdatedInput(button, input, options, caretPos, moveCaret){ let output = input; if((button === "{bksp}" || button === "{backspace}") && output.length > 0){ - output = this.removeAt(output, caretPos); + output = this.removeAt(output, caretPos, moveCaret); } else if(button === "{space}") - output = this.addStringAt(output, " ", caretPos); + output = this.addStringAt(output, " ", caretPos, moveCaret); else if(button === "{tab}" && !(typeof options.tabCharOnTab === "boolean" && options.tabCharOnTab === false)){ - output = this.addStringAt(output, "\t", caretPos); + output = this.addStringAt(output, "\t", caretPos, moveCaret); } else if((button === "{enter}" || button === "{numpadenter}") && options.newLineOnEnter) - output = this.addStringAt(output, "\n", caretPos); + output = this.addStringAt(output, "\n", caretPos, moveCaret); else if(button.includes("numpad") && Number.isInteger(Number(button[button.length - 2]))){ output = this.addStringAt(output, button[button.length - 2], caretPos); } else if(button === "{numpaddivide}") - output = this.addStringAt(output, '/', caretPos); + output = this.addStringAt(output, '/', caretPos, moveCaret); else if(button === "{numpadmultiply}") - output = this.addStringAt(output, '*', caretPos); + output = this.addStringAt(output, '*', caretPos, moveCaret); + else if(button === "{numpadsubtract}") - output = this.addStringAt(output, '-', caretPos); + output = this.addStringAt(output, '-', caretPos, moveCaret); else if(button === "{numpadadd}") - output = this.addStringAt(output, '+', caretPos); + output = this.addStringAt(output, '+', caretPos, moveCaret); else if(button === "{numpaddecimal}") - output = this.addStringAt(output, '.', caretPos); + output = this.addStringAt(output, '.', caretPos, moveCaret); else if(button === "{" || button === "}") - output = this.addStringAt(output, button, caretPos); + output = this.addStringAt(output, button, caretPos, moveCaret); else if(!button.includes("{") && !button.includes("}")) - output = this.addStringAt(output, button, caretPos); + output = this.addStringAt(output, button, caretPos, moveCaret); return output; } + /** * Moves the cursor position by a given amount * @@ -182,7 +185,7 @@ class Utilities { updateCaretPos(length, minus){ if(minus){ if(this.simpleKeyboardInstance.caretPosition > 0) - this.simpleKeyboardInstance.caretPosition = this.simpleKeyboardInstance.caretPosition - length + this.simpleKeyboardInstance.caretPosition = this.simpleKeyboardInstance.caretPosition - length; } else { this.simpleKeyboardInstance.caretPosition = this.simpleKeyboardInstance.caretPosition + length; } @@ -194,14 +197,11 @@ class Utilities { * @param {string} source The source input * @param {string} string The string to add * @param {number} position The (cursor) position where the string should be added + * @param {boolean} moveCaret Whether to update simple-keyboard's cursor */ - addStringAt(source, string, position){ + addStringAt(source, string, position, moveCaret){ let output; - if(this.simpleKeyboardInstance.options.debug){ - console.log("Caret at:", position); - } - if(!position && position !== 0){ output = source + string; } else { @@ -211,11 +211,15 @@ class Utilities { * Avoid caret position change when maxLength is set */ if(!this.isMaxLengthReached()){ - this.updateCaretPos(string.length); + if(moveCaret) this.updateCaretPos(string.length); } } + if(this.simpleKeyboardInstance.options.debug && moveCaret){ + console.log("Caret at:", position); + } + return output; } @@ -224,8 +228,9 @@ class Utilities { * * @param {string} source The source input * @param {number} position The (cursor) position from where the characters should be removed + * @param {boolean} moveCaret Whether to update simple-keyboard's cursor */ - removeAt(source, position){ + removeAt(source, position, moveCaret){ if(this.simpleKeyboardInstance.caretPosition === 0){ return source; } @@ -245,10 +250,10 @@ class Utilities { if(emojiMatched){ output = source.substr(0, (position - 2)) + source.substr(position); - this.updateCaretPos(2, true); + if(moveCaret) this.updateCaretPos(2, true); } else { output = source.substr(0, (position - 1)) + source.substr(position); - this.updateCaretPos(1, true); + if(moveCaret) this.updateCaretPos(1, true); } } else { prevTwoChars = source.slice(-2); @@ -256,13 +261,17 @@ class Utilities { if(emojiMatched){ output = source.slice(0, -2); - this.updateCaretPos(2, true); + if(moveCaret) this.updateCaretPos(2, true); } else { output = source.slice(0, -1); - this.updateCaretPos(1, true); + if(moveCaret) this.updateCaretPos(1, true); } } + if(this.simpleKeyboardInstance.options.debug && moveCaret){ + console.log("Caret at:", this.simpleKeyboardInstance.caretPosition); + } + return output; } /** @@ -277,7 +286,6 @@ class Utilities { let currentInput = inputObj[options.inputName]; let condition = currentInput.length === maxLength; - if( /** * If pressing this button won't add more characters diff --git a/src/lib/services/tests/Utilities.test.js b/src/lib/services/tests/Utilities.test.js index a4d45b86..38c0f1ea 100644 --- a/src/lib/services/tests/Utilities.test.js +++ b/src/lib/services/tests/Utilities.test.js @@ -416,11 +416,14 @@ it('Keyboard removeAt will exit out on caretPosition:0', () => { let keyboard = new Keyboard(); keyboard.setInput("test"); - keyboard.caretPosition = 0; keyboard.utilities.removeAt(keyboard.getInput(), 0); - expect(keyboard.getInput()).toBe("test"); + + keyboard.setInput("test"); + keyboard.caretPosition = 5; + keyboard.utilities.removeAt(keyboard.getInput(), 0, true); + expect(keyboard.caretPosition).toBe(4); }); it('Keyboard removeAt will remove multi-byte unicodes with caretPos>0', () => { @@ -430,27 +433,36 @@ it('Keyboard removeAt will remove multi-byte unicodes with caretPos>0', () => { keyboard.caretPosition = 6; let output = keyboard.utilities.removeAt("test\uD83D\uDE00", 6); - expect(output).toBe("test"); + + keyboard.caretPosition = 6; + output = keyboard.utilities.removeAt("test\uD83D\uDE00", 6, true); + expect(keyboard.caretPosition).toBe(4); }); it('Keyboard removeAt will not remove multi-byte unicodes with caretPos:0', () => { testUtil.setDOM(); let keyboard = new Keyboard(); - let output = keyboard.utilities.removeAt("\uD83D\uDE00"); + expect(output).toBeFalsy(); + output = keyboard.utilities.removeAt("\uD83D\uDE00", 0, true); expect(output).toBeFalsy(); }); it('Keyboard removeAt will remove regular strings', () => { testUtil.setDOM(); - let keyboard = new Keyboard(); + let keyboard = new Keyboard({ + debug: true + }); keyboard.caretPosition = 6; let output = keyboard.utilities.removeAt("testie", 6); - expect(output).toBe("testi"); + + keyboard.caretPosition = 6; + output = keyboard.utilities.removeAt("testie", 6, true); + expect(keyboard.caretPosition).toBe(5); }); \ No newline at end of file