Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger autocomplete without submitting a form

Tested with Chrome, IE and Firefox:

<iframe id="remember" name="remember" class="hidden" src="/content/blank"></iframe>

<form target="remember" method="post" action="/content/blank">
  <fieldset>
    <label for="username">Username</label>
    <input type="text" name="username" id="username" value="">
    <label for="password">Password</label>
    <input type="password" name="password" id="password" value="">
  </fieldset>
  <button type="submit" class="hidden"></button>
</form>

In your Javascript trigger the submit, e.g. $("form").submit(); $("#submit_button").click() (updated from comments)

You need to return an empty page at /content/blank for get & post (about:blank didn't work for me but YMMV).


We know that the browser saves its information only when the form is submitted, which means that we can't cancel it with return false or e.preventDefault()

What we can do is make it submit the data to nowhere without reloading a page. We can do that with an iframe

<iframe name="💾" style="display:none" src="about:blank"></iframe>

<form target="💾" action="about:blank">
    <input name="user">
    <input name="password" type="password">
    <input value="Login" type="submit">
</form>

Demo on JSfiddle (tested in IE9, Firefox, Chrome)

Pros over the currently accepted answer:

  • shorter code;
  • no jQuery;
  • no server-side page loaded;
  • no additional javascript;
  • no additional classes necessary.

There is no additional javascript. You normally attach an handler to the submit event of the form to send the XHR and don't cancel it.

Javascript example

// for modern browsers with window.fetch
document.forms[0].addEventListener('submit', function (event) {
    fetch('login.php', {
        method: 'post',
        body: new FormData(event.target))
    }).then(r => r.text()).then(() => { /* login completed */ })
    // no return false!!
});

No-javascript support

Ideally, you should let the form work without javascript too, so remove the target and set the action to a page that will receive your form data.

<form action="login.php">

And then simply add it via javascript when you add the submit event:

formElement.target = '💾';
formElement.action = 'about:blank';

I haven't tested this, but it might work if you submit the form to a hidden iframe (so that the form is actually submitted but the current page is not reloaded).

<iframe name="my_iframe" src="about:blank"></iframe>

<form target="my_iframe" action="about:blank" method="get">...</form>

---WITHOUT IFRAME---

Instead of using iframe, you can use action="javascript:void(0)", this way it doesn't go to another page and autocomplete will store the values.

<form action="javascript:void(0)">
    <input type="text" name="firstName" />
    <button type="submit">Submit</button>
</form>

Maybe you can use this Twitter Typeahead...is a very complete implementation of a autocomplete, with local and remote prefetch, and this make use of localStorage to persist results and also it show a hint in the input element...the code is easy to understand and if you don't want to use the complete jquery plugin, I think you can take a look of the code to see how to achieve what you want...


You can use jQuery to persist autocomplete data in the localstorage when focusout and when focusin it autocompletes to the value persisted.

i.e.

$(function(){
 $('#txtElement').on('focusout',function(){
   $(this).data('fldName',$(this).val());
 }

 $('#txtElement').on('focusin',function(){
   $(this).val($(this).data('fldName'));
 }
}

You can also bind persistence logic on other events also depending on the your application requirement.


For those who would rather not change their existing form functionality, you can use a second form to receive copies of all the form values and then submit to a blank page before your main form submits. Here is a fully testable HTML document using JQuery Mobile demonstrating the solution.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile.structure-1.4.5.min.css" />
    <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
    <form method="post">
        <input type="text" name="email" />
        <input type="submit" value="GO" onclick="save_autofill(this);" />
    </form>


    <script>
        function save_autofill(o) {
            $(':input[name]', $('#hidden_form')).val(function () {
                return $(':input[name=' + this.name + ']', $(o.form)).val();
            });

            $('#hidden_form').find("input[type=submit]").click();
        }
    </script>

    <iframe name="hidden_iframe" style="display:none"></iframe>
    <form target="hidden_iframe" id="hidden_form" action="about:blank" style="display:none">
        <input type="text" name="email" />
        <input type="submit" />
    </form>
</body>
</html>

The save_autofill function just needs to be called on your main form submit button. If you have a scripted function that submits your form, place that call after the save_autofill call. You must have a named textbox in your hidden_form for each one in your main form.

If your site uses SSL, then you must change the URL for about:blank with https://about:blank.