Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery using event.preventDefault() with on('input')

I'm catching paste events with $('selector').on('input', function(event) { ... });

Then I'm trying to test what's been pasted and if it doesn't pass validation, cancel the paste with event.preventDefault(). Unfortunately, by the time the listener function is executed, the text has already been pasted and event.preventDefault() does nothing.

So what's a good way to catch paste events, and if what's been pasted doesn't validate, undo/prevent the paste?

I know I can use .on('paste', function(event) { ... }), but that doesn't give me the text that's been pasted or the contents of the input element after the paste, unless I use setTimeout() with some minute wait time, and I'd like to avoid using setTimeout().

like image 867
Val Schuman Avatar asked Mar 03 '13 03:03

Val Schuman


People also ask

What is event preventDefault () in jQuery?

The event. preventDefault() method stops the default action of an element from happening. For example: Prevent a submit button from submitting a form. Prevent a link from following the URL.

What is the use of event preventDefault ()?

The preventDefault() method cancels the event if it is cancelable, meaning that the default action that belongs to the event will not occur. For example, this can be useful when: Clicking on a "Submit" button, prevent it from submitting a form. Clicking on a link, prevent the link from following the URL.

What's the difference between event preventDefault () and event stopPropagation () methods?

preventDefault() prevents the default browser behavior for a given element. stopPropagation() stops an event from bubbling or propagating up the DOM tree.


1 Answers

First of all some background on event trigger order for the input element:

keydown -> keypress -> paste -> input -> keyup -> change

Whenever you call preventDefault it stops the chains, like nothing happened.

So my suggestion is to catch the paste event, prevent its default behavior and do your logic there.

I know I can use .on('paste', function(event) { ... }), but that doesn't give me the text that's been pasted or the contents of the input element after the paste

Actually you can retrieve the content of the clipboard. See this doc. Support is all major browser (but only IE11+). I do not know if by the time of the writing of the question this functionality was available or not.

Fiddle example

$('#myInput').on('paste', function(e) {
    // Cancel the event - this prevents the text from being entered into the input and stops the event chain
    e.preventDefault();

    // Get the content of the clipboard
    let paste = (event.clipboardData || window.clipboardData).getData('text');

    // Validate what it is pasted       
    if (paste == "text to paste") {
        // If condition is satisfied manually set the value of the input
        $(this)
            .val(paste)
            // Manually trigger events if you want
            .trigger('input')
            .trigger('change');
    }
});

Notes on the code:

  • This solution does not include setTimeout. Whenever you make it with setTimeout you see for a very short time the text being pasted, like a blinking effect.
  • If text meets condition I manually set it in the input. However this does not trigger input and change events. If you need them, just manually trigger them
  • Similar approach is to first check the text and if it does not meet requirements then call preventDefault, otherwise do nothing. This way you avoid manually setting value in the input and triggering events afterward.
like image 172
antanta Avatar answered Oct 22 '22 20:10

antanta