My attempt at browser-based username/password autocomplete with GWT
Last night, I did a quick spike to try and implement username/password autocomplete in my GXT application. By "autocomplete", I don't mean Ajax-style autocomplete, but rather browser-based autocomplete. The best information I found on doing this is in the following post:
http://osdir.com/ml/GoogleWebToolkit/2009-04/msg01838.html
I didn't use this technique (wrapping an existing form with a FormPanel) because I'm using GXT and didn't want to lose the look-and-feel of my login form.
I was successful in getting everything to work in Firefox (it populates both the username and password). In IE, it only populates the username, not the password. In Safari/Chrome, it doesn't work at all. Here's how I did it:
1. Created a hidden HTML form on my HTML page that embeds GWT.
<form method="post" action="javascript:void(0)" style="display: none"> <input type="text" id="username" name="username" value=""/> <input type="password" id="password" name="password" value=""/> <input type="submit" value="Login" id="login"/> </form>
2. When a user clicks on the "Login" button in my GWT application, populate the fields in this hidden form and "click" on the Login button (which will do nothing since the action="javascript:void(0)").
// Set the hidden fields to trigger the browser to remember DOM.getElementById("username").setAttribute("value", username.getValue()); DOM.getElementById("password").setAttribute("value", password.getValue()); clickFormLogin(); ... public static native void clickFormLogin() /*-{ $doc.getElementById("login").click(); }-*/;
This works in Firefox 3.5 and prompts me to save the user/pass at the top of the screen. Why doesn't this work in Safari/Chrome? My guess is because the form's action doesn't go anywhere and the form is not submitted. If I change the action to be an actual URL and show the form, clicking on the form's Login button will save it in those browsers.
Grabbing the actual populated values when the screen loads did turn out to be a bit tricky. With IE, I was able to grab the username, but not the password. It seems that keyboard or mouse interaction (tabbing off or focusing/blurring) with the username field is necessary to get the password field populated. In Firefox, I was unable to grab the values if I did it straight away. The solution turned out to be wrapping everything in a Timer and waiting a 1/2 second.
// grab user/pass from browser and hidden login form (if user has stored them) // runs 1/2 second after page loads so cursor goes at end of username and works in Firefox Timer t = new Timer() { public void run() { username.setValue(getElementValue("username")); password.setValue(getElementValue("password")); if (username.getValue() != null) { password.focus(); } validate(); } }; t.schedule(500); ... public static native String getElementValue(String domId) /*-{ return $doc.getElementById(domId).value; }-*/;
While I'm glad I got it working in Firefox, I'm disappointed with IE's lack of password autocompletion. More than anything, I can't help but think there's a way to make this work in WebKit-based browsers. If you've successfully implemented cross-browser username/password autocomplete in GWT, please share your experience. If you share your experience about successfully doing it in Safari/Chrome, I might even buy you a beer or two.