14

in in Input field, if the user presses Backspace or Delete key, is there a way to get the deleted character.

I need to check it against a RegExp.

user160820
  • 14,866
  • 22
  • 67
  • 94
  • You need to check *a character* against a regexp? – mkluwe Jul 06 '10 at 09:54
  • you may attach a *keyup* handler and wait for the backspace character, prevent default action, do the removal yourself but before that you know what is the last character so you can do the regex. – gblazex Jul 06 '10 at 10:19

4 Answers4

9

Assuming the input box has an id 'input'. Here is how with least amount of code you can find out the last character from the input box.

document.getElementById("input").onkeydown = function(evt) {
  const t = evt.target;
  if (evt.keyCode === 8) { // for backspace key
    console.log(t.value[t.selectionStart - 1]);
  } else if (evt.keyCode === 46) { // for delete key
    console.log(t.value[t.selectionStart]);
  }
};
<input id="input" />
Sasha Kondrashov
  • 4,038
  • 1
  • 18
  • 29
Akshay Mittal
  • 101
  • 1
  • 4
8

The following will work in all major browsers for text <input> elements. It shouldn't be used for <textarea> elements because the getInputSelection function doesn't account for line breaks correctly in IE. See this answer for a (longer) function that will do this.

function getInputSelection(input) {
    var start = 0, end = 0;
    input.focus();
    if (    typeof input.selectionStart == "number" &&
            typeof input.selectionEnd == "number") {

        start = input.selectionStart;
        end = input.selectionEnd;
    } else if (document.selection && document.selection.createRange) {
        var range = document.selection.createRange();
        if (range) {
            var inputRange = input.createTextRange();
            var workingRange = inputRange.duplicate();
            var bookmark = range.getBookmark();
            inputRange.moveToBookmark(bookmark);
            workingRange.setEndPoint("EndToEnd", inputRange);
            end = workingRange.text.length;
            workingRange.setEndPoint("EndToStart", inputRange);
            start = workingRange.text.length;
        }
    }
    return {
        start: start,
        end: end,
        length: end - start
    };
}

document.getElementById("aTextBox").onkeydown = function(evt) {
    evt = evt || window.event;
    var keyCode = evt.keyCode;
    var deleteKey = (keyCode == 46), backspaceKey = (keyCode == 8);
    var sel, deletedText, val;
    if (deleteKey || backspaceKey) {
        val = this.value;
        sel = getInputSelection(this);
        if (sel.length) {
            deletedText = val.slice(sel.start, sel.end);
        } else {
            deletedText = val.charAt(deleteKey ? sel.start : sel.start - 1);
        }
        alert("About to be deleted: " + deletedText);
    }
};
Community
  • 1
  • 1
Tim Down
  • 318,141
  • 75
  • 454
  • 536
3

No, there is no variable that stores the deleted char. Unless you have a history for Undo/Redo, but it would be difficult to get the information out of that component.

Easiest would be to compare the contents of the input field before and after delete/backspace have been pressed.

Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
3

You could try something with the caret position:

function getCaretPosition(control){
  var position = {};
  if (control.selectionStart && control.selectionEnd){
    position.start = control.selectionStart;
    position.end = control.selectionEnd;
  } else {
    var range = document.selection.createRange();
    position.start = (range.offsetLeft - 1) / 7;
    position.end = position.start + (range.text.length);
  }

  position.length = position.end - position.start;
  return position;
}

document.getElementById('test').​​​​onkeydown = function(e){
  var selection = getCaretPosition(this);
  var val = this.value;

  if((e.keyCode==8 || e.keyCode==46) && selection.start!==selection.end){
    alert(val.substr(selection.start, selection.length));
  } else if(e.keyCode==8){
    alert(val.substr(selection.start-1, 1));
  } else if(e.keyCode==46){
    alert(val.substr(selection.start, 1));
  }
}​

Tested on Chrome 6. See jsFiddle for an example

Harmen
  • 22,092
  • 4
  • 54
  • 76
  • 1
    Care to explain `(range.offsetLeft - 1) / 7;`? – Tim Down Jul 06 '10 at 10:23
  • Err, I have no idea, I searched for a caret position function on Google – Harmen Jul 06 '10 at 10:27
  • The caret position function is dodgy. Not just for that line, whose purpose is beyond me, but for the test for `control.selectionStart && control.selectionEnd`: this will return false if both are 0, which is not good and will cause errors in non-IE browsers. – Tim Down Jul 06 '10 at 10:45
  • The IE code here seems to be relying on the size of each character being exactly seven pixels, and the edge of the input being at 0 inside the `offsetParent`. This is almost-comically unlikely to hold true. Reading the selection/caret position in IE is frustratingly difficult (see Tim's previous posts!) but this way is a non-starter. – bobince Jul 06 '10 at 10:58
  • There's also a missing line for retrieving the event object in IE in the `keydown` handler. `e = e || window.event;` would do it. – Tim Down Jul 06 '10 at 11:23