views:

61

answers:

2

Hey there,

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, "-"); }); 
        });
+3  A: 

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
what do `i` and `v` stand for?
quakkels
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
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
@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
@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
@quakkels - You can copy/paste, why is it everyone forgets this when designing validation?
Nick Craver
@Nick - That's right, thanks! I always forget about copy / paste. Yes, a dual approach would probably be the slickest.
Peter Ajtai
@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
Thanks for the great advice!
quakkels
@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
@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
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
+5  A: 

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

CD Sanchez
While this does answer the immediate question, it doesn't solve the problem, for example I can paste a space in there and keep going.
Nick Craver