ChatGPT解决这个技术问题 Extra ChatGPT

Trigger autocomplete without submitting a form

I am writing a very simple web app with three text inputs. The inputs are used to generate a result, but all the work is done in Javascript, so there is no need to submit a form. I'm trying to find a way to get the browser to store input values for autocomplete as it would if they were in a form that was submitted.

I have tried giving the inputs autocomplete="on" manually, but without a form to submit, the browser has no way of knowing when it should store the values, so this has no effect.

I have also tried wrapping the inputs in a form that has onSubmit="return false;", but preventing the form from actually submitting appears to also prevent the browser from storing its inputs' values.

It is of course possible to manually use localStorage or a cookie to persist inputs and then generate autocomplete hints from those, but I'm hoping to find a solution that taps into native browser behavior instead of duplicating it by hand.

Not sure If I understand the question correctly. Does it mean that you'll have loaded the information in the browser so the javascript will do a lookup in some preloaded data using the information from three input box? Some autocomplete implementations I saw, uses Ajax to load results. That doesn't fit your model, does it?
Here, try the solution provided in a similar question: stackoverflow.com/questions/8400269/…
@VKen I simply want the browser to treat the inputs as if they were part of a form that had been submitted, in that the user will see the values they'd previously entered as autocomplete suggestions, without actually submitting a form.
That sounds like it needs a history record of inputs. Sounds like how browser saves form inputs to autosuggest/autocomplete. AFAIK, we'll need local storage. This plugin amplifyjs is good. For your criteria, no local storatge, no connection to server search via form submit(ajax or similar), where is the history going to come from? This sounds like an offline app closer to a browser extension, rather than a web app. Your question piqued my interest and I hope someone better can answer too.

l
laktak

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).


Just a note, there is no need to define a content/blank URL to point the iframe and form at - defining the attributes as about:blank works fine for me.
FYI this didnt work for me (maybe because I tried it from a chrome extension page). I modified it slightly and it did work: set an identifiable class to the submit button (say "mySubmit"), then instead of $("form").submit() do $(".mySubmit").click().
+1, but it will not work, if you use $("form").submit();, you have to use e.g. $("#submit_button").click()
@AmericanUmlaut I think you are mistaken. Chrome 36.0.1985.125 does not display a "save password" prompt if you I use about:blank for both the iframe and form. You should be able to reproduce this on your end.
@Gili I wasn't aware of that, and it's definitely a useful observation for a lot of authors. In my concrete example, the password field has autocomplete disabled, so I've never noticed that difference.
f
fregante

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';

This answer may need an update for 2018. The jsfiddle does not appear to do prompt the user for anything
The question isn't about prompting, but about saving the data entered without submitting the form to the server.
Yes, I understand. I am referring to the chrome browser "save password" prompt that is triggered by autocomplete forms, not a js prompt
A
Alex

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>

p
pravchuk

---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>

This only works for the first submit and then doesn't save any new values you try to add.
I
IJMorgado

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...


no commits to Twitter Typeahead for more than a year.... maybe select2.github.io is any good...
P
Prakash Bhagat

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.


I like this idea. This makes sense especially when you only have a few inputs that require autocomplete, rather than dirty the code with the workaround of hidden iframe.
But just tested, jquery .data() does not persist the data when the page is reloaded. Might as well use localStorage.setItem(key,value).
C
Carter Medlin

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.


about:blank is indeed necessary to avoid some warnings in Firefox. I wonder if there are other options that don't have this problem. Maybe javascript:void(0)? Also, does submitting another form really adds to the browser's autocompletion for all forms?
B
Bassel Shmali

From what i searched.. it seems you need to identify the names. Some standard names like 'name', 'email', 'phone', 'address' are automatically saved in most browser.

Well, the problem is, browsers handle these names differenetly. For example, here is chrome's regex:

first name: "first.*name|initials|fname|first$"

email: "e.?mail"

address (line 1): "address.*line|address1|addr1|street"

zipcode: "zip|postal|post.*code|pcode|^1z$"

But chrome also uses autocomplete, so you can customize the name and put an autocomplete type, but i believe this is not for custom fields..

Here is chrome's standard

And it's another thing in IE, Opera, and Mozilla. For now, you can try the iframe solution there, so you can submit it. (Maybe it's something semi-standard)

Well, that's all i can help.


p
pseudosudo

Make sure you're submitting the form via POST. If you're submitting via ajax, do <form autocomplete="on" method="post">, omitting the action attribute.


m
max zhou

you can use "." in both iframe src and form action.

 <iframe id="remember" name="remember" style="display:none;" src="."></iframe>
 <form target="remember" method="post" action=".">
    <input type="text" id="path" size='110'>
    <button type="submit" onclick="doyouthing();">your button</button>
</form>