How does form auto-filling in the browser work? - browser

How does form autofill work in modern web browsers? Which are the most common techniques used in browsers that implement automatic form filling?
-- EDIT --
The question is not about autocomplete, is about form autofilling, which cares not only about the previously inputted values but also considers the meaning and structure of the field to be completed. Google Chrome implementation, for example, tries to parse the inputted fields to guess their type and structure. Or at least is that what I understood from the code linked above.

Take a look over at this answer by kmote.
Highlight is that the browser looks at the field's name tag and makes an educated guess at what sort of data would go there (regex matching is a good naive way to do this). Chrome is working to get some sort of standardization so that this isn't quite as hit-or-miss.

Different technologies and browsers use various methods to both calculate what to display as well as how they display it, but some sources to check out are:
Google's high-level description
How to implement it with jQuery (note that there is a jQuery autocomplete plugin as well).
If you are looking into implementing it (or just using it) yourself, I would highly recommend taking a look at the plugin.

The first element of answer is simply the non standard HTML form's autocomplete attribute that was introduced with Internet Explorer a few years ago.
Ironically, you can read a good history an introduction on mozilla site here: The autocomplete attribute and web documents using XHTML

This question is pretty old but I have an updated answer for 2017!
In order to trigger autocomplete, all you have to do is name it right.
The following answer is from my original answer from here: https://stackoverflow.com/a/41965106/1696153
Here's a link to the official current WHATWG HTML Standard for enabling autocomplete.
Google wrote a pretty nice guide for developing web applications that are friendly for mobile devices. They have a section on how to name the inputs on forms to easily use auto-fill. Eventhough it's written for mobile, this applies for both desktop and mobile!
How to Enable AutoComplete on your HTML forms
Here are some key points on how to enable autocomplete:
Use a <label> for all your <input> fields
Add a autocomplete attribute to your <input> tags and fill it in using this guide.
Name your name and autocomplete attributes correctly for all <input> tags
Example:
<label for="frmNameA">Name</label>
<input type="text" name="name" id="frmNameA"
placeholder="Full name" required autocomplete="name">
<label for="frmEmailA">Email</label>
<input type="email" name="email" id="frmEmailA"
placeholder="name#example.com" required autocomplete="email">
<!-- note that "emailC" will not be autocompleted -->
<label for="frmEmailC">Confirm Email</label>
<input type="email" name="emailC" id="frmEmailC"
placeholder="name#example.com" required autocomplete="email">
<label for="frmPhoneNumA">Phone</label>
<input type="tel" name="phone" id="frmPhoneNumA"
placeholder="+1-555-555-1212" required autocomplete="tel">
How to name your <input> tags
In order to trigger autocomplete, make sure you correctly name the name and autocomplete attributes in your <input> tags. This will automatically allow for autocomplete on forms. Make sure also to have a <label>! This information can also be found here.
Here's how to name your inputs:
Name
Use any of these for name: name fname mname lname
Use any of these for autocomplete:
name (for full name)
given-name (for first name)
additional-name (for middle name)
family-name (for last name)
Example: <input type="text" name="fname" autocomplete="given-name">
Email
Use any of these for name: email
Use any of these for autocomplete: email
Example: <input type="text" name="email" autocomplete="email">
Address
Use any of these for name: address city region province state zip zip2 postal country
Use any of these for autocomplete:
For one address input:
street-address
For two address inputs:
address-line1
address-line2
address-level1 (state or province)
address-level2 (city)
postal-code (zip code)
country
Phone
Use any of these for name: phone mobile country-code area-code exchange suffix ext
Use any of these for autocomplete: tel
Credit Card
Use any of these for name: ccname cardnumber cvc ccmonth ccyear exp-date card-type
Use any of these for autocomplete:
cc-name
cc-number
cc-csc
cc-exp-month
cc-exp-year
cc-exp
cc-type
Usernames
Use any of these for name: username
Use any of these for autocomplete: username
Passwords
Use any of these for name: password
Use any of these for autocomplete:
current-password (for sign-in forms)
new-password (for sign-up and password-change forms)
Resources
Current WHATWG HTML Standard for autocomplete.
"Create Amazing Forms" from Google. Seems to be updated almost daily. Excellent read.
"Help Users Checkout Faster with Autofill" from Google in 2015.

Related

Change "materialize" css framework to use "outlined" material-style form inputs

My goal is to create an input like the one described as being 'outline variant' in these Material docs.
How do I configure and/or what CSS should I add to materialize CSS forms to use the 'outline' variant?
There appears to be a few issues/requests for this outline variant, but the Materialize folks have indicated that it wasn't part of the spec at the time and have subsequently closed the issues.
I dug through some of the Material samples versus styling on the Materialize framework and noticed that they are handling things slightly different as far as padding, borders/shadows etc.
Achieving this outline variant as the default treatment is going to require some slightly destructive style updates that should probably be handled via the preprocessed files, but here is an example of some quick and dirty overrides
Note the addon class "input-outlined" in the markup:
<div class="col input-field input-outlined s6">
<input placeholder="Placeholder" id="first_name" type="text" class="validate">
<label for="first_name">First Name</label>
</div>
As far as I can tell, they're related but not the same project and do not use the same CSS files. I was using a CDN link for Materialize for a little while and none of the Material.io classes were taking effect.
Then I switched over to using the suggested Material.io CDN links, found here: https://material.io/develop/web/docs/getting-started/
Once I did that, I could use the HTML markup and class names that became visible on the page you provided after I clicked the "Web" tab.
It works. Here is a Codepen showing both styles of text inputs in action (this Codepen is using the Material.io CDN links in the settings).
The main difference between filled and outlined is that filled looks to be the default. I'm inferring that the Material.io design system has you repeat the classname and append a modifier if you wish to deviate from the default.
For instance, in the linked codepen, notice that the filled (default) text field is inside <div class="mdc-text-field"> while the outlined text field is inside <div class="mdc-text-field mdc-text-field--outlined"></div>.

Capybara Cucumber Find Field

I'm using Capybara with Cucumber.
The webpage I'm testing contains many email fields throughout but the ID's and labels for the input field change depending on which page you're on.
What I'm trying to do is create an generic reference to any email field so that one fill in method will work for all pages.
When inspecting the input fields, I can see they are of type='email
The full html:
<input id="privatekeeper_email_email" name="privatekeeper_email.email" value="" data-validity-message="Must be a valid email address" no_optional_label="true" type="email" autocomplete="off" maxlength="254">
In my block below you should be able to grasp what I'm tring to do:
email_fields = all('input[type="email"]')
fill_in(email_fields[0], with: text)
fill_in(email_fields[1], with: text)
end
When I run this, I get the following error:
Capybara::ElementNotFound: Unable to find field #<Capybara::Node::Element tag="input" path="/html/body/div[3]/div/div[2]/form/div/div[2]/div[6]/div/div[2]/div/div/div/div[2]/input">
Reading the Capybara docs, I can see that fill_in responds to ID, name or Label so my reference might not work. Is there anyway I could get this block to work?
Like I said, the Id's and labels are not consistent throughout the user journey
Since you've already found the element you need to call #set on it instead of using fill_in
email_fields[0].set(text)

Related entries in a Safecracker form?

I'm trying to create a Safecracker form in ExpressionEngine to create a recipe. I have a recipe channel, which can have many ingredients from an ingredients channel (using the multi-relationship add-on from devot:ee). However, I'm having trouble listing the ingredients within my form. This is my mark-up:
{exp:safecracker channel='recipes' datepicker='no' id='add-recipe-form' include_jquery='no' return='recipes/view/ENTRY_ID' safecracker_head='no'}
{related_entries id='ingredients'}
{title}
{/related_entries}
{/exp:safecracker}
The problem is, the actual EE tags are just getting output on my web page.
I figure I'm doing something fundamentally wrong, so could someone point me in the right direction? Thanks.
This is called "variable collision" - you're nesting entries which use the same variable/tag names as those used by the parent tag (in this case, {title}), and due to how EE's parse order works, the parent tag is winning every time.
The solution is to put your above code into another template, and embed that template within your Safecracker form. Embeds are run at the very end of template processing, after all of the other EE tags are parsed, so you won't run into the same collision.
Derek is right, you need to embed your related entries. I've got this working on my Toronto EE meetup site with this code.
Simplified Template code:
{exp:safecracker channel="gta-attendee"}
<div class="form_row" style="display:none;">
<label class="small">Choose Meetup to Attend:<span class="required">*</span></label>
{embed="includes/_playa_select" selected="{attendee-event:child_ids}" }
</div>
{/exp:safecracker}
embedded code:
{exp:channel:entries dynamic="no" channel="gta-meetup" limit="1"}
<input value="{entry_id}" name="attendee-event[selections][]" type="hidden">
{/exp:channel:entries}
In the code I'm using the Playa Module, but the principle is the same.
Hope this helps
Sean

Firewatir: Firewatir scripts to select a item from the drop down

I am new to Watir automation testing and would like to get some help for the drop down.On our website we have a state drop down where you enter the first letter of the state (in my example C for California) and it narrows it down to the all states starting with C. Once you have the list you need to click on the correct state. But I am having difficulties selecting the correct state.
(Below is the html from our website:
<div class="x-form-field-wrap x-trigger-wrap-focus" id="ext-gen202" style="width: 166px;">
<input type="hidden" id="entityStateCode" name="entityStateCode" value="">
<input type="text" id="ext-comp-1005" autocomplete="off" size="24" class=" x-form-text x-form-field x-form-focus">
I used the following to automate the scenario but none of these are giving me what i am looking for:
#browser.text_field(:id,"ext-comp-1005").value=("CA")
#browser.text_field(:id,"ext-comp-1005").set("CA")
#browser.text_field(:id=> "ext-comp-1055",:index => 5).set "CA"
I really appreciate that if you can point me to the right direction.
Thanks
I ran into a similar situation before. In my situation there was a TABLE inside the DIV which had a separate row for each item in the dynamic drop down. So, if that's the case for you then you would need to use something like this to access the items:
#browser.text_field(:id,"ext-comp-1055").set "C"
table = #browser.div(:id, "ext-gen336").table(:index, 1)
puts "First entry value: #{table[1][1].text}"
table[2][1].click # second entry
Try printing out the HTML for the DIV at runtime to see the specifics of what you need to interact with if that doesn't work.
You did not tell what the problem is, this is not enough:
none of these are giving me what i am
looking for
This should enter CA into text field:
browser.text_field(:id => "ext-comp-1005").set("CA")
If it is entering text into wrong text field, change :id => "ext-comp-1005".
If it is entering text into the correct text field, but list of states does not appear, you probably have to fire some javascript event. Take a look at How to find out which JavaScript events fired? question.

How to handle encoded inputs that need to be edited?

Using Microsoft's AntiXssLibrary, how do you handle input that needs to be edited later?
For example:
User enters:
<i>title</i>
Saved to the database as:
<i>title</i>
On an edit page, in a text box it displays something like:
<i>title</i> because I've encoded it before displaying in the text box.
User doesn't like that.
Is it ok not to encode when writing to an input control?
Update:
I'm still trying to figure this out. The answers below seem to say to decode the string before displaying, but wouldn't that allow for XSS attacks?
The one user who said that decoding the string in an input field value is ok was downvoted.
Looks like you're encoding it more than once. In ASP.NET, using Microsoft's AntiXss Library you can use the HtmlAttributeEncode method to encode untrusted input:
<input type="text" value="<%= AntiXss.HtmlAttributeEncode("<i>title</i>") %>" />
This results in
<input type="text" value="<i>title</i>" /> in the rendered page's markup and is correctly displayed as <i>title</i> in the input box.
Your problem appears to be double-encoding; the HTML needs to be escaped once (so it can be inserted into the HTML on the page without issue), but twice leads to the encoded version appearing literally.
You can call HTTPUtility.HTMLDecode(MyString) to get the text back to the unencoded form.
If you are allowing users to enter HTML that will then be rendered on the site, you need to do more than just Encode and Decode it.
Using AntiXss prevents attacks by converting script and markup to text. It does not do anything to "clean" markup that will be rendered directly. You're going to have to manually remove script tags, etc. from the user's input to be fully protected in that scenario.
You'll need to strip out script tags as well as JavaScript attributes on legal elements. For example, an attacker could inject malicious code into the onclick or onmouseover attributes.
Yes, the code inside input boxes is safe from scripting attacks and does not need to be encoded.

Resources