20

I am dynamically generating a form. For simplicity's sake assume it's a login form with email/password. The form is submitted, but onsubmit it fires an AJAX request that handles the actual login and the submit event is cancelled (e.preventDefault()).

I use e.preventDefault() to cancel the default action of the form, that is, go to the page in 'action' but this also seems to cancel the autocomplete detection of the browser.

I think you need to fullfill several requirements for the native autocomplete to work:

  • Your input field type="text" must have a name
  • The form must be submitted <-- this isn't really happening in my case

Is my analysis correct and is there any way to make autocomplete work in this case?


To ward off the fanboys: I'm not looking for any solution that involves jQuery or [insert your framework], I want to use the native browser autocomplete feature. I don't have a list of words that I want to autocomplete with.

smhg
  • 2,159
  • 19
  • 26
Halcyon
  • 57,230
  • 10
  • 89
  • 128

3 Answers3

14

Ok i found a convoluted way to do this:

Here is the javascript:

function ajaxit() {
    var iFrameWindow = document.getElementById("myframe").contentWindow;
    iFrameWindow.document.body.appendChild( document.getElementById("myform").cloneNode(true));   
    var frameForm = iFrameWindow.document.getElementById("myform");
    frameForm.onsubmit = null;
    frameForm.submit();
    return false;
}

Here is the html:

<form id="myform" onsubmit="return ajaxit();" autocomplete="on">
    <input id="foo" name="foo"/> 
    <input type="submit" />
</form>
<iframe id="myframe" src=""></iframe> <!-- you'll want this hidden -->

Clicking submit will run the ajaxit() method. the method creates the same form in an iframe, and submits it to the server. You can either piggyback that submit to do your server request or you can do a separate ajax request and ignore the iframe.

I know that it's ugly, but it works.

EDIT: Here is a jsbin to play with.

Vad.Gut
  • 521
  • 1
  • 5
  • 19
Daniel Moses
  • 5,872
  • 26
  • 39
  • Clever, I like it. I wonder why I didn't think of that :P I had the idea that an `iframe` wouldn't work, but apparently it does! – Halcyon Dec 08 '11 at 19:38
  • There are actually 2 different situations: forms that are submitted with AJAX and forms that are dynamically generated (and probably also submitted with AJAX). The *jsbin* example covers only the first. – smhg Dec 02 '13 at 18:13
  • Can you please elaborate on what is going on? What do we gain by submitting the form inside an iframe as opposed to submitting it directly? I thought the problem we are trying to solve is how to submit a form using AJAX instead of the normal form-submit mechanism. In my case, I must submit JSON. The server will not accept the normal form encodings (e.g. application/x-www-form-urlencoded). – Gili Jul 21 '14 at 04:39
  • Gili, that is not the problem. The problem is that IF you submit it using AJAX, then the browser will not remember the values for future auto-complete. This question does not go into submitting a form using ajax. It assumes you are already doing that, and wish to have the browser store the values in it's auto-complete history. – Daniel Moses Jul 21 '14 at 15:27
  • Has anybody used this in production on a large site? Are there any pitfalls with using this method? Just as a security measure, if you're submitting sensitive data remember to add a method attribute to the form that isn't a value of get! – alexrogers Mar 19 '15 at 15:48
11

DMoses solution greatly inspired my solution but it there is a significant difference so I thought it would be a good idea to make my own solution, the bounty goes to DMoses though :P

DMoses solution moves (or copies) the form to the iframe and then submits it. The reason you want to do this is so your 'parent' from doesn't reload. There is a simpler solution: have the form submit to the iframe. This works just the same and you don't have to copy any nodes.

This step is entirely repeatable as well. The only downside is that you don't control when exactly an autocomplete entry is added. You might want to add only valid entries but at least this case mimics perfectly the way a normal form would behave if no ajax were involved. If you want to control what gets added to the autocomplete, use DMoses' solution, copy the form and submit it in the iframe.

For me, this is enough:

<form onsubmit="return ajaxit();" autocomplete="on" target="the_iframe">
    <input id="foo" name="foo"/> 
    <input type="submit" />
</form>
<iframe id="the_iframe" name="the_iframe" src="javascript:false"></iframe> <!-- you'll want this hidden -->

The best part: no extra JavaScript is required to make this work! (other than generating a unique id/name for the form, but that's super trivial).

jsFiddle: http://jsfiddle.net/KzF6s/13/

Halcyon
  • 57,230
  • 10
  • 89
  • 128
  • Thanks for the bounty! I wonder if you return a HTTP 500 if the value still gets added by most browsers? Might be worth trying if it's important. – Daniel Moses Dec 09 '11 at 17:28
  • 1
    I don't think it's important. The page I post to is not a real page anyway (`javascript:false`) and just having an idle page that always returns `500` just to get this to work is iffy. – Halcyon Dec 09 '11 at 18:43
  • In current browsers, I cannot seem to get this to work: http://jsfiddle.net/KzF6s/ – smhg Dec 02 '13 at 18:38
  • I think you're correct. This solution stopped working for me too. – Halcyon Dec 02 '13 at 18:58
  • I was wrong: `event.preventDefault()` shouldn't be there. This is a correct fiddle: http://jsfiddle.net/U8Fcb/. However: this works in Chrome (v31) and FireFox (has native support actually). Not in IE9 or IE10 (a local example seems to work in IE8, surprisingly). – smhg Dec 02 '13 at 19:57
  • As I mentioned with the other comment: this might work when you form is already present on page load. But for dynamically generated forms, this does not seem to be a "complete" solution. – smhg Dec 02 '13 at 19:59
  • 1
    I added my solution to your jsbin and it works on chrome. So it looks like you might have to actually do the submit now. http://jsfiddle.net/KzF6s/1/ – Daniel Moses Dec 02 '13 at 23:19
0

After messing around a bit with fiddles in comments on other answers' workarounds, I decided to make this list for anyone who can wait for browsers to handle this correctly.

So, as a summary, these browser versions support autocomplete values on forms generated with JavaScript:

  • FireFox 25
  • Chrome 33 (current version is 31, so coming soon)
  • Internet Explorer 11 (reference)
smhg
  • 2,159
  • 19
  • 26