views:

48

answers:

4

I have a problem with IE (8, have not tested on 7). I have a very simple situation: I create a form element

var formNode = $('<form>');

I attach a bunch of other elements to the form (fieldsets with input elements inside of tables). I then attach the form to the DOM, and then bind a submit handler:

formNode.bind('submit', function (ev) {
   alert('submit of form!');
   // do lots of stuff....
 }

This works with Safari on my Mac (yah, I'm a Mac guy), and on Safari and Firefox on Windows, but the alert is never called when I click the submit button when using IE 8. Instead, the browser tries to submit a GET request for / (I have not set either a Method or an Action for the form - perhaps that is necessary?).

Any insights would be greatly appreciated as I am making changes hit-or-miss in order to debug.

+1  A: 

You haven't said what level of HTML you're using, but FWIW, action is a required attribute on form elements in HTML4. So it wouldn't be too surprising if a browser behaved oddly without it. (In HTML5, the validator says it's not required any longer, probably because some of this stuff is now allowed on the submit buttons themselves.)

T.J. Crowder
HTML 4. I tried setting action="" on the element creation, and now the form doesn't even render on IE 8 (works on Mac Safari). Will keep trying...
Zhami
`action=""` is also invalid. Try `action="#"`. But if the form didn't even render, frankly I suspect there's a larger problem elsewhere.
T.J. Crowder
Curious: if I try setting the action="#" in the jQuery element creation, the element is not created and the form doesn't render; code: formNode = $('<form action="#">') .... however if I set the action by .attr('action', '#') then the form renders. But still, the submit binding does not work.
Zhami
I think we might need to see more code then. Certainly it's not reproduceable just with the code above (well, after the trivial missing `)` is fixed).
bobince
My code that is having a problem executes in a context of a huge amount of other code. I am working to create a standalone test case. If I fail to achieve that, then I know the problem is with my context.
Zhami
A: 

Why have you bound the handler to the submit event of the form rather than the click event of the button?

J. Strange
I tend to approach forms that way `$('form').submit('/* stuff */');` rather than `$('submitButton').click(/* stuff */);`, because there's no guarantee that the submit button will be used to submit the form (users might hit enter from any of the `<input type="text" />` fields, as one alternative (I suspect that screen-reader browsers might have even more arcane methods of form submission), which `submit()` gets, but `click()` probably wouldn't.
David Thomas
@David: yes, this is the best approach. You should only put submission handling on a submit button click event when it's a non-default submit button. Although *usually* when you press Enter to submit a form it causes a button click event, there are cases where that doesn't happen. (It depends on the browser, the number of buttons in the form, and the number of text fields in the form.) For safety, always put submit handling on the form object.
bobince
In my case, I need to prevent default submit behavior (a call to the server). My app uses client side Sinatra-like routing (using Sammy), and all functionality is Browser resident (i.e. Javascript driven). Perhaps I can try doing what I need on the click event... if I can stop its causing of the form to submit... will try that as I can't seem to get the bind event handler to actually be bound to the form.
Zhami
A: 

Are you remembering to return false (or event.preventDefault()) from your event handler? If not, the form will continue to submit, effectively navigating you to the action URL, or the same URL as the current document, if there is none. Though really there should be some action both for HTML validity and to provide a working non-JavaScript solution where possible (progressive enhancement and all that).

If you do have the return false, make sure no JavaScript errors are occurring in the handler code that abort the function before it gets to return false. Turn on JS error reporting in the Internet Options and/or use the debugger.

bobince
I wish I had the problem of needing to stop propagation :-) But the problem is that the submit handler does not even execute. Yes, the code returns false. Right now for testing, I issue an alert on entry - which doesn't occur - and then return false. ... As for needing an action... my use-case is an in-browser Javascript app - there's nothing the server can do as all functionality for this form's action happens in the handler. This works for all Browsers I have tried except for IE. My app is not in any way "progressive" - if Javascript doesn't work, then the app is DOA.
Zhami
+1  A: 

There a variety of issues with listening for events from form elements with jQuery in Internet Explorer. There are a series of comments on the jQuery forum about: IE-specific issues with live ('submit'). Granted I know you are using bind and not live but many of the described problems involve attempts at using both.

I commented on your answer asking which version of jQuery you are using. If you haven't already and can do so I'd upgrade to the latest release.

A few code solutions:

Bind the submit handler to each child of the body element
adapted from synertech1 answer in the aforementioned jQuery forum discussion.

var submitHandler = function() { ... };

$("body").children().each(function() {
      $("form", this).bind("submit", submitHandler);
})

Bind to the submit input type
I hate this option because the form element is the more appropriate element to bind to.

 $('form > input[type*="submit"]').bind('click', function(event) {
     var form = $(this).parent;
     form.submit();
     event.preventDefault();
 });
ahsteele
Thanks for the link and suggestions. I am trying to narrow down the problem because what I have found is that if I build a minimal HTML file with a form and a submit button and bind to that, IE works. So I have spent hours now instantiating a form-and-button in my app, finding where it works... and where it doesn't, and am trying to hone in on a dividing line that may shed light on why it works in some cases and not others. I hope I am not fruitlessly spinning my wheels.
Zhami
@Zhami In your tests what are you binding the event to, the button or the form? The suggestion to **bind the submit handler to each child of the body element** is there because there is conjecture that events bound form events at the document level have a propensity to be lost by IE. I'd bind them to the body and see what happens.
ahsteele
I am binding to the form itself. I'd like to get this to work that way, so will continue to investigate the "collision" (with the Sammy library) to see if I can find a focused work-around.
Zhami
@Zhami binding to the body is still working from the form element but listening for the event on the body element. :)
ahsteele