How to tell Chrome form does not contain credit card fields? - html

Chrome is being overzealous and thinks my HTML form contains credit card information and thus proposes to fill it in with credit card information.
Are there any attributes that I can use to tell Chrome that there is no credit card information to be filled in, in this form?
The field names it is trying fill in credit card information in are:
reg_id (it puts in a CC number here)
emergency_first_name (it puts in first name here)
emergency_last_name (it puts in last name here)
I don't want to have to disable autocomplete if I don't have to.
The frustrating thing here is the Chrome 'knows better' attitude, where it ignores any value to autocomplete, including off:
<input autocomplete="off" value="" size="10" maxlength="10" id="id_reg_id" name="reg_id" type="text">
Edit: updated following answers.

try
input type="custom"
or use textarea with a single row and resize off

Your browser shouldn't remember your credit card number by default -- I can only assume that you entered into a field that had a 'generic' autocomplete value on it. You can always force your browser to forget this information by simply hitting Delete when selecting it (with the arrow keys) in the dropdown of pre-fill options.
As for preventing it appearing in certain fields, it depends on what information you want each field to hold, but there's a wide array of autocomplete values that you can use. You can use number for IDs, and the other two fields you mentioned actually come with specialised autocomplete values, given-name and family-name:
<input name="reg_id" autocomplete="number" />
<input name="emergency_first_name" autocomplete="given-name" />
<input name="emergency_last_name" autocomplete="family-name" />
If number just won't cut it, you can also make use of a JavaScript regular expression to further restrict input:
const regex = new RegExp("^[a-zA-Z]+$");
const form = document.getElementsByTagName('form')[0];
const reg_id = document.getElementsByTagName('input')[0];
form.addEventListener('click', function(e) {
e.preventDefault();
if (regex.test(reg_id)) {
this.submit();
}
});
<form>
<input name="reg_id" autocomplete="number" />
<input name="emergency_first_name" autocomplete="given-name" />
<input name="emergency_last_name" autocomplete="family-name" />
</form>

I have been banging my head against the desk for a while because of this. We have forms to enter Instruments test data, and a field called "Test Card Number", as well as "Kit (Exp. Date)". Guess what Chrome thinks these fields are for?
Needless to say, I'm pretty sure the users would be VERY upset to see chrome us trying to pull their CC information when they're inputing clinical research data.
Even autocomplete="new-password" and autocomplete="nope" are failing to do any good, here.
I tried to load the field with no label and add it dynamically in javascript. No dice. Used html entities instead of characters. Nope.
Well, after a few hours of scouring the web with no solution in sight, I figured one out: insert a few random - within each word of the offending labels. (For me, with Test Card Number, it had to be in BOTH Card and Number. Test was fine left alone).
One could easily write a javascript extension/utility function to split the html of an offending label and slap that invisible span down the middle (and one to remove it in case of needing to use the label value).
Something like this (using jQuery and old js standards because we support old browsers, with no verifications if label is missing or empty, so adapt accordingly. In fact, I'm sure a regex or some other fancy stuff could be used, but I don't have the time to fiddle around with it atm):
jQuery.fn.breakAutofill = function () {
var $lbl = $("label[for='" + this[0].id + "']"),
finalText = $lbl.html().split(" "),
foilSpan = "<span style='display:none;'>-</span>";
for (var idx in finalText) {
var textVal = finalText[idx],
midPos = Math.floor(textVal.length / 2);
finalText[idx] = textVal.substr(0, midPos) + foilSpan + textVal.substr(midPos);
}
$lbl.html(finalText.join(" "));
}
Which you can then call on document ready :
$("your_input_selector").breakAutofill();
I hope that helps someone.

Related

Best accessible way to show a default for a form field

What's the best/recommended way to indicate a form field will have a particular default value if you don't fill it out? I'm especially thinking about fields that are dynamic based on other fields, and wanting it to be correctly accessible.
Think a URL slug. When creating an account, if you fill the field out then that's fine. If you don't, a value will be generated based on your username. But it won't be the same as your username, just generated from it.
Actually setting the form field seems bad because it makes it less obvious you can change it yourself.
I'm not sure if placeholder text works here, but I assume not. I could do an aria-labelledby pointing to something that says "Default value: xyz" but I'm not sure if that will work, or how well it will be understood by screen readers - especially if it's changing automatically.
Cheers
The best way to do this is to populate the input and expose the fact that it was automatically filled in via the label as an extra bit of information.
Labels on inputs are read once you focus the related input.
For this reason we can generate labels "on the fly" to contain whatever we want.
As such the best option here would be to generate the label on blur of the first input that the second input depends on.
Within the label we add the instructions that explain why this input is already filled in.
We then auto populate the second input based on the input of the first.
In the below example I have appended "URL" to the first input value in order to simulate some sort of transformation from username to URL.
I also remove the explanation in parenthesis if the user has changed the second input value.
$('#iUsername, #iUserURL').on('blur', function(){
var ElUserName = $('#iUsername');
var ElUserURL = $('#iUserURL');
if(ElUserURL.val() == ""){
ElUserURL.val(ElUserName.val() + "URL");
$('label[for="iUserURL"]').text("user url (you can change this if you want, we have set it as " + $('#iUsername').val() + "URL)");
}else if(ElUserURL.val() != ElUserName.val() + "URL"){
$('label[for="iUserURL"]').text("user url");
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="iUsername">User Name</label><br/>
<input id="iUsername" /><br/>
<hr/>
<label for="iUserURL">User URL</label><br/>
<input id="iUserURL" /><br/>
<hr/>
<label for="itest">I have added this third input just so you have something to tab too, it does not add anything to the fiddle</label><br/>
<input id="itest" />

Can ng-invalid parameters work similarly to a conditional ng-required?

This is my first time asking something here so I tried to put as much information as possible to help in my predicament.
I have a question pertaining to an HTML form I'm building that uses some AngularJS which I'm learning more about as I go along.
The form itself uses some mathematics in it which I'm generating a dividend from 2 fields at a time while also factoring in a total number of people. The page itself will generate the dividend on the page itself to give the user a real-time look at their math, so there are already ng-models on most if not all fields. The catch is that the dividend itself for the fields cannot exceed 1 as I'm doing percentages from 0-100%.
Previously if the numerator was higher than the denominator, or the denominator was higher than the max amount of people I would have an explanation field that was previously be a non-required field toggle to required like so:
<textarea rows="4.5" cols="50" id="My_Fields_Notation__c" tabindex="11"
name="My_Fields_Notation__c" maxlength="255"
ng-required='fieldDen < fieldNum || fieldDen > numberOfPeople'
type="text"></textarea>
My question is if I was to remove the ng-required on this field and add a separate ng-invalid on the numerator and denominator each
(ng-invalid='fieldDen < fieldNum' on the numerator and ng-invalid='fieldDen > numberofPeople' on the denominator)
Would that cause the field to not submit if those parameters are met? (ex. if a user has Numerator: 100, Denominator: 50 and/or Number of people: 100, Denominator: 101 would the form not submit since the numbers don't meet those parameters I'm trying to set)
EDIT: If this helps to better explain my situation. I have several numerators and denominators for this form all with their own ng-model names.
The numerator cannot be higher than the denominator
The denominator cannot be higher than the number of people
If either or happens on any of the numerators and denominators, I want to block submission of the form
At the same time the form is in a drupal page and the only JS file I've been able to successfully call in was the angular file so far, so I think any additional script needs to be coded in the page itself if I need to create any controllers.
If your form submit's or doesn't submit depends on how you do the submission.
It will submit if you use:
<button ng-click='mySubmitFunction()'>Submit</button>
It will not submit if you use:
<button ng-click='formValid() && mySubmitFunction()'>Submit only if valid</button>
To check if your validation condition is met add a validation function:
$scope.formValid = {
return ($scope.fieldDen < $scope.numberofPeople) && ($scope.fieldDen < $scope.fieldNum)
}
If you only want to validate a certain input you can also write a validation directive for this. This let's you show i.e. custom error messages if a certain condition is not met like the format, example plunkr taken from the docs: http://plnkr.co/edit/7ewLoTgWWwyeo7HAvTqU?p=preview
you can add a ngPattern to the input you want to validate and then you just can use the $valid given by angularjs to validate that element.
<form name="myForm">
<input type="text" name="userName" ng-model="user.name" ng-pattern="{string}" >
</form>
//to test just use
{myForm.userName.$valid}

Accessibility of UI Widget that is a composite of input field and button

We have UI widget that is a composite of input field and an icon. This widget is basically meant to be used as a form field to let users select a value from a huge list of values. Users can either type a value in the input field or click on the icon to launch a dialog with all the possible value list. Selecting a value in this dialog will set the value in the input field. Users can also type a partial value in the input field and tab-out in which case, the widget tries to autocomplete the value entered and if it doesn't succeed, it will launch the same dialog as user clicking on the icon.
How would I make such a widget accessible through screen readers? There doesn't seem any role or any other aria attribute which seems to be tailor made for my usecase. At the minimum, I would expect the users using screen readers to know that this widget has an helper icon from where a value can be selected.
I am reading this as an order database/form, where call takers can just select type in the customer number or fill out the 10+ fields. And if the caller doesn't know their ID or whatever, the call taker can do a search.
I recommend removing the autocomplete on tab functionality, because that wouldn't too fun for some. I'd code it like:
<p id="instr">Put instructions here</p>
<label for="user">Look Up User</label> <input id="user" aria-describedby="instr">
<input type="button" value="Populate Form">
<input type="button" value="Search">
I made an answer about modals quite some time ago, that should get you started. The listing in the dialog may not be the most fun to wade through. I'd recommend either updating this question or making a new one for that part.
Interesting and challenging.
To start with make sure icon has an alt text which explains its role - this is assuming it is an image. If not use title attribute to explain its role.
Add a title attribute to the input box and succinctly mention that user can also chose values using icon or partially type its value to autocomplete it.
If your form design allows instructions to be placed next to the form fields place a descriptive text right next to the widget.
These recommendations may not make it entirely accessible but will surelytake you close to where you want to be. I'm hoping that this widget will be used in more than one place in your project allowing user to get accustomed to it.
Last one to consider is to see if any aria role fits your widget controls in any way.

HTML5 datalist value vs. inner-text

I have an issue that is manifesting between Chrome and Firefox's handling of the HTML5 datalist element.
I may be abusing it, which Firefox is handling the way I expect, but Chrome is not. I have not tried it on Opera. This is for an in-house page, so I can control the browser being used.
I set a value, as well as the inner-text, as in:
<input list="Names" placeholder="Enter Name or ID" name="txtSearchValue" autocomplete="off"/>
<datalist id="Names"><%=OptionsList%></datalist>
The server-side value "OptionsList" gets built dynamically from a database query. The end result looks, approximately, like this:
<option value="123">Sam's Fresh Sandwiches</option>
<option value="234">Sawatdee</option>
etc.
On Firefox, I can type the letters "S" then "A" (case insensitive) and both of the above entries will appear. As soon as I type a "W" or select Sawatdee with the mouse, the text box is populated with 234. This is what I desire to have happen - as I want 234 sent back to the server and not Sawatdee. It also works if I type "A" then "T".
On Chrome, I can type all the letters I want, but nothing will appear in the list. However, if I type a 2, only the second entry will appear; but in the list it will show a 2 followed by Sawatdee.
Am I over-using/abusing the datalist or does Chrome have a problem with it? Or is Chrome handling it as it is technically supposed to and I've found a Firefox bug?
I'm trying to do something similar. I think the issue is the datalist isn't spec'ed to work like a dropdown option list. One work around is that you generate both an <%=OptionsList%> and then an array <%=OptionListValues %>...so once you get the text value in your input, you can use javascript to look for it's key in the OptionListValues and send the key instead of the description back to the server. Pain in the rear and adds an extra data load on the client side, though I guess you could do this server side as well (send the text in the input and then lookup the text and get the key on the server side).
Too bad Chrome doesn't work like FF on this, maybe in the future the browsers will work like Mozilla on this.
Or you can do something like this. Say you have the following input/datalist
<input id="datalisttestinput" list="stuff" ></input>
<datalist id="stuff">
<option id="3" value="Collin" >
<option id="5" value="Carl">
<option id="1" value="Amy" >
<option id="2" value="Kristal">
</datalist>
You can use jQuery (or plain javascript) to dig out the id value...here is my example, I'm sure this could be optimized a bit.
function GetValue() {
var x = $('#datalisttestinput').val();
var z = $('#stuff');
var val = $(z).find('option[value="' + x + '"]');
var endval = val.attr('id');
alert(endval);
}
That should get you going.
Slightly modifying infocyde's answer to use a hidden field to contain the value which ultimately gets sent to the server.
$('#inputStates').change(function(){
var c = $('#inputStates').val();
$('#inputStates').val(getTextValue());
$('#statesHidden').val(c);
});
function getTextValue(){
var val = $('#inputStates').val();
var states = $('#states');
var endVal = $(states).find('option[value="' + val + '"]');
//depending on your logic, if endVal is empty it means the value wasn't found in the datalist, you can take some action here
return endVal.text();
}

HTML form doesn't contain a form submit button name when using the Enter key

My ASP.NET MVC 3 website has code on the server side that checks for the name of the submit button clicked to submit the form. The code works when I use the mouse to click the button, but when I use the Enter key, the form gets posted, but the request doesn't contain the name of the submit button.
Is there some attribute I can set on the submit button to get this to work for both clicking and using the Enter key?
Here is my HTML:
<div>Search:</div>
<form action="/Item/Search" method="post">
<input class="fulltextsearch" id="FTSearchText" name="FTSearchText" type="text" value="" />
<input type="submit" value="Go" name="FTSearchButton" />
</form>
</div>
On the server side, I have a custom model binder that uses the following code to determine if the user clicked the submit button.
// See if the value provider has the required prefix
var hasPrefix = bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName);
var searchPrefix = (hasPrefix) ? bindingContext.ModelName + "." : string.Empty;
var searchButton = GetValue(bindingContext, searchPrefix, "FTSearchButton");
// If this value doesn't have value, the user didn't click the button so exit
if (string.IsNullOrEmpty(searchButton)) {
return null;
}
private static string GetValue(ModelBindingContext context, string prefix, string key) {
var result = context.ValueProvider.GetValue(prefix + key);
return result == null ? null : result.AttemptedValue;
}
Here is the problem I'm having with this. I have a page that displays a list of items. I have a 'search' textbox and a submit button in an HTML form. When the user enters text in the textbox and clicks the search button or uses the enter key, the page posts the form data via HTML GET, and returns the first eight records found. The page then displays page links for additional pages. The problems is that when the user clicks a page link, the form data is all blank, and my filter information is lost (the form isn't posted with the form value when using these links). So, I end up displaying a blank list of items (blank searches returns zero results) instead of paging the data.
By adding the check for the button name in my form data, I could determine whether or not to simply page the data, or do a new look up.
I wouldn't rely on this. There are plenty of documented bugs with this scenario. Just add a hidden field with name='submit'. That way it wouldn't be too hard to recode the backend.
<input type='hidden' name='submit' value='FTSearchButton'/>
So, I researched this last night and almost got somewhere. Then this morning, I really did get somewhere and here's where I ended up.
Apparently the W3C standards for form submission are pretty lax when describing the functionality as it relates to the Enter button and submitting forms. It seems they determined that
When there is only one single-line text input field in a form, the user agent should accept Enter in that field as a request to submit the form.
So that leaves a lot of wiggle room for the browser makers. Today, virtually all browsers support using the Enter key to submit a form, whether the form contains one or more single line text input boxes.
The problem I'm having is more or less unique to Internet Explorer, and only when the form contains one, single-line text input control. For whatever reason, Microsoft decided that when Internet Explorer submits a form like this, it doesn't include the submit button's name/value pair in the post body. However, it does include the button's name/value pair if the user clicks the submit button --or-- uses the Enter key, and the form contains more than one single-line text input control.
So, the only solution I can think of or find suggested is to add a second single-line text input to my form, and then set the the style to
visibility: hidden; display: none;
My form now has two single-line text input controls, so the form will post with the name/value pair in the form body, regardless of whether or not the user used the Enter key or clicked the submit button.
So, we have a workaround that was discovered by ASP.NET developers. It seems the key/value pair is required by ASP.NET web-forms to fire the click event, so this work around isn't something new, albeit not my favorite way to do things.