Form submission in Firefox

  • Thread starter Stuart Perryman
  • Start date
S

Stuart Perryman

Hi,

I have the following code which works just fine in IE6 but not in
Firefox.
It is an extract of several table rows each with an individual form.
It is generated by php.

<form action="MaintNotification.php?ReqID=5" method="post"
name="frm5">
<tr align="left" bgcolor="#dddddd" class="text" onClick="submit()"
onMouseOver="show(event,'titleinfo');this.style.backgroundColor='#CCFFCC';"
onMouseOut="hide('titleinfo');this.style.backgroundColor='#dddddd';">
<td>
<input name="fromStatus" type="hidden" value="true">
Database Population
</td>
<td>2005-04-25 00:33:00</td>
<td>2005-04-25 01:33:00</td>
<td>Pending</td>
<td></td>
</tr>
</form>

If I just use onClick="submit()" FF tels me submit is not defined
If I use document.frm5.submit I am told it is not a function

What do I need to do to get the form submitted when someone clicks on
the table row?

Thanks in advance

Stuart
 
L

Lee

Stuart Perryman said:
Hi,

I have the following code which works just fine in IE6 but not in
Firefox.
It is an extract of several table rows each with an individual form.
It is generated by php.

<form action="MaintNotification.php?ReqID=5" method="post"
name="frm5">
<tr align="left" bgcolor="#dddddd" class="text" onClick="submit()"
onMouseOver="show(event,'titleinfo');this.style.backgroundColor='#CCFFCC';"
onMouseOut="hide('titleinfo');this.style.backgroundColor='#dddddd';">
<td>
<input name="fromStatus" type="hidden" value="true">
Database Population
</td>
<td>2005-04-25 00:33:00</td>
<td>2005-04-25 01:33:00</td>
<td>Pending</td>
<td></td>
</tr>
</form>

If I just use onClick="submit()" FF tels me submit is not defined
If I use document.frm5.submit I am told it is not a function

What do I need to do to get the form submitted when someone clicks on
the table row?

Thanks in advance

This test case works for me:

<html>
<body>
<table>
<form action="MaintNotification.php?ReqID=5" method="post"
name="frm5">
<tr align="left" bgcolor="#dddddd" class="text" onClick="document.frm5.submit()"
onMouseOver="show(event,'titleinfo');this.style.backgroundColor='#CCFFCC';"
onMouseOut="hide('titleinfo');this.style.backgroundColor='#dddddd';">
<td>
<input name="fromStatus" type="hidden" value="true">
Database Population
</td>
<td>2005-04-25 00:33:00</td>
<td>2005-04-25 01:33:00</td>
<td>Pending</td>
<td></td>
</tr>
</form>
</table>
</body>
</html>
 
R

RobG

Stuart said:
Hi,

I have the following code which works just fine in IE6 but not in
Firefox.
It is an extract of several table rows each with an individual form.
It is generated by php.

<form action="MaintNotification.php?ReqID=5" method="post"
name="frm5">
<tr align="left" bgcolor="#dddddd" class="text" onClick="submit()"
onMouseOver="show(event,'titleinfo');this.style.backgroundColor='#CCFFCC';"
onMouseOut="hide('titleinfo');this.style.backgroundColor='#dddddd';">
<td>

You've been given fixes to your script above, but my question is why
use a td as a pseudo-button? Why not use a button (inside the td if
you like), then it will work without JavaScript and will submit the
form by default?

You can still have onmouseover, etc. with a button and support non-JS
users at the same time:

<URL:http://www.w3.org/TR/html4/interact/forms.html#edef-BUTTON>
 
R

Richard Cornford

Stuart said:
I have the following code which works just fine in
IE6 but not in Firefox.
It is an extract of several table rows each with an
individual form. It is generated by php.

<form action="MaintNotification.php?ReqID=5"
method="post" name="frm5">
<tr align="left" bgcolor="#dddddd" class="text"
onClick="submit()"
</tr>
</form>

If I just use onClick="submit()" FF tels me submit is
not defined If I use document.frm5.submit I am told it
is not a function

What do I need to do to get the form submitted when
someone clicks on the table row?

In addition to knowing how to encourage your code to work in more
browsers (by using an absolute reference to the form object) it might be
valuable to understand why you experienced the problem in the first
place.

The first thing that needs to be understood is how it works when and
were it did, because in pure javascript terms it really shouldn't. A web
browser, presented with an onclick attribute in the HTML (or any other
intrinsic event) uses the string provided as the value for that
attribute as the body code for a function that it generates internally.
The resulting function is then assigned to a property of the DOM element
that represents the corresponding HTML element. In this case that would
be the - onclick - property of the TR element (at least where the
browser supports onclick events on that type of element). This is
approximately equivalent to doing:-

referenceToTR_Element.onclick = function(event){
submit();
};

- in javascript code (with the - event - argument omitted on IE browsers
as they do not pass the event object directly to the function when it is
called).

When the browser triggers the corresponding event (onclick in this case)
it calls the resulting function as a method of the DOM element. The
equivalent of:-

referenceToTR_Element.onclick(e);

- (where the - e - argument is a reference to the event object, but not
on IE browsers as they do not pass the event to event handling method
calls.

The execution of the event handling method is then expect to follow the
normal javascript/ECMAScript rules. As it only contains one statement
that statement is executed. That statement is made up of an Identifier
followed by an empty Arguments expression; thus it is a function call
with no arguments. To execute the statement without errors the
Identifier must be resolved as a reference to a function object, so the
resolution of the identifier becomes the first problem.

Identifiers are resolved against the scope chain. Each object in the
scope chain is examined in turn to see if it (or one of its prototypes
(if any)) has a named property, the name of which corresponds with the
identifier (in terms of the sequence of characters used). If such an
object is identified then the Identifier is resolved as a reference to
the value of the property of that object on the scope chain that has the
corresponding name. If no such object is identified on the scope chain
then the Identifier is resolved as having the value - Undefined - (but
in such a way as to actually represent an undefined named property of
the global object, so that assignments operations have predictable
behaviour with unresolved identifiers).

So for the Identifier - submit - to resolve as a reference to a function
it is necessary that an object on the scope chain of the event handling
method has a property with the name "submit" that refers to a function
object (the value of the property is the reference).

If the example assignment of a function expression to an event handling
property of a DOM element was the whole story then the resulting scope
chain for a call to that function would be expected (assuming no
function nesting during the assignment (see javascript closures)) to
consist of the Variable/Activation object associated with the specific
function/method call (the repository of formal arguments, inner function
definitions, function local variables and the - arguments - object) and
the global object. The Identifier - submit - is not a declared local
variable, a formal argument and there are no inner functions, so it will
not be resolved as a property of the Variable/Activation object at the
top of the scope chain and identifier resolution will move on the global
object. In a browser environment it would not be expected that the
global object would have a property called "submit" either. So the
expectation would be that the function would error when it attempted to
execute the statement - submit(); -.

And indeed there are many browsers where it would indeed error, but they
do not include IE 5.0+, and may not include versions of Opera 7+ or
Mozilla/Gecko. This is because some browsers (including, but not
necessarily exclusively, those listed above) create their intrinsic
event attribute specified event handling functions with a custom scope
chain. And whenever that custom scope chain includes a reference to the
FORM element the Identifier - submit - would be resolved as a reference
to the - submit - method of that element on the scope chain (assuming
some object higher in the chain did not itself have a property named
"submit").

However, the provision of custom scope chains for internally generated
event handling functions is inconstant in its behaviour across those
browsers that do implement it. On IE it has some linking with the
presence and location of FORM elements within the DOM and is dynamic at
the time of execution (or assignment), while on Mozilla the custom scope
chain is related to the DOM hierarchy (the path between the element in
question and the document at the root of the DOM) and is static (if you
move the function to a different element it retains the custom scope
chain it was created with). And on Opera 7 the structure of the custom
cope chain resembles that of IE (with differences dependent on the
browser sub-version) but the chain is as static as that of Mozilla.

So the reason that - submit(); - works in IE is that the Identifier -
submit - is resolved on the custom scope chain as a reference to the -
submit - method of the form element. But the reason that it does not
work on the Mozilla derived Firefox (which does provide a custom scope
chain) involves another area of inevitable inconstancy - error
correction.

Your generated HTML is invalid. The direct children of the HTML TBODY
element (be it specified or implied) may only be TR elements. You have
placed a FORM element in that context. While the authors of pure HTML
can more or less get away with disregarding validity in HTML (it usually
don't make any perceivable difference to the outcome as presented by
various browsers) anyone scripting a web browser is interacting with a
standardised DOM structure, and there are rules as to the structure of
that DOM. Rules derived from the HTML specifications and their DTDs.

While building a DOM from HTML source code a browser encountering a FORM
element where only a TR is allowed must perform some error-correction.
Mostly they will not just reject the illegal element as the prevalence
of invalid HTML on the Internet would tend to make them look broken, so
they bend over backwards to accommodate any nonsense they are presented
with. But they still have to do something, and as a standard can only
reasonably specify what they are supposed to do with correct mark-up how
they handle invalid mark-up is largely up to their authors. (They don't
even have the option of copying each other as the error-correction code
on any given browser is unlikely to be public to the extent necessary
for another browser manufacturer to copy/reproduce its exact behaviour.
Error-correction is inevitably inconsistent across browsers as a
result).

Firefox/Mozilla/Gecko handle encountering a FORM within a TBODY where
only a TR is allowed, will move the FORM element back in the DOM to the
last location where it would be allowed (before the TABLE element),
maintaining the form's - elements - collection as references to the
contained form controls. Those controls remain descendants of the TABLE
and cease to be descendants of the FORM. Opera and IE have different
(and distinct) error-correction strategies that produce different DOM
structures form this mark-up (as should also be expected to be true for
any other browser).

So it is the interaction of the divergent custom scope chain creation
techniques with inconstant error-correction strategies that prevents the
code form working on Firefox/Mozilla/Gecko. The custom scope chain of
Firefox includes all of the DOM elements on a path between the TR and
the DOM root (at the document), but the error-correction for the invalid
HTML ahs moved the FORM element off that path, so the Identifier -
submit - is not resolved against the scope chain.

At first sight this all sounds like the sort of thing that makes people
think that writing cross-browser code is impossible, but it is actually
a situation that arises directly (and only) form the author's disregard
for the applicable standards. There is no applicable standard for the
creation of custom scope chains so a standards-conforming browser
doesn't have to create one at all, and those that do cannot be expected
to produce consistent behaviour in this respect. And there is no
standard for how invalid HTML is to be handled in the creation of a DOM.

But following the standard that do apply avoids the problem entirely;
writing event handling attribute code so that it conforms with only the
behaviour specified by ECMA 262 (i.e. don't expect a scope chain that
differs from the one defined in the ECMA 262) will result in code that
behaves identically on all ECMAScript conforming web browser (and most
that pre-date that standard) and using only formally valid HTML mark-up
will result in the browsers creating structurally consistent DOMs from
that mark-up (as there is a direct and clearly specified mapping from
valid mark-up to DOM structure).

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top