Turn off autocompletion without affecting session history caching - html

I would like to
(1) not show any suggestions to the user while typing in an input field.
This can be done like this:
<input autocomplete="off">
However, I noticed that this also
(2) disables the history chaching, e.g. when you go to another site and click on the history back button the input field will be empty.
You can try it here:
http://jsfiddle.net/LC53F/
Only text inserted into the first field will survive going to a new page and back again.
Is there a way to only have effect (1), but not (2)?

This solution should work, but is not ideal: just sharing an idea.
I don't think you will be able to preserve history with 'autocomplete', so let's try to fiddle out something.
Here's an idea: the history is based on input names, so you can turn off the autocompletion from other sites by using an uncommon name (but still constant, for example: 'email_fakeSuffix_194h5g48').
Then, to turn off autocompletion from this input previous values, you can change its name everytime the page is loaded (ie. append a random number). The problem is that, doing this, you will also turn off the history.
So, the main idea is to use an uncommon input's name and to change it just before submitting the form:
The value won't be saved by the browser because the name has changed
If you navigate to another page without submitting, the value will
still be set because you haven't change the name yet.
Here's an example using JQuery (you can use anything else, or even vanilla JS)
JSFiddle: http://jsfiddle.net/vse9jx3r/
HTML
<form>
<input id="input1" name="email_fakeSuffix_194h5g48">
<input name="input2">
<input type="submit">
</form>
JS
$('form').submit(function() {
$('#input1').attr('name', 'email_fakeSuffix_194h5g48_' + Date.now());
//SUBMIT THE FORM (MAY DO NOTHING AT ALL)
});
You can tell me if I'm not clear enough.

This works for me (using jQuery 1.9.1):
$(function(){
$('input[type=text]').prop('autocomplete','off');
$('#formid').on('submit', function(e){
$('input[type=text]').removeProp('autocomplete');
});
});

Related

HTML5 autofocus not working on generated view

I'm using EmberJS for my webapp and when I create a new record (set in edit mode), my first field (input text) has the autofocus="autofocus" parameter set. It works on Chrome the first time without problem, but not after.
The page loads once because it's an Ember app, and the views (record views) are being re-generated when I create a new record.
Any idea how to resolve this issue?
EDIT:
I have removed the autofocus property, and tried only to use Jquery focus() like in https://stackoverflow.com/a/14763643
App.FocusedTextField = Em.TextField.extend({
didInsertElement: function() {
this.$().focus();
}
});
Now, there is no focus even the first time. Also, if I tried replacing this.$().focus(); with this.$().hide();, then the input is hidden. this.$() in the console shows the right input as well, but focus() just does not work!
I would consider moving your input to a view or a component and then do something like this.$().focus(); in the didInsertElement function.
I came across the exact same issue with autofocus but the .focus() function did work for me. Here's how I coded it:
html:
<input type="text" id="idTextbox"/>
javascript:
$('#idTextbox').focus();

Stop LastPass filling out a form

Is there a way to prevent the LastPass browser extension from filling out a HTML-based form with an input field with the name "username"?
This is an hidden field, so I don't want any software to use this field for their purposes:
<input type="text" name="username" id="checkusername" maxlength="9" value="1999" class="longinput" style="display:none">
The solution should not be like "rename the input field".
Adding
data-lpignore="true"
to an input field disabled the grey LastPass [...] box for me.
Sourced from LastPass.com
Two conditions have to be met:
The form (not the element) needs to have autocomplete="off" attribute
Lastpass user needs to have this option enabled:
(old) Settings > Advanced > Allow pages to disable autofill
(new) Account Options > Extension Preferences > Advanced > Respect AutoComplete=off: allow websites to disable Autofill
So this depends on both user and the developer.
What worked for me is having word "-search-" in the id of the form, something like <form id="affiliate-search-form"> - and lastpass doesn't add its elements onto the form inputs. It works with something simpler like <form id="search"> but doesn't work with <form id="se1rch">
I know I'm late to the party here, but I found this when I was trying to stop lastpass from ruining my forms. #takeshin is correct in that autocomplete is not enough. I ended up doing the hack below just to hide the symbol. Not pretty, but I got rid of the icon.
If any lastpass developers are reading this, please give us an attribute to use, so we don't have to resort to stuff like this.
form[autocomplete="off"] input[type="text"] {
background-position: 150% 50% !important;
}
I think lastpass honors the autocomplete="off" attribute for inputs, but I'm not 100% sure.
EDIT
As others have pointed out. this only works if the user has last pass configured to honor this.
For me worked either type=search which is kinda equal to text or using role=note.
You can check the LastPass-JavaScript but it's huge, may be you can find some workaround there, from what I saw they only check 4 input types, so input type=search would be one workaround:
!c.form && ("text" == c.type || "password" == c.type || "url" == c.type || "email" == c.type) && lpIsVisible(c))
Also those are the role-keywords they seem to ignore:
var c = b.getAttribute("role");
switch (c) {
case "navigation":
case "banner":
case "contentinfo":
case "note":
case "search":
case "seealso":
case "columnheader":
case "presentation":
case "toolbar":
case "directory":`
I checked LastPass' onloadwff.js, prepare for 26.960 lines of code :)
Add "search" to input id
<input type="text" name="user" id="user-search"/>
Bit late to the party but I have just achieved this with modifying the form with:
<form autocomplete="off" name="lastpass-disable-search">
I guess this fools lastpass into thinking that it's a search form. This does not work for password fields however! Lastpass ignores the name field in this case.
The only way I've managed to do this is to add the following directly at the top of the form:
<form autocomplete="off">
<div id="lp" ><input type="text" /><input type="password" /></div><script type="text/javascript">setTimeout(function(){document.getElementById('lp').style.display = 'none'},75);</script>
</form>
It causes a nasty flicker but does remove the autofill nonsense - though it does still show the "generate password" widget. LastPass waits until domready and then checks to see if there are any visible password fields, so it's not possible to hide or shrink the mock fields above.
This ES6 style code was helpful for me as it added data-lpignore to all my input controls:
const elements = document.getElementsByTagName("INPUT");
for (let element of elements) {
element.setAttribute("data-lpignore", "true");
}
To access a specific INPUT control, one could write something like this:
document.getElementById('userInput').setAttribute("data-lpignore", "true");
Or, you can do it by class name:
const elements = document.getElementsByClassName('no-last-pass');
for (let element of elements) {
element.setAttribute("data-lpignore", "true");
}
For this latest October 2019 buggy release of Lastpass, this simple fix seems to be best.
Add
type="search"
to your input.
The lastpass routine checks the type attribute to determine what to do with its autofill, and it does nothing on this html5 type of "search." This fix is mildly hacky, but it's a one line change that can be easily removed when they fix their buggy script.
Note: After doing this, your input might appear to be styled differently by some browsers if they pick up on the type attribute. If you observe this, you can prevent it from happening by setting the browser-specific CSS properties -webkit-appearance and -moz-appearance to 'none' on your input.
None of the options here (autocomplete, data-lpignore etc.) prevented LastPass from auto-filling my form fields unfortunately. I took a more sledge-hammer approach to the problem and asynchronously set the input name attributes via JavaScript instead. The following jQuery-dependent function (invoked from the form's onsubmit event handler) did the trick:
function setInputNames() {
$('#myForm input').each(function(idx, el) {
el = $(el);
if (el.attr('tmp-name')) {
el.attr('name', el.attr('tmp-name'));
}
});
}
$('#myForm').submit(setInputNames);
In the form, I simply used tmp-name attributes in place of the equivalent name attributes. Example:
<form id="myForm" method="post" action="/someUrl">
<input name="username" type="text">
<input tmp-name="password" type="password">
</form>
Update 2019-03-20
I still ran into difficulties with the above on account of AngularJS depending upon form fields having name attributes in order for ngMessages to correctly present field validation error messages.
Ultimately, the only solution I could find to prevent LastPass filling password fields on my Password Change form was to:
Avoid using input[type=password]entirely, AND
to not have 'password' in the field name
Since I need to be able to submit the form normally in my case, I still employed my original solution to update the field names 'just in time'. To avoid using password input fields, I found this solution worked very nicely.
Here's what worked for me to prevent lastpass from filling a razor #Html.EditorFor box in Chrome:
Click the active LastPass icon in your toolbar, then go to Account Options > Extension Preferences.
On this screen check "Don't overwrite fields that are already filled" (at the bottom)
Next, click "advanced" on the left.
On this screen check "Respect AutoComplete=off: allow websites to disable Autofill".
I did not need to do anything special in my ASP cshtml form but I did have a default value in the form for the #Html.EditorFor box.
I hope this helps and works for someone. I could not find any Razor-specific help on this problem on the web so I thought I'd add this since I figured it out with the help of above link and contributions.
For someone who stumbles upon this - autocomplete="new-password" on password field prevents LastPass from filling the password, which in combination with data-lpignore="true" disables it at all
Try this one:
[data-lastpass-icon-root], [data-lastpass-root] {
display: none !important;
}
Tried the -search rename but for some reason that did not work. What worked for me is the following:
mark form to autocomplete - autocomplete="off"
change the form field input type to text
add a new class to your css to mask the input, simulates a password field
css bit: input.masker {
-webkit-text-security: disc;
}
Tried and tested in latest versions of FF and Chrome.
type="hidden" autocomplete="off"
Adding this to my input worked for me. (the input also had visibility: hidden css).
Update NOV 2021
I have noticed that all LastPass widgets are wrapped in div of class css-1obar3y.
div.css-1obar3y {
display: none!important;
}
Works perfectly for me
None of these work as of 10/11/2022.
What I did was add the following to a fake password field
<input id="disable_autofill1" name="disable_autofill1"
style="height:0; width:0; background:transparent;
border:none;padding:0.3px;margin:0;display:block;"
type="password">
This seems to be enough to minimize the size this element takes on screen (pretty much 0 for me) while still not triggering last pass's vicious algorithm. Put it before the real password field.
I'm sure a variant of this could be used to fool last pass for other fields where we don't need autofill or to suggest a new password.

Form enter key action with lists and AngularJS

In my AngularJS project I have an account details page where you can change your personal account information. This page allows for multiple phone numbers and e-mailaddresses to be supplied. Using mouse input (or tabbing to buttons and pressing them with space bar) works perfectly, however I'd like to add the convenience of the enter key pressing the 'logical' buttons.
My form looks like (accidentally forgot to translate a few items):
A simplified version of the HTML for the form can be found on PasteBin, I've mainly removed the directives for managing the lists.
All buttons are <button> elements except for the cancel button which an <a> to the previous page, and the submit button is <button type="submit">.
When selecting any text box and pressing enter, the first (non-disabled) <button> element is 'clicked'. Meaning if I would change the last name, hit enter, the first phone number would be removed.
When you're in a new entry of phone numbers or e-mailaddresses (the row with the green + button) it should click that button, and if it's disabled do nothing.
When you're in any other text box on the form it should hit the save button, and also if the save button's disabled, do nothing.
Both buttons will be disabled based on form validation.
There'd be no trouble in changing the type of a button from button to submit if that'd help.
I would preferably have an all HTML solution, using just semantics, but I doubt that's really possible. So the logical alternative would be to use an AngularJS directive.
Please do not provide a jQuery or plain JavaScript solution relying on IDs or something like that. I don't want to hack my way around AngularJS, rather embrace it.
In the meantime I've worked on a directive that allows me to declare what I've called 'submit scopes'.
In essence you have actions (inputs) and targets (buttons), they're bound through a service by a key you can assign in the template. To avoid keys from clashing and from simple annoying work you can create a submit-scope which will cause it's children to prepend a unique key to the value they're accessing.
Within a submit-scope you can still override an action to use a global key instead by setting the attribute global-submit="true".
Example code:
<div submit-scope>
<input type="text" submit-action />
<button type="button" submit-target>Pressing enter in the above field will click this button.</button>
</div>
You can view the entire source code and a slightly larger example on Plnkr.
I just tried to replace
<button>Cancel</button>
with
<input type="button" value="Cancel">
and it seems to work correctly...

Is there a way for HTML form to submit default value?

Is there a way (without JS) to make input fields POST a default value in case some input fields were blank when the submit was executed?
In other words: I want to avoid on server side reciving stuff like
"ID=&PW="
<form>
<input name="ID" value="stuff"/>
<input name="PW" value="stuff"/>
</form>
setting the value doesn't really help as the user still can clean the input field by him self.
There is no way to do so in pure HTML. Even if you use JS to setup defaults, someone can intercept and modify HTTP Request.
Never trust input values. You can't assume their values.
No. Not without JavaScript.
...but it would be so easy with JavaScript. Not that I advocate inline scripts, but how about:
<input name="ID" value="stuff" onBlur="this.value=this.value==''
? 'default'
: this.value;" />
The Javascript you see is a simple ternary operator, following the pattern:
myVar = condition ? valueIfTrue : valueIfFalse;
So it's checking if the input is blank. If so, set it to a default; if not, let it be.
You should simply enforce the default value server-side. Otherwise the user will always have the ability to trip you up. You can use javascript to reduce the chance of this happening but javascript will always be exposed to the user. Html doesn't have a method for this and even if I'm wrong and it does, or does in the future - such a thing is ALSO exposed to the user.
You're talking about using strtok. I'd recommend simply breaking the tokenizing out twice. Once for the &, and then within each of those results again for the = (obviously if the second result of each pair is blank or null, substituting the default). Otherwise, tokenize it yourself, still on the server.

Creating a dynamic html form

I would like to create a form that changes dynamically.
I have a form for creating a project (with fields such as: project_name, project_description...) and the project can have any amount (bigger or equal to 0) of categories.
What i want is to display a button which would give the user the option to add another category field. In addition I would also like the option for category fields to be "deleteable" by the user (if he changes his mind or made a mistake). What would be the best way to do so. I would like an Ajax type solution.
My solution so far is to leave an empty div beneath the last category and onclick of the button to load another field into that div with yet another div which will be used for the next div. Not to happy with this solution since i now have to count how many fields I have and give each div it's own id which complicates the matter even more.
Is there a more simple solution to this?
If you are trying to add fields dynamically with a button, you can easily do so by doing something like the following:
HTML:
<form>
<p>
<label>Name:</label> <input type="text">
<label>Age:</label> <input type="text">
<span class="remove">Remove</span>
</p>
<p>
<span class="add">Add fields</span>
</p>
</form>
JS:
$(".add").click(function() {
$("form > p:first-child").clone(true).insertBefore("form > p:last-child");
return false;
});
$(".remove").click(function() {
$(this).parent().remove();
});
Demo: http://jsfiddle.net/UeSsu/1/
I started to write a form generator is based on a definition in JSON a while back. It works but could use some enhancements. It's written using Prototype.js but it wouldn't be a huge effort to port it over to jQuery.
You're welcome to steal the code. (just view source)
I've done something similar. To delete fields I didn't really removed fields. I just hidden them with a display:none and had a hidden input "delete" that I trigger to true. Then, the page receiving the result knows which field is to be deleted in the database.
They are not deleted before the form is submitted. It's like a "two pass" conception. But if you don't really need a true ajax, it works fine. Otherwise you need your JS remove function to call the server and tell to delete the field with its id. A little bit more complex to code.