9

How do I disable backspace keystroke if anything other than 2 specific input fields are focused on using jquery?

here is my current code (NOW INCLUDING 2 TEXTBOXES):

$(document).keypress(function(e){
  var elid = $(document.activeElement).attr('id');
  if(e.keyCode === 8 && elid != 'textbox1' || elid != 'textbox2'){
      return false;
  };
});

this is not working though....any ideas?

sadmicrowave
  • 39,964
  • 34
  • 108
  • 180

9 Answers9

13

I think this would do the trick:

$(document).keydown(function(e) {
    var elid = $(document.activeElement).hasClass('textInput');
    if (e.keyCode === 8 && !elid) {
        return false;
    };
});

assuming that the textboxes has the class 'textInput'.

Here is a working example

Karl Johan
  • 4,012
  • 1
  • 25
  • 36
  • Event does not fire here for backspace – Giorgio Luparia Dec 20 '12 at 11:51
  • 1
    You are right, the `keypress` doesn't fire on backspace. Iv'e updated to `keydown` and now it works. Thanks for the remark – Karl Johan Dec 20 '12 at 12:22
  • Great, this works. I've changed the condition check to $(document.activeElement).is("input[type=text]") since I'm not using such a class. Might add other types if needed. – Giorgio Luparia Dec 20 '12 at 12:45
  • In my opinion, the answer from @rybo111 is better because then one doesn't need to apply a class on everything, because it doesn't look at :focus but activeElement (which already has focus), and because it includes INPUTs and TEXTAREAs. http://stackoverflow.com/a/17278620/105539 – Volomike Nov 09 '15 at 16:23
  • Backspace doesn't register as a keyboard event on Chrome, but it does on Firefox – Gokhan Demirtas Dec 03 '15 at 09:18
  • @Volomike In the original question the asker wanted to disable backspace in every input field except two. That is why my answer needs a special class, to enable him to choose which inputs that shall accept backspace. – Karl Johan Dec 04 '15 at 12:56
8

This will disable backspace on your site without having to add specific classes to input boxes. To disable backspace except when using input boxes use .is("input:focus") if you want to disable backspace except when using textarea boxes use .is("input:focus, textarea:focus")

$(document).keypress(function(e){ 
    var elid = $(document.activeElement).is("input:focus"); 
    if(e.keyCode === 8 && !elid){ 
       return false; 
    }; 
});
Hudson-Peralta
  • 111
  • 1
  • 3
6

The solution of Hudson-Peralta + QF_Developer is great, but it has one flaw:
If your focus is on a radio button or checkbox the backspace button will still throw you back out of the page. Here is a modification to avoid this gap:

$(document).keydown(function(e){ 
  var elid = $(document.activeElement).is('input[type="text"]:focus, textarea:focus'); 
    if(e.keyCode === 8 && !elid){ 
      return false; 
    }; 
});

EDIT 20130204:
keypress() replaced by keydown()!
The code above now works correctly.

EDIT 20151208:
As mentioned in the comment of @outofmind there are more input types that could throw you back when backspace is pressed. Please add to the comma separated selector list of the is() method any type of input fields that allow direct character input and that are really used in your HTML code, like input[type="password"]:focus, input[type="number"]:focus or input[type="email"]:focus.

Jpsy
  • 20,077
  • 7
  • 118
  • 115
  • You are absolutely correct, Thomas! I have corrected my answer accordingly. In a project where I use the code myself, I also use keydown, but to stay in line with the discussion here I copied and modified existing blocks from this discussion and introduced the error. Sorry. – Jpsy Feb 04 '13 at 08:28
  • Why focus only on INPUT[type="text"] only and not all INPUTs? If it's already the active element, why only search on the :focus items? – Volomike Nov 09 '15 at 16:20
  • 1
    You should also allow `input[type="number"]` and `input[type="password"]` – outofmind Dec 08 '15 at 11:54
  • Fully agree, @outofmind. I have edited the answer. Thanks! – Jpsy Dec 08 '15 at 16:26
5

I think a slight modification is needed to handle textareas:

var elid = $(document.activeElement).is("input:focus, textarea:focus"); 
QFDev
  • 8,668
  • 14
  • 58
  • 85
4

I made a slight change to the accepted answer, which may be of use to someone:

$(document).keydown(function(e) {
    var elid = $(document.activeElement).is("input, textarea") ;
    if (e.keyCode === 8 && !elid) {
        if(e.ctrlKey) {
            window.history.back()
        }
        else {
            alert("Navigating with Backspace has been disabled. Use CTRL + Backspace if you want to go back to the previous page (and lose any unsaved changes).");
            return false;
        }
    }
});

With this method, the user can still navigate using Backspace by holding CTRL, but also it takes into account textarea as well as any input.

Of course, the alternative is to use something like this instead, which doesn't allow the user to leave the page if they've inputted anything.

Community
  • 1
  • 1
rybo111
  • 12,240
  • 4
  • 61
  • 70
  • 1
    This should have been selected as the best answer because it is the most complete. Thank you for this -- I used it successfully today with QWebView widget in a Qt/C++ application. – Volomike Nov 09 '15 at 16:15
2

@Nick Craver, disgraceful answer for a couple of reasons. Answer the question or at least patronize thoughtfully.

Here is a prototype based solution I ended up using for my forms because users complained that backspace would take them away from the form (which is such an obviously counterintuitive thing to do, one wonders why all browsers use the backspace key as back button).




        // event handlers must be attached after the DOM is completely loaded
        Event.observe(window, 'load', function() {
          // keypress won't fire for backspace so we observe 'keydown'
          Event.observe(window, 'keydown', function(event){
            // 8 == backspace
            if( event.keyCode == 8) {
                // with no field focused, the target will be HTMLBodyElement
               if( event.target == document.body) {
                  // stop this event from propagating further which prevents                      
                  // the browser from doing the 'back' action
                  event.stop();
               }
             }
          });
        });

Wulf
  • 393
  • 2
  • 10
  • Looks awesome, but doesn't run on Chrome because it doesn't have Event.observe. I also stuck it inside $(document).ready(function(){ ...stuck here... } because you said "must be attached after the DOM is completely loaded". – Volomike Nov 09 '15 at 16:08
  • @Volomike Sorry, I should've made it more clear that this is a solution based on the prototype javascript framework (http://prototypejs.org/). It's similar to jquery, just worse. – Wulf Dec 02 '15 at 13:05
2

Hudson-Peralta's answer worked good for me but I did a small modification since I use many keydown events:

$(document).keydown(function(e){ 
            var elid = $(document.activeElement).is("input:focus"); 
            if(e.keyCode === 8 && !elid){ 
               e.preventDefault(); 
            }; 
        });
Peter O.
  • 32,158
  • 14
  • 82
  • 96
Cobol
  • 53
  • 2
  • 9
0

I too have worked hard on the same. Finally, I found the answer and for everybody's convenience I've placed the solution on http://blog.totusinfo.com/jquery-disable-backspace-for-document-history-except-inputs-and-textarea/

Raju Sarvasiddi
  • 411
  • 1
  • 4
  • 7
0

I modified the answer a little bit more to combine everyone's good answer
1. used selector "input[type=text]:focus, textarea: focus" to maintain default behavior for these elements, and as JPsy said, to prevent default behavior on inputs like checkbox
2. used e.target instead to make the code depends more exclusively on JQuery, since I'm not sure if every browser support document.activeElement well

EDIT
3. Include password field also by adding "input[type=password]:focus",

     $(document).keydown(function(e){

          var code=e.keyCode;
          var is_to_stop= (!$(e.target).is("input[type=text]:focus, input[type=password]:focus, textarea:focus")) && (code==8);
          if(is_to_stop){
            return false;
          }

    });

JK ABC
  • 576
  • 5
  • 12