15

I thought it would be a simple thing to hijack the space key when in a form input so that it would function like a hyphen. Generally jQuery makes stuff like this really simple.

The code I tried is this:

        $("#StreamUrl").keydown(function (e) {
            if (e.keyCode == 32) return 109;
        });

But this has no effect whatsoever. I tried a more simple script:

        $("#StreamUrl").keydown(function (e) {
            //if (e.keyCode == 32) return 109;
            alert(e.keyCode);
        });

This script correctly alerts 32 on space press and 109 on hyphen press. Also, I have no JavaScript errors.

Why wouldn't if (e.keyCode == 32) return 109; work? When I replace that line with if (e.keyCode == 32) alert("space!!"); I get the alert correctly, so I know the if is returning true correctly.

What gives?

Edit - Solution

Thanks to @Nick for pointing out the copy-paste issue. I ended up with a little bit of a hybrid. Here's the code that I have gotten to work which is both smooth and handles Copy/Paste.

        $("#StreamUrl").keydown(function (e) {
            if (e.keyCode == 32) {
                $(this).val($(this).val() + "-"); // append '-' to input
                return false; // return false to prevent space from being added
            }
        }).change(function (e) {
            $(this).val(function (i, v) { return v.replace(/ /g, "-"); }); 
        });
quakkels
  • 11,676
  • 24
  • 92
  • 149
  • 2
    Your code works ok, except for the following case: If the user moves the caret by using the arrow keys, and then types space, the hyphen is added to the end of the field instead of being inserted at the caret position. – Sorin Postelnicu Oct 26 '12 at 10:34
  • This solution can be improved by using some tricks from here: http://stackoverflow.com/questions/4085312/jquery-get-the-cursor-position-of-text-in-input-without-browser-specific-code/ – Sorin Postelnicu Oct 26 '12 at 10:45

2 Answers2

21

The problem is that return 109 doesn't do what you want it to do. In an event handler, you return true or false depending on whether or not you want the browser to execute the default action. In keydown, you would return false to prevent the character from being inserted.

$("#StreamUrl").keydown(function (e) {
     if (e.keyCode == 32) { 
       $(this).val($(this).val() + "-"); // append '-' to input
       return false; // return false to prevent space from being added
     }
});

jsfiddle example

Cristian Sanchez
  • 31,171
  • 11
  • 57
  • 63
11

You usually want the keyup event instead here, which fires after the space has been added, something like this is a bit easier:

$("#StreamUrl").bind("keyup change", function () {
  $(this).val(function(i, v) { return v.replace(/ /g,"-"); });
});

Try it out here, what this does is allow the space to be added, but then instantly does a replace of spaces for hyphens by passing a function to .val(). For older versions of jQuery, it'd look like this:

$("#StreamUrl").bind("keyup change", function () {
  $(this).val($(this).val().replace(/ /g,"-"));
});

This works even for people pasting content, an easy way to get around keydown validation.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • what do `i` and `v` stand for? – quakkels Oct 04 '10 at 21:26
  • What's the advantage of `keyup` over `keydown`? Daniel's code works nicely (at least in Chrome), even if you keep the space depressed, and it isn't as visually jarring as suddenly have spaces replaced with dashes (esp. after the space is depressed for a long period of time). – Peter Ajtai Oct 04 '10 at 21:28
  • Thank you for the code.. but I do prefer Daniels code because the space character is never even executed... thus the split second it takes for the replace function to complete is avoided and the cursor doesn't jump around. – quakkels Oct 04 '10 at 21:30
  • @Peter - You can paste spaces for example, and the approach in the other answer will never fix this, some method of *replacing* the spaces will, I'd recommend binding to both `keyup` and `change` actually. @quakkels - Keep in mind your accepted answer won't do anything for that either. – Nick Craver Oct 04 '10 at 21:34
  • @Nick - Won't do anything for replacing spaces? If spaces aren't entered in the first place, there wouldn't be any spaces to replace. – quakkels Oct 04 '10 at 21:39
  • 1
    @quakkels - You can copy/paste, why is it everyone forgets this when designing validation? – Nick Craver Oct 04 '10 at 21:39
  • @Nick - That's right, thanks! I always forget about copy / paste. Yes, a dual approach would probably be the slickest. – Peter Ajtai Oct 04 '10 at 21:40
  • @Nick - I do see the point about copy-paste. However, I do like the smooth-ness of Daniel's solution so the nod still has to go to him. But I will likely implement an additional function to replace spaces on blur or keyup. – quakkels Oct 04 '10 at 21:41
  • 1
    @quakkels - I think your priorities as a UI designer are a bit backwards but whatever works. I wouldn't *ever* expect a user to lay on the spacebar for entering a URL, and *if* they did it would be very, *very* rare and it'd still work, but if you prefer a lot more code to reach the same goal, so be it. Functionality, *then* appearances, **always**. My problem is more of an accepted answer not accounting for the *very* common copy/paste case being accepted and the *next* person using it blindly, it makes this question/answer a very bad resource. – Nick Craver Oct 04 '10 at 21:45
  • @Nick - I think people forget about copy / paste because of the wording of these types of questions: `prevent the space key from entering a space` - `ctr-v` is not in that verbiage. A mindset issue I guess. – Peter Ajtai Oct 04 '10 at 21:49
  • Yes, I agree that @Nick's answer had more complete functionality in his approach. If I could mark both answers as correct I would. Function is priority over appearance, but appearance MUST be a priority for those who may repeatedly use an application. I don't mind that I have "extra" code in my implemented solution so the input is smooth because I want to avoid any possible irritation that a user may experience form a cursor bouncing as they type. A higher quality user experience does take more work. – quakkels Oct 04 '10 at 21:55
  • This is really neat! I didn't realize that would work with pasted content too. I had a special case where I needed an A as first character and then only numbers, but with allowing left arrow I could go to the left and just enter another a and another one, so that the pattern I was trying to force (A followed by 8 numbers) could be broken. Due to good html5 pattern it wasn't still couldn't be submitted, but maybe with replacing on keydown with keyup can fix that problem too. – Julix Oct 14 '16 at 02:35