Chrome auto formats input=number - html

I have a web application where I'm specifying an input field to be a number using the HTML5 property type="number".
<input type="number" value="123456" />
By specifying the type, Chrome automatically formats the value to include a comma (123,456). In other browsers it does not format the number, but it also does not prevent non-numeric characters.
In this case, I don't want the comma to be added. Is there any way to turn off localized formatting?

This is occurring because of the behavior associated with the HTML5 number input type in Chromium, and you are definitely not the only one that doesn't care for this.
I have worked around this issue in the past by using the text type. For example, this has worked well (tested just now in Chrome 11.0.696.71):
<input type="text"
placeholder="Enter Text"
name="inputName"
pattern="[0-9]*">
This behavior of the number type (to me, at least) is definitely a bug, because the HTML5 standard specifies the number should have the following value when formatted for display:
The algorithm to convert a number to a string, given a number input, is as follows: Return a valid floating point number that represents input.
And the standard defines a "valid floating point" number here, and as far as I can see, including grouping characters is not expected.
Update
I've isolated the issue to the following code down in the guts of WebKit. I've included the line that fixes the issue here as well:
// From LocalizedNumberICU.cpp
String formatLocalizedNumber(double number, unsigned fractionDigits)
{
NumberFormat* formatter = numberFormatter();
if (!formatter)
return String();
UnicodeString result;
formatter->setMaximumFractionDigits(clampToInteger(fractionDigits));
formatter->setGroupingUsed(FALSE); // added this line to fix the problem
formatter->format(number, result);
return String(result.getBuffer(), result.length());
}
I'm on vacation next week, but plan on submitting this patch to the WebKit team when I return. Once they (hopefully) accept the patch, Chromium should pull it in as part of its normal refresh process.
You can see the original code here, the patched revision here, and the diff of the
original file and the patched file here. The final patch was created by Shinya Kawanaka.

There are a couple of extra properties that you can check including valueAsNumber.
Chrome attempts to provide you with the best input method possible based on the input type. In this case, number also has some extra abilities such as toggle up and down.
The point of this, is if the number isn't valid, you will be able to detect that there are errors and also set the styling input[type=number]:invalid { background-color: red; }

You could try ...
<input type="text" pattern="[0-9]*" value="123456" />
which will enforce the entry of 0-9 on Firefox 4 on the desktop as well as an iPhone; I don't have Chrome at hand to try it on, but it should do the same.

Number is one of the new HTML5 input types. There are loads of these - email, date, time, url, etc. However, I think only Chrome has implemented them so far. The others fall back to using the default type (text).
For more info about HTML5 input types: http://diveintohtml5.ep.io/forms.html
If you want to disable it on Chrome, you could leave as text and change it to number if the user device is a handheld. Since it's not a usability killer if the user device sniffing gives the wrong result, you shouldn't have any problems.

Refer to my answer for this similar question.
I believe using <input type="tel" /> is most logical for avoiding this pitfall currently. The other options are intriguing and slightly new to me (like the pattern attribute) but I found them to be unsatisfactory for my design. You can look at a screenshot of a mobile application I complete for Hilton not too long ago here (it's actually shown in the answer I first referenced).

Here is a whole list of regular expressions that you can plug into the "pattern" attribute of the html input tag: HTML5 Pattern
Here is how I am using a pattern to format the number two decimal points:
<input type="number" pattern="\d+(\.\d{2})?" />
Unfortunately it doesn't seem to work quite right on the iPad.

Try this:
if (navigator.userAgent.toLowerCase().indexOf("chrome") >= 0) {
$('[type=number]').attr('type', 'text').attr('pattern', '[0-9]*');
}

Why would you want to disable localized formatting? If you want a different format, just change the localization settings of your PC. Why would a user not be interested to show a number in his or her local format? This is definitely not a bug in Chrome but a feature!
It seems to me you are not really using a "number" as input but rather a "text" code with a pattern. See the other posts for suggestions to that.

Related

ng-form and autocomplete="off"

I have an angular form like this
<ng-form name="AddTaskForm" autocomplete="off">
......
</ng-form>
However when I begin entering data, chrome is still prompting me with previously entered values.
How can I prevent chrome (and all browsers) from showing any drop down on my input with previously entered values?
I did some search and found that people were writing custom directives, but not sure if this is really required.
Despite autocomplete being a pretty well defined part of the HTML5 spec, Chrome has flip-flopped on how they use the autocomplete property. Originally honoring autocomplete="off" (2013), they then decided that developers must be using it wrong and the browser should just ignore it.
This doesn't mean there aren't very valid cases where you don't want the browser autofilling data (e.g. on CRM systems), but by and large, we see those as the minority cases. And as a result, we started ignoring autocomplete=off for Chrome Autofill data.
(Source: Chromium bug from 2015 marked as WontFix)
According to the Priority of Constituencies:
In case of conflict, consider users over authors over implementors over specifiers over theoretical purity. In other words costs or difficulties to the user should be given more weight than costs to authors; which in turn should be given more weight than costs to implementors...
...Which leaves us developers in the unfortunate spot of finding a work-around. This article from MDN outlines the current state well, and offers this solution of setting autocomplete to new-password:
If an author would like to prevent the autofilling of password fields in user management pages where a user can specify a new password for someone other than themself, autocomplete="new-password" should be specified, though support for this has not been implemented in all browsers yet.
I'm not sure how long this will remain valid, but for now (tested in Chrome 53 in September 2016) this is the easiest solution:
<input type="password" name="someName" autocomplete="new-password" />
Edit: Note: This has the side-effect of asking the user to save the password, possibly overwriting an existing password. So while it does "prevent the autofilling of password fields" it does not remove the element from the autocomplete mess altogether.
Edit: Updated Info: Newer versions of Chrome once again respect the autocomplete=off attribute, as Alexander Abakumov pointed out in his answer. He had it working for Chrome 68, works on Chrome 70 for me.
autocomplete="off" works now. Tested in the current Chrome 70.0.3538.110.
Demo.
It looks Chrome ignores the autocomplete property for individual inputs; the old work around was to add autocomplete=off on the entire form like you have done (which is a pretty incomplete solution as it will then add this functionality to all inputs contained in the form, which may not be desired).
Anyway, from this post it looks like that work around is no longer available, so it looks like you may need a directive. I know this may not be what you're looking for, but I think it's your only option for chrome.
myApp.directive('autocomplete', function() {
return {
restrict: 'A',
link: function( $scope, el, attr ) {
el.bind('change', function(e) {
e.preventDefault();
}
}
}
});

How to set HTML5 type="date" input fields (e.g. in Chrome) using Selenium/Protractor?

I want to update the date value (displayed as mm/dd/yyyy with only the number portions modifiable) of some HTML5 date form fields:
<input type="date"/>
in my Selenium/Protractor tests. I've tried using sendKeys for this but (on Chrome) have not been successful so far.
Is there a way to do this using sendKeys? Or some other way to do it?
Using Chrome on Mac with Protractor, the following approach has worked for me.
Template (html5)
<input type="date" placeholder="Due Date" ng-model="newLesson.dueDate">
Test
this.newLessonDate = element( by.model('newLesson.dueDate') );
this.newLessonDate.sendKeys('01-30-2015');
I kept getting errors until I entered the date format as '01-30-2015'.
Seems like the best approach at the moment is to update the input field without touching its UI representation.
For normal Selenium this approach appears to work (as the UI updates to match):
selenium.executeScript('document.getElementById("continuousFrom").value = "2050-01-01"');
selenium.executeScript('document.getElementById("continuousTo").value = "2050-01-14"');
My case is a bit more tricky because I'm using Angular and Protractor and the above approach didn't result in the model being changed. So I've ended up with this (even uglier) approach that modifies the model directly:
browser.waitForAngular();
browser.executeScript('var scope = angular.element($("#continuousFrom").get(0)).scope(); scope.dates.from = "2033-01-01"; scope.$apply();');
browser.executeScript('var scope = angular.element($("#continuousTo").get(0)).scope(); scope.dates.to = "2033-01-14"; scope.$apply();');
Also this is in a Protractor test and it took me a while to realise that the executeScript call does not wait for Angular to have finished creating the new DOM itself - hence the waitForAngular to make sure the ids are there.
I had the same issue today, and I found the solution here http://www.guru99.com/handling-date-time-picker-using-selenium.html
The solution is to send only the date numbers, for example instead of sending "2015-06-12" you need to send "20150612".
I finally found a working solution, use Date.prototype.toLocaleDateString:
// Remember that Date months are 0 based.
var keys = selenium.executeScript(
'return (new Date(2016, 2, 7)).toLocaleDateString()'
);
sendKeys(keys);
I had a Credit Card expiry date with month and year only. The solution worked form me is using protractor.Key.TAB to move the cursor and input like below
element(by.id('cc-expiry')).sendKeys('12', protractor.Key.TAB, '2019');
So in your case you can try
element(by.id('cc-expiry')).sendKeys('12', protractor.Key.TAB, '12', protractor.Key.TAB, '2019');
Selenium is meant to mimic user interaction and not setting attributes.
However updating the DOM elements by setting the type could be done using Javascript
document.getElementById("someID").setAttribute("type","date")
I had an issue where sendKeys() was working, but the input was always $invalid. The only format that worked for me was 'YYYY-MM-DD' i.e. '2015-08-05'. Any other variation on that format; slashes instead of hyphens, no delimiter, etc. remained invalid.
Even though I'm using Firefox version 37.0.2 which clearly supports HTML5 input type=date, It's noteworthy that the docs say:
"In browsers that do not yet support the HTML5 date input, a text element will be used. In that case, text must be entered in a valid ISO-8601 date format (yyyy-MM-dd), for example: 2009-01-06."
FWIW This answer is the opposite of what worked for me.

Can a plain HTML link (A) reload a page without query string values

I want to essentially reload the page I'm on without some of the query strings which might be present (thus changing content on the page). I've found that leaving the href tag empty like so href="" works, but I wonder if this a safe method, ie. does it work in older browsers?
Edit:
In fact scrap that, leaving it blank doesn't work (some great testing by me there). So, I guess my question now is, how can I reload the same page without any query string values? And without knowing the file name and without using Javascript. I guess I'm looking for something like / or #.
I think I know a trick. When you use a <form> tag with empty action and no (or GET) method parameter it will use your url but will replace the GET parameters (query string) with the values in your form, so:
On page http://example.com/foo.html?query=string
<form action="">
<input type="submit" value="hello" />
</form>
If you click on the button you will get to:
http://example.com/foo.html (Firefox 8)
http://example.com/foo.html (Internet Explorer 9)
http://example.com/foo.html? (Chrome 15)
http://example.com/foo.html? (Safari 5)
Edit: the trailing question mark is likely a Webkit issue.
There is an interesting post about empty URLs. It refers to RFC 3986, which defines URLs.
Basically, from a spec point of view you should be save, in that href="" references the current page.
I assume that all browsers adhere to this, but this is just an educated guess. The HTML5 spec also allows empty URLs.
Edit: To meet the updated question, (almost) removing the query string can be done with href="?".
Empty href is an empty relative uri which should be resolved to base uri without problems.
Yes, you can try this: href="#".

Google Chrome input type="date"

I have almost no knowledge of web programming, but I have been tasked to solve something on my company's website. Apparently, I have an issue with browsers using HTML5 on a legacy site using type="date" and I need to find a way around it.
My site has a lot of date fields that the user must input like such:
<input type="date" name="DateStart" size="15" value="8/30/2011">
In every browser we currently use except Chrome, this works just fine. Chrome is the only browser that supplies rolling buttons to scroll through the date. What I see on the back end of this is an attempt to do this:
FormatDateTime(DateStart, 2)
I get an invalid date error which means that we cannot use Chrome to fill out this form. Is there a way around this problem?
Actually chrome's support for 'date' is broken. (See here). At least for the moment.
The use of 'date' in the HTML is absolutely fine - browser's which do not know of or support an input type are supposed to fallback to type='text'.
Currently chrome partially supports date, in a way that is essentially broken (it adds a couple of up-down buttons, but no datepicker.)
Of course you do need to bear in mind that if you are using type='date', and if the browser supports it, then you'll want to disable whatever datepicker support you'd otherwise be using.
UPDATE (6 Feb 2012):
It looks to me like this is now fixed. Chrome no longer claims to support input type='date', and does not provide the partially complete implementation.
UPDATE (17 Aug 2012):
Chrome does now have input type="date" support, and it's more functional this time.
Chrome does not have issues with date-inputs, you are using the wrong date-format, sir. Chrome isn't the only browser until today which has support for the new HTML5 inputs. Opera for example displays a dropdown with a calendar on inputs with type="date".
Also the size-attribute does not exist on HTML5-date-inputs.
The value field for the input type = input needs to be in the format yyyy-MM-dd. Check the W3 standards on this.
This means you must do something like DateTime.Now.ToString("yyyy-MM-dd"). in your code, I would suggest a custom HtmlHelper.
The format of the date in the browser is completely dependent on your system settings.
Use this date format : date("Y-m-d");

Is there a valid way to disable autocomplete in a HTML form?

When using the xhtml1-transitional.dtd doctype, collecting a credit card number with the following HTML
<input type="text" id="cardNumber" name="cardNumber" autocomplete='off'/>
will flag a warning on the W3C validator:
there is no attribute "autocomplete".
Is there a standards-compliant way to disable browser auto-complete on sensitive fields in a form?
Here is a good article from the MDC which explains the problems (and solutions) to form autocompletion.
Microsoft has published something similar here, as well.
To be honest, if this is something important to your users, 'breaking' standards in this way seems appropriate. For example, Amazon uses the 'autocomplete' attribute quite a bit, and it seems to work well.
If you want to remove the warning entirely, you can use JavaScript to apply the attribute to browsers that support it (IE and Firefox are the important browsers) using someForm.setAttribute( "autocomplete", "off" ); someFormElm.setAttribute( "autocomplete", "off" );
Finally, if your site is using HTTPS, IE automatically turns off autocompletion (as do some other browsers, as far as I know).
Update
As this answer still gets quite a few upvotes, I just wanted to point out that in HTML5, you can use the 'autocomplete' attribute on your form element. See the documentation on W3C for it.
I would be very surprised if W3C would have proposed a way that would work with (X)HTML4. The autocomplete feature is entirely browser-based, and was introduced during the last years (well after the HTML4 standard was written).
Wouldn't be surprised if HTML5 would have one, though.
Edit: As I thought, HTML5 does have that feature. To define your page as HTML5, use the following doctype (i.e: put this as the very first text in your source code). Note that not all browsers support this standard, as it's still in draft-form.
<!DOCTYPE html>
HTML 4: No
HTML 5: Yes
The autocomplete attribute is an enumerated attribute. The attribute
has two states. The on keyword maps to the on state, and the off
keyword maps to the off state. The attribute may also be omitted. The
missing value default is the on state. The off state indicates that by
default, form controls in the form will have their autofill field name
set to off; the on state indicates that by default, form controls in
the form will have their autofill field name set to "on".
Reference: W3
No, but browser auto-complete is often triggered by the field having the same name attribute as fields that were previously filled out. If you could rig up a clever way to have a randomized field name, autocomplete wouldn't be able to pull any previously entered values for the field.
If you were to give an input field a name like "email_<?= randomNumber() ?>", and then have the script that receives this data loop through the POST or GET variables looking for something matching the pattern "email_[some number]", you could pull this off, and this would have (practically) guaranteed success, regardless of browser.
No, a good article is here in Mozila Wiki.
I would continue to use the invalid attribute. I think this is where pragmatism should win over validating.
How about setting it with JavaScript?
var e = document.getElementById('cardNumber');
e.autocomplete = 'off'; // Maybe should be false
It's not perfect, but your HTML will be valid.
I suggest catching all 4 types of input:
$('form,input,select,textarea').attr("autocomplete", "off");
Reference:
http://www.w3.org/Submission/web-forms2/#the-autocomplete
http://dev.w3.org/html5/markup/input.html
If you use jQuery, you can do something like that :
$(document).ready(function(){$("input.autocompleteOff").attr("autocomplete","off");});
and use the autocompleteOff class where you want :
<input type="text" name="fieldName" id="fieldId" class="firstCSSClass otherCSSClass autocompleteOff" />
If you want ALL your input to be autocomplete=off, you can simply use that :
$(document).ready(function(){$("input").attr("autocomplete","off");});
Another way - which will also help with security is to call the input box something different every time you display it: just like a captha. That way, the session can read the one-time only input and Auto-Complete has nothing to go on.
Just a point regarding rmeador's question of whether you should be interfering with the browser experience: We develop Contact Management & CRM systems, and when you are typing other people's data into a form you don't want it constantly suggesting your own details.
This works for our needs, but then we have the luxury of telling users to get a decent browser:)
autocomplete='off'
autocomplete="off" this should fix the issue for all modern browsers.
<form name="form1" id="form1" method="post" autocomplete="off"
action="http://www.example.com/form.cgi">
[...]
</form>
In current versions of Gecko browsers, the autocomplete attribute works perfectly. For earlier versions, going back to Netscape 6.2, it worked with the exception for forms with "Address" and "Name"
Update
In some cases, the browser will keep suggesting autocompletion values even if the autocomplete attribute is set to off. This unexpected behavior can be quite puzzling for developers. The trick to really forcing the no-autocompletion is to assign a random string to the attribute, for example:
autocomplete="nope"
Since this random value is not a valid one, the browser will give up.
Documetation
Using a random 'name' attribute works for me.
I reset the name attribute when sending the form so you can still access it by name when the form is sent. (using the id attribute to store the name)
Note that there's some confusion about location of the autocomplete attribute. It can be applied either to the whole FORM tag or to individual INPUT tags, and this wasn't really standardized before HTML5 (that explicitly allows both locations). Older docs most notably this Mozilla article only mentions FORM tag. At the same time some security scanners will only look for autocomplete in INPUT tag and complain if it's missing (even if it is in the parent FORM). A more detailed analysis of this mess is posted here: Confusion over AUTOCOMPLETE=OFF attributes in HTML forms.
Not ideal, but you could change the id and name of the textbox each time you render it - you'd have to track it server side too so you could get the data out.
Not sure if this will work or not, was just a thought.
I think there's a simpler way.
Create a hidden input with a random name (via javascript) and set the username to that. Repeat with the password. This way your backend script knows exactly what the appropriate field name is, while keeping autocomplete in the dark.
I'm probably wrong, but it's just an idea.
if (document.getElementsByTagName) {
var inputElements = document.getElementsByTagName("input");
for (i=0; inputElements[i]; i++) {
if (inputElements[i].className && (inputElements[i].className.indexOf("disableAutoComplete") != -1)) {
inputElements[i].setAttribute("autocomplete","off");
}
}
}
I MADE THIS WORK IN 2020!
I basically create a css class that applies -webkit-text-security to my inputs.
Here's the link to a more recent discussion:
https://stackoverflow.com/a/64471795/8754782
This solution works with me:
$('form,input,select,textarea').attr("autocomplete", "nope");
if you want use autofill in this region: add autocomplete="false" in element
ex:
<input id="search" name="search" type="text" placeholder="Name or Code" autcomplete="false">
Valid autocomplete off
<script type="text/javascript">
/* <![CDATA[ */
document.write('<input type="text" id="cardNumber" name="cardNumber" autocom'+'plete="off"/>');
/* ]]> */
</script>