Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

browser native autocomplete for dynamically generated forms (handled with ajax)

Tags:

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.

like image 891
Halcyon Avatar asked Dec 06 '11 12:12

Halcyon


People also ask

How to create autocomplete components in HTML?

HTML provides a native way to create autocomplete components. Create a label and input like you normally would. Then create a datalist element, and add an option element for each autocomplete choice. Give the datalist an ID.

How to save autocomplete and event in login form?

It simple and normal filling a form like username and password in a login form. After the form submitted (the form data post) browser will save the autocomplete or event in FF will ask to save along with the password. Now, think about the login submitted via ajax.

How do I get a list of autocomplete options from an API?

If our JavaScript fails, we still have a completely usable field, just without any autocomplete functionality. Next, we can use the fetch () method to get a list of autocomplete options from an API or endpoint. For this demo, I have a simple JSON file with an array of wizards.


2 Answers

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.

like image 121
Daniel Moses Avatar answered Nov 20 '22 22:11

Daniel Moses


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/

like image 30
Halcyon Avatar answered Nov 20 '22 22:11

Halcyon