tags:

views:

64

answers:

3

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.

+2  A: 

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_D
+1  A: 

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
Care to explain `(range.offsetLeft - 1) / 7;`?
Tim Down
Err, I have no idea, I searched for a caret position function on Google
Harmen
Tim Down
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
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
gotta love undocumented pieces of code
Luca Matteis
+2  A: 

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);
    }
};
Tim Down