6

Is it possible to have a HTML input on a form that only accepts pasted input?

As part of our registration process, the enduser needs to enter a 20 character identification token into a basic HTML input form. Ideally, the user would simply copy/paste the token into the appropriate field. We don't want to allow the user to manually type this in, as it is likely that they will mistype letters, and we don't have any reliable means to validate the input.

The token comes from desktop software and needs to be pasted into an already opened webpage (i.e. where they download the software from). As such, a clickable link isn't a viable option.

Is there any way to do this, e.g. through Javascript? Thanks.


My solution, adapted from SimplePi's answer:

<html>
<body>
<script type="text/javascript">
 function validate(evt) {
   var theEvent = evt || window.event;
   var key = theEvent.charCode || theEvent.which;

   if(key >= 32 && (theEvent.ctrlKey === undefined || !theEvent.ctrlKey)) {
    if(theEvent.preventDefault) theEvent.preventDefault();
    else theEvent.returnValue = false;
  }
 }
 </script>
  <span>Textbox name</span> <br />
 <input type="text" onkeypress='validate(event)' value=""/>
</body>
</html>

This works in some, but not all browsers. Firefox on Mac is the only offender I've found - firefox in general reports ctrl-v the exact same as v, but on windows the theEvent.ctrlKey member can differentiate between the two. Doing the same on a mac will apparently require keydown/up to check whether or not cmd is pressed. It's doable, but not included in this code, in case anyone else wishes to use this.

DylanStreb
  • 149
  • 2
  • 8
  • 3
    I am pretty sure this is possible BUT this would be a very bad User Experience. Most users would copy/paste token ID anyways so why put extra effort for the very minimum users? – stackErr Feb 06 '14 at 14:45
  • 2
    You would have to allow both keyboard shortcut pasting (which can vary by OS) and right-click context menu pasting. Also, what's to stop them from pasting something entirely different than a token of yours? – ajp15243 Feb 06 '14 at 14:48
  • 1
    Where are they getting the token from? – Matt Burland Feb 06 '14 at 14:48
  • @ajp15243 There's nothing to prevent them from pasting in random text, although we can enforce that the text has to be exactly 20 characters. This is to prevent user error from accidentally mistyping one (or several) letters, which would be indetectable. – DylanStreb Feb 06 '14 at 15:16
  • @stackErr Yes, it might not be the best solution, but I want to see if the option exists. That way we can weigh the pros and cons of having this restriction. Having a user register with an incorrect token will effectively make their account useless and will result in a support call to fix it. – DylanStreb Feb 06 '14 at 15:19
  • 2
    @DylanStreb I'm pretty sure it is possible, but would require quite a lot of investment and testing to make sure it doesn't contain any hidden, gaping holes. Why not just have them enter the key two or three times to ensure that they have not entered it incorrectly? If they're copy/pasting like most people, this will be quick and not error prone. If they are typing unlike most people, the chances of them mistyping it the same way two or three times is astronomically lower than once. – ajp15243 Feb 06 '14 at 15:22
  • @ajp15243 Yes, that's another option I've considered. Again, at this stage I'm just gathering options. I'm not the one making the final call. I just want to be able to present the different possibilities available for addressing this issue. – DylanStreb Feb 06 '14 at 15:55
  • @DylanStreb Understandable. If you have the time for it, you might just quickly prototype something for the input's change/keypress/etc. events and see what kind of keystrokes and values come through for different scenarios (e.g. typing, Ctrl+V/Cmd+V, right-click paste). This could give you a better idea about what's going to be easy/possible. Honestly, though, this option would require a lot more time than something like multiple match-up inputs, and would have diminishing return and potentially poor user experience. – ajp15243 Feb 06 '14 at 16:06
  • @ajp15243 Okay, thanks. I'll see what I can do with those functions. – DylanStreb Feb 06 '14 at 16:18

3 Answers3

6

Here is a more robust solution, I expanded on the code above. There may be a bit of overkill but it works on all browsers. The code below will:

  1. Make the textbox just like readonly but will honor tab index and set focus
  2. Support all clipboard functions win and mac with mouse or keyboard
  3. Allow undo, redo and select all

$( "#your_textbox" ).keypress(function(evt) {
 // Note this could be a bit of overkill but I found some
 // problems in Firefox and decided to go the distance
 // including old windows keyboard short cut keys.
 // Enumerate all supported clipboard, undo and redo keys
 var clipboardKeys = {
  winInsert : 45,
  winDelete : 46,
  SelectAll : 97,
  macCopy : 99,
  macPaste : 118,
  macCut : 120,
  redo : 121, 
  undo : 122
 }
 // Simulate readonly but allow all clipboard, undo and redo action keys
 var charCode = evt.which;
 //alert(charCode);
 // Accept ctrl+v, ctrl+c, ctrl+z, ctrl+insert, shift+insert, shift+del and ctrl+a
 if (
  evt.ctrlKey && charCode == clipboardKeys.redo ||  /* ctrl+y redo   */
  evt.ctrlKey && charCode == clipboardKeys.undo ||  /* ctrl+z undo   */
  evt.ctrlKey && charCode == clipboardKeys.macCut ||  /* ctrl+x mac cut  */
  evt.ctrlKey && charCode == clipboardKeys.macPaste ||  /* ctrl+v mac paste  */
  evt.ctrlKey && charCode == clipboardKeys.macCopy ||  /* ctrl+c mac copy  */ 
  evt.shiftKey && evt.keyCode == clipboardKeys.winInsert || /* shift+ins windows paste */ 
  evt.shiftKey && evt.keyCode == clipboardKeys.winDelete || /* shift+del windows cut */ 
  evt.ctrlKey && evt.keyCode == clipboardKeys.winInsert  || /* ctrl+ins windows copy */ 
  evt.ctrlKey && charCode == clipboardKeys.SelectAll  /* ctrl+a select all  */
  ){ return 0; }
 // Shun all remaining keys simulating readonly textbox
 var theEvent = evt || window.event;
 var key = theEvent.keyCode || theEvent.which;
 key = String.fromCharCode(key);
 var regex = /[]|\./;
 if(!regex.test(key)) {
  theEvent.returnValue = false;
  theEvent.preventDefault();
 }
});
Jim Dandy BOA
  • 533
  • 7
  • 13
5
<script type="text/javascript">
 function validate(evt) {
   var theEvent = evt || window.event;
   var key = theEvent.keyCode || theEvent.which;
   key = String.fromCharCode(key);
  var regex = /[]|\./;
   if(!regex.test(key)) {
    theEvent.returnValue = false;
    if(theEvent.preventDefault) theEvent.preventDefault();
  }
 }
 </script>
  <span>Textbox name</span>
 <input name="ReceiveNo" type="text" class="txtbox" onkeypress='validate(event)' value=""         required tabindex="" />
SimplePi
  • 95
  • 1
  • 4
  • 15
  • This appears to simply restrict the textbox to numbers only, and also forbids any pasting of text. – DylanStreb Feb 06 '14 at 20:44
  • @DylanStreb I fixed the number thing. Pasting works just fine. Checked it on my own server. – SimplePi Feb 06 '14 at 20:51
  • 1
    Simply doing `key != 22` instead of `key = String.fromCharCode(key);` and the regex seems to work, as 22 is the value set to key when pressing ctrl-v. The right-click menu is unaffected. Doing it that way may be the solution, but I'll need to test it more thoroughly. Thanks. – DylanStreb Feb 06 '14 at 22:00
  • Did some more thorough testing and made some changes. I've updated my original post with my modifications, which mostly works. Thank you. – DylanStreb Feb 10 '14 at 18:51
2

Why make them even paste it in? if you are sending the verification token via email then just route them to http://example.com/verify/{{TOKEN}} via email and pickup the rest of the registration process from there.

Tom
  • 33,626
  • 31
  • 85
  • 109
  • 1
    Sorry, updated it with more details: The token is obtained from a desktop application. It's the serial number for a physical device that they need to apply to their user account. – DylanStreb Feb 06 '14 at 15:14