tags:

views:

354

answers:

3

Hi everyone,

I have a form where a check an input field for its value and then i do an Ajax call using the typewatch plugin ( a small little thing which detects that the user has stopped typing after a predefined interval ). It works great.

As this field is a "coupon discount" in an order form, the value could be entered by copy pasting the "coupon code" from an email or something. It also works with Ctrl+C - Ctrl+V for Copy and paste but not when a user selects the text with the mouse, clicks copy from the context menu and then paste from this menu.

Is there a way in jQuery to check for this kind of behaviour in jQuery somehow?

+1  A: 

You could set a low time out (1 second) that checks is the value has changed since the last check.

You could also simply ignore it and when the form submits grab the contents of this coupon discount input and process it.

Josh K
A: 

I have had a similar issue before. As far as I know, the browser issues no events when the user pastes via right click, nor when they select from the list of previously used values.

I ended up solving it in a good enough way by additionally binding my event handler to the blur event. The only case this didn't catch was when they paste a value with the mouse, then hit the Enter key to submit. I was able to get around this through a little hackery:

$(element)
  .bind('keydown blur', handlerFunction)
  .keydown(function(event) {
    if (event.keyCode === 13 /* Enter Key */) {
      event.preventDefault();
      event.stopPropagation();
    }
  })
  .keyup(function(event) {
    if (event.keyCode === 13 /* Enter Key */) {
      $(this).closest('form').submit();
    }
  });

Essentially, this works because jQuery will execute the events in the order they were bound. Normally, form submission takes place on the keydown of an Enter keypress. In order to give the keyup handler time to do its magic, you need to delay that form submission until the keyup event happens, so the other keyup handler can run first.

Now, you said that you were using a plugin that adds a delay before reacting to the users event. That means you may not be able to use this technique verbatim. One thing that might work instead would be to call the handler function directly before allowing the form to submit. To do that, you would change the last keyup handler to:

  .keyup(function(event) { // Part 2
    if (event.keyCode === 13 /* Enter Key */) {

      handlerFunction.call(this, event); // force it to happen now

      $(this).closest('form').submit();
    }
  });

As Josh K mentioned before, you could simply bind something to the submit event on your form to do something similar. If you are doing Ajax there, though, be sure to set async: false in the passed options, because otherwise the form will go ahead and submit without waiting for the call to complete.

Kent
A: 

(this solution has not been tested, but!) I'd try something like this:

var keys_pressed = 0; // count the number of key press events
var required_keys_pressed = 10;
$('#yourinputElement').keydown ( function () {
  keys_pressed++; // add one
}); 
$('#yourform').submit (function () {
  if (keys_pressed < required_keys_pressed)
  {
     // not enough keys pressed or was a CTRL + v
  }
  else
  {
     // required number of keys pressed for your code
  }
});

Remember though people can always bypass this with browser plugins, so it's not a guarantee that things have gone the way you want them to. You should ALWAYS perform some kind of server-side validation too

slightlymore