Reputation: 52500
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
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
Reputation: 36
I found a way that works with Chrome, Firefox and Edge:
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
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
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
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
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
Reputation: 1500
You can use this code:
$(".TextID").attr("autocomplete", "off"); //disable input level
Upvotes: 0
Reputation: 20279
jQuery one:
$(".indication-checkbox").attr("autocomplete", "off");
Upvotes: 5