at.
at.

Reputation: 52500

Disable autofill on a web form through HTML or JavaScript?

Is there a way to disable autofill in Chrome and other browsers on form fields through HTML or JavaScript? I don't want the browser automatically filling in answers on the forms from previous users of the browser.

I know I can clear the cache, but I can't rely on repeatedly clearing the cache.

Upvotes: 34

Views: 66855

Answers (8)

Iqbal
Iqbal

Reputation: 1316

After trying numerous suggestions here and elsewhere, I finally came up with a solution that, while simple, got the job done effectively.

During my testing, I noticed that the input value was being autofilled right after the document finished loading. This timing meant that neither document.ready nor the DOMContentLoaded event provided a straightforward fix to clear it.

So, I opted for a quick workaround: I used a setTimeout to delay clearing the input field by one second after the document loads, ensuring that the autofill completes before I reset the field. It may not be the most elegant solution, but it reliably cleared the field for me.

Here’s the code snippet I used:

// Select the input field
var srch = document.getElementById('dt-search-0');

// Clear the autofilled value after a short delay
setTimeout(function () {
    srch.value = '';
}, 1000); // you may adjust the delay as you wish.

And here’s the input field in question:

<input type="search" class="form-control form-control-sm" id="dt-search-0" placeholder="" aria-controls="tblusers">

I hope this helps anyone facing the same issue! Sometimes, a simple delay can save the day.

Happy coding!

Upvotes: 0

Yowser
Yowser

Reputation: 36

I found a way that works with Chrome, Firefox and Edge:

  1. Set the name and ID of all of your inputs to random.
  2. Put some hidden rubbish in a span element in the field prompt.

Even when you rename / reID (??) each input, the browser uses the prompt to guess and still offers autocomplete. So, I did this in the prompt:

First/Given N<span style="display:none">fmkdgnkdfjgh</span>ame

The browser doesn't see this as a Name prompt. I did the same with Email, Mobile, Postcode and they all stopped offering autocomplete. Happy days!

I combined this into a small library:

    var formFields = []; // Holds table of random element IDs vs original IDs/names

    // Make sure our proposed new random field name is unique (it will be, but belt and braces)
    var isUniqueFormElementID = iufeid = function (proposedID) {
        for (var p = 0; p < formFields.length; p++) {
            if (formFields[p].id == proposedID)
                return false;
        }
        return true;
    }

    // Given an element and a prefix, generate a random field name, record it in formFields and change the element's ID and Name
    var setFormElementID = sfeid = function (element, prefix) {
        if (element.type.toLowerCase() == "text") {
            do
                newID = prefix + Math.floor(Math.random() * 1000000);
            while (iufeid(newID) == false);

            formFields.push({ id: newID, origID: element.id, origName: element.name });
            element.id = newID;
            element.name = newID;
        }
    }

    // Return the index of an element's original ID in formFields
    var findFormElement = ffe = function (origID) {
        for (var p = 0; p < formFields.length; p++) {
            if (formFields[p].origID == origID)
                return p;
        }
        return -1;
    }

    // Return an element given its original ID
    var getFormElement = gfe = function (origID) {
        var idx = ffe(origID);

        if (idx != -1)
            return document.getElementById(formFields[idx].id);
        else
            return null;
    }

    // Remove an element from formFields and set its ID and Name back to the original
    var resetFormElementID = removeFormElement = rfeid = rfe = function (origID) {
        var idx = ffe(origID);

        if (idx != -1) {
            ele = document.getElementById(formFields[idx].origID);
            ele.id = formFields[idx].origID;
            ele.name = formFields[idx].origName;
            formFields.splice(idx, 1);
            return ele;
        } else
            return null;
    }

    // Remove all elements from formFields and set their ID and Name back to the original
    var resetAllFormElementIDs = removeAllFormElements = rafeids = rafae = function () {
        for (var p = 0; p < formFields.length; p++) {
            ele = document.getElementById(formFields[p].id);
            ele.id = formFields[p].origID;
            ele.name = formFields[p].origName;
        }

        formFields = [];
    }

    // Return and obfuscate the prompt text of a field
    var obfuscatePrompt = oP = function (promptText) {
        var words = promptText.split(" ");

        for (var p=0; p<words.length; p++)
            words[p] = words[p][0] + "<span style='display:none'>fmkdgnkdfjgh</span>" + words[p].substring(1);

        return words.join(" ");
    }

    // Main call
    //
    // form             Form. The form object. If null, defaults to the first form found in document.forms.
    // promptClassName  String. The class name of the tags that contain the prompt text
    // elementPrefix    String. The prefix prepended to each element ID and name. If null, Defaults to "fld_".
    var thwarteAutoFill = taf = function(form, promptClassName, elementPrefix) {
        if (form == null) {
            if (document.forms.length > 0) {
                form = document.forms[0];
            }
        }

        if (elementPrefix == null) {
            elementPrefix = "fld_";
        }

        if (form != null && typeof promptClassName === "string") {
            for (var p = 0; p < form.elements.length; p++)
                sfeid(form.elements[p], elementPrefix);

            prompts = document.getElementsByClassName(promptClassName);
            for (p = 0; p < prompts.length; p++)
                prompts[p].innerHTML = oP(prompts[p].innerText);
        }
    }

I call thwarteAutoFill(form, promptClassName, prefix) when the page has loaded, which randomises the text field IDs and names and looks for any element with the class name promptClassName and obfuscates the words inside those elements.

Then when I want to get a reference to a field I call gfe("origID") and it returns the correct element.

I also have a resetAllFormElementIDs function (untested as of writing this) that puts everything back as it was so I can call it before posting the form.

Convoluted, but seems to work ;-)

Upvotes: 0

Dejan Dozet
Dejan Dozet

Reputation: 1009

I am working with onfocus and onblur, like this:

<form>
  <p>Type something in both fields and hit submit button, then refresh this page and click on the first field. In chrome, you will get autocomplete on the first field, but if you select it it will populate only that first field!</p>
  <input type="text" name="first" placeholder="with autocomplete" /> <br/>
  <input type="text" name="second" placeholder="without autocomplete"
  readonly="readonly" 
  onfocus="if (this.hasAttribute('readonly')) {this.removeAttribute('readonly');}"
  onblur="if (!this.hasAttribute('readonly')) {this.setAttribute('readonly','readonly')};"
  /><br/>
  <button type="submit">Send</button>
</form>

Upvotes: 0

Vladimir Marton
Vladimir Marton

Reputation: 576

I had the same issue. Wanted to stick to a HTML solution (I dont like dirty JS workarounds). The only thing that worked for me is when I changed ID and/or name of the input to something that is not a usual keyword.

Read Talinon's answer from this Laracast thread:

I once had this problem on a text field. No matter what I did, Chrome insisted on auto filling/completing. I eventually discovered changing the id/name of the element solved the problem. It's like Chrome has some hard-coded keywords it looks for and is bent on autofilling them. If the problem persists with the proposed hacks, try changing the id/name to something that doesn't contain "title" or "address", etc.

Long story short:

<form>
    <input type="email" name="fem" />
    <input type="password" name="fpass" autocomplete="new-password" />
</form>

Longer story (explanation why this works): Disabling autocomplete on form inputs with HTML

Upvotes: 3

LNendza
LNendza

Reputation: 1400

You can do it at the input level in HTML by adding autocomplete="off" to the input.

http://css-tricks.com/snippets/html/autocomplete-off/

You could also do it via JS such as:

someForm.setAttribute( "autocomplete", "off" ); 
someFormElm.setAttribute( "autocomplete", "off" );

Upvotes: 35

oddpodm
oddpodm

Reputation: 157

In fact autocomplete off doesn't always work in newer browsers. E.g in Chrome it is ignored if the autofill property is set. See the link: http://caniuse.com/#feat=input-autocomplete-onoff

Upvotes: 10

Anand Dwivedi
Anand Dwivedi

Reputation: 1500

You can use this code:

$(".TextID").attr("autocomplete", "off"); //disable input level 

Upvotes: 0

testing
testing

Reputation: 20279

jQuery one:

$(".indication-checkbox").attr("autocomplete", "off");

Upvotes: 5

Related Questions