Our developers came across an interesting issue with Firefox autocomplete last week. I joined in to help debug the problem and we killed a good 8 man hours between 3 of us all the while receiving some sarcastic "have you tried jQuery" taunts from the design team. No developer should have to suffer taunts from the design team, so we thought we'd share our problem and the final solution.The ProblemWe started integrating our first set of fields which were programatically enabled / disabled conditionally based upon certain tests - normally a fairly simple and straightforward task.Several days later after long development stints we began to notice a consistent issue causing one or more fields on the screen to become disabled. The issue exhibited the following characteristics:
- Different fields and different quantities of fields were affected after each refresh
- Fields that were actually being programatically disabled / enabled always had the correct state applied when the page loaded
- A hard refresh (Ctrl+F5) would rectify the issue momentarily
- The issue was being experienced in Firefox but not Chrome
- Markup was valid with the exception of warnings about some missing attributes
To provide some quick background:
- our application is heavily ajax based and as a result it doesn't rely on traditional form based data submission or field naming (thanks to data binding that knockout provides).
We initially thought the issue came about due to some developer error and spent several hours combing git commits and reverting to different commits to see where the issue began. Because the issue was so random and happened each time on page load (before any disabling logic was applied) it was hard to blame bad code, so we looked elsewhere.All we knew for a fact was that the issue did not occur in chrome (so it was unlikely to be a programming or logic error) and that the issue began after we started conditionally disabling fields.The big revealFirefox has an autocomplete feature which as well as automatically filling field values on page reloads, also re-applies field states (e.g. disabled fields). This functionality does seem to have some quirks however:
- It works even when fields aren't wrapped in a form tag.
- It works even if fields don't have names.
The issue lies primarily in the second point above - if a field doesn't have a name, firefox will still remember the value and state of a field. Apparently on page reload, Firefox will re-apply that memorized state to any other field without a name attribute as it sees fit even if its not the same field.We couldn't immediately track down the issue as all of our input value attributes are bound to our data model - meaning that they are overridden programatically after page load (regardless of what firefox loads in). Not all of our fields have disabled bindings however and as a result those were affected by the problem.The ResolutionThe issue affects any developers that don't rely on the name attribute of input fields (or don't consistently apply it) or those that rely on non unique fields names.
- The easiest fix for us (seeing as we don't rely on forms anyway) was to wrap the entire application up in a form tag and switch auto complete off via the autocomplete attribute - ironically the only way to turn it off is to add the attribute to a form tag which didn't exist in the first place. Keep in mind that if you choose this solution, you can't rely on form tags at all elsewhere in your application.
- If you do rely on forms or want to support accessibility (which we do eventually), you may find it's easier to ensure that all of your input fields are named.
- Use your programming skills to reset the disabled attribute on all elements that don't have one after page load.