0

I just realized that inside a form event handler (like onsubmit or oninput etc), you can access control values globally, meaning the following does indeed work:

<form onsubmit="alert(theInput.value); return false">
  <input name="theInput">
</form>

Why does this work? I never defined theInput anywhere and it is also not a global variable.

Assuming that the internal browser code assigns those variables itself, why cant I access theInput in a custom event handler?

function submitHandler() {
  alert(theInput.value)
}
<form onsubmit="submitHandler(); return false">
  <input name="theInput">
</form>

In submitHandler(), theInput is undefined and the code breaks, as I expected.

Is there any documentation available about this? Could not find any, but it is admittedly something hard to search for. MDN docs even use this syntax in one of their examples.

phil294
  • 10,038
  • 8
  • 65
  • 98
  • 1
    "onfoo" event handler functions are constructed as if they were in a series of `with` statements. It's primitive and weird and prone to all sorts of bizarre and confusing bugs, and that's a primary reason people recommend never using that method of attaching event handlers. – Pointy Jul 15 '19 at 22:47

2 Answers2

3

Inline handlers (unintuitively) appear to run inside a with(this), where this is the element that the handler is on:

<form onsubmit="debugger; console.log(theInput.value); return false">
  <input name="theInput">
  <button>submit</button>
</form>

enter image description here

The document is also withed as well.

From a <form>, you can access an input with a particular name via dot notation, so referencing theInput.value works just like referencing this.theInput.value in the inline handler.

Solution: Never use inline handlers, they're crazy.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Thanks, makes sense. Unfortunately, Firefox doesnt display `with block`s in its dev tools, but I believe you. :P – phil294 Jul 15 '19 at 22:58
  • @Blauhirn yes it's really confusing and as you have discovered not at all obvious what's going on. It seemed like a really cool idea in 1998 probably. – Pointy Jul 15 '19 at 23:07
0

It seems that the browser is assigning theInput behind the scenes. The reason it's not working in your second case is because you're looking for theInput in the scope of the submitHandler function, not the scope of the actual event handler. It works if you pass theInput into submitHandler in your HTML onsubmit, even if you change the variable name in submitHandler.

function submitHandler(input) {
  alert(input.value)
}
<form onsubmit="submitHandler(theInput); return false">
  <input name="theInput">
</form>

Furthermore, it fails if you change submitHandler(theInput) to something else, see below:

function submitHandler(input) {
  alert(input.value)
}
<form onsubmit="submitHandler(myInput); return false">
  <input name="theInput">
</form>
ldtcoop
  • 680
  • 4
  • 14