20

I have this right now:

<input type="text" placeholder="Paste text" onPaste="alert(this.value);">

This does infact work, except, it returns a blank alert window. I don't get any value. Help?

Jake
  • 1,399
  • 3
  • 16
  • 39

2 Answers2

45

The onpaste event fires before the input's value is changed. You need something such as a setTimeout:

<input type="text" placeholder="Paste text" onPaste="var e=this; setTimeout(function(){alert(e.value);}, 4);">​

I'm storing a reference to this inside a global var as this is not accessible inside the scope of a timeout function which is attached to the window object.

I'm using 4 miliseconds as the Timeout as it's the minimum valid Interval/Timeout in the HTML5 specification. Edit: As noted in the comments, you may also use 0 miliseconds as timeOut which is automatically recalculated to 4. jsPerf tests.

Fiddle

You may as well use a function call inside your onpaste event passing this as a parameter to prevent your HTML mixing with JS too much. :)

And here's a function easier to read and which you can use in multiple inputs:

function pasted(element) {
    setTimeout(function(){
        alert(element.value);
    }, 0); //or 4
}​

Which can be called with simply onPaste="pasted(this)" for any input.

Fiddle

Fabrício Matté
  • 65,581
  • 23
  • 120
  • 159
  • 3
    @DmitryScriptin Yes it can, but in the HTML5 specification it will be interpreted as 4 even if you set it to 0 (there are some test cases in jsperf to prove that), so I used a valid number to prevent re-calculations. :) – Fabrício Matté Jun 10 '12 at 22:55
  • 2
    I prefer "0" for a "queued event", as then I don't have to guess what the *intent* is (that and it makes for consistent code) although just *omitting* the value should also suffice. There will **no** performance impact for a "re-calculation". –  Jun 10 '12 at 22:59
  • @pst Both will be interpreted at the same time, I guess it's more of a programmer preference. I'll add it on my next edit. :) – Fabrício Matté Jun 10 '12 at 23:02
  • @FabrícioMatté It is. As long as the reason for such choices are stated ... at least there is reasoning occurring, differences aside ;-) –  Jun 10 '12 at 23:03
  • @FabrícioMatté I updated the post with `var` to avoid clobbering `window.e`. (Global properties are never closed-over, but can appear to give that effect until a re-entrant situation is encountered...) –  Jun 10 '12 at 23:06
  • 1
    Thank you @pst, I'm not very fan of inline JS inside HTML, hence I updated with a new function as well. =] – Fabrício Matté Jun 10 '12 at 23:07
9

This is because the onpaste event fires before the content gets pasted into the element (link) so it's not there yet at the time you handle it.

Modern browsers support methods of obtaining clipboard data inside the event handler. Refer to JavaScript get clipboard data on paste event (Cross browser) for cross-browser solution attempts.

Also, you can always work around your issue by simply starting a timer in the event handler function (10ms should be enough) that would check your input value later.

Community
  • 1
  • 1
Dmitry Pashkevich
  • 12,206
  • 9
  • 49
  • 68