PDA

View Full Version : Getting the browser to remember the username and password on a login form



murrah
24 Nov 2012, 1:05 AM
Hi.

Specifically I am referring to where a browser will ask the user if they want to remember the username and password when a login form is submitted. I am testing on FF 16, IE 9, Chrome 23 and Safari 5.1. On each I used a non-Ext standard HTML-only login form to make sure that the browser settings were correct and that the "remember" functionality works. All good so far.

My original code had functional XHR authentication and the client wanted the remember-password functionality to work for their users. For testing at this stage I am using the standardSubmit (form) to see if I can get that working first before adding more complexity re XHR.

I have read a lot about various solutions to this and am only having partial success. Since this is such a common requirement of end users I can only assume that others must have solved this by now. However, I cant find a solution that seems to work across all current browsers.

The first thing I added was an extension to convert the text fields from autocomplete="off" to "on":

// To use to help browsers remember the username and password fields
// http://stackoverflow.com/questions/11965919/browser-does-not-remember-password-during-login
Ext.define('Ext.ux.form.AutocompleteField', {
extend: 'Ext.form.field.Text',
alias: 'widget.autocompletefield',

initComponent: function () {
Ext.each(this.fieldSubTpl, function (oneTpl, idx, allItems) {
if (Ext.isString(oneTpl)) {
allItems[idx] = oneTpl.replace('autocomplete="off"', 'autocomplete="on"');
}
});
this.callParent(arguments);
}
});

That worked to supply the ability to autocomplete the username field so users would see the usual drop box of previous entries etc. It did not do that on IE9 even though my straight html page does work on IE9.

So, moving on to the login form itself:

Ext.define('MyApp.view.Loginform', {
extend: 'Ext.form.Panel',
alias: 'widget.loginform',
title: 'Please log in',

// replaced by the one on the autoEl below. On submit the page does go to this url.
//url: 'http://.../user/authenticate', // shortened
width: 350,
height: 300,

standardSubmit: true,
defaultType: 'autocompletefield',

// Required to wrap the fields in a <form> tag so the browsers will know it is a form!
// Ext 4 does not do that natively.
autoEl: {
tag: 'form',
action: 'http://.../user/authenticate', // URL shortened for display
method: 'post'
},

items: [{
name: 'username',
width: 400,
allowBlank: false,
fieldLabel: 'User name'
}, {
name: 'password',
width: 400,
allowBlank: false,
inputType: 'password',
fieldLabel: 'Password'
}],

buttons: [{
text: 'submit',
type: 'submit',
handler: function () {
this.up('form').getForm().submit();
}
}]
});

The View has a dedicated "do nothing" controller and is added to my viewport like so:
{
region: 'east',
xtype: 'loginform'
}

Ok, confirming that the login form is displaying correctly and when I enter a username and password it posts to the url provided.

The other piece of the puzzle that has been suggested is to add a html login form to my index.html file (with the same values as the Ext form), which I did:

<html>
<head>
<meta charset="UTF-8">
<!--- The standard Ext tags are in here - removed for brevity ... --->
<script type="text/javascript" src="app.js"></script>
</head>

<body>
<form id="login" action="http://.../user/m-authenticate" method="post"><!--- url shortened for display --->
<input class="x-hidden" type="text" id="username" name="username" />
<input class="x-hidden" type="password" id="password" name="password"/>
<input class="x-hidden" type="submit" id="submit" value="Login" />
</form>
</body>
</html>

Results:
In Safari, the form displays previous username entries created via the plain HTML page and will change the password as I select a different username. It wont ask to save a new combination or update the password of an existing saved username. That is the best result of all the browsers!

In IE, nothing. That is probably because the autocomplete doesnt work in the first place.

In FF, it will display the previous usernames but will not supply the matching password nor update the password on submit.

In Chrome, same as FF.

Here is the DOM courtesy of FireBug:
<form id="loginform-1041" class="x-panel x-border-item x-box-item x-panel-default"
method="post" action="http://.../user/authenticate"
style="width: 350px; height: 657px; margin: 0px; left: 1250px; top: 60px;">
<div id="loginform-1041_header" class="x-panel-header x-docked x-panel-header-default x-horizontal x-panel-header-horizontal x-panel-header-default-horizontal x-top x-panel-header-top x-panel-header-default-top x-docked-top x-panel-header-docked-top x-panel-header-default-docked-top x-unselectable"
style="-moz-user-select: -moz-none; width: 350px; left: 0px; top: 0px;">
<div id="loginform-1041-body" class="x-panel-body x-panel-body-default x-panel-body-default"
style="width: 350px; left: 0px; top: 24px; height: 604px;">
<table id="username" class="x-field x-form-item x-field-default x-anchor-form-item x-form-dirty"
cellpadding="0" style="width: 400px; table-layout: fixed;">
<tbody>
<tr id="username-inputRow">
<td id="username-labelCell" class="x-field-label-cell" width="105" valign="top"
halign="left" style="">
<td id="username-bodyEl" class="x-form-item-body " role="presentation"
colspan="2" style="width: 100%;">
<input id="username-inputEl" class="x-form-field x-form-required-field x-form-text"
type="text" autocomplete="on" style="width: 100%; -moz-user-select: text;"
name="username" size="1" aria-invalid="false" data-errorqtip="">
</td>
</tr>
</tbody>
</table>
<table id="password" class="x-field x-form-item x-field-default x-anchor-form-item"
cellpadding="0" style="width: 400px; table-layout: fixed;">
<tbody>
<tr id="password-inputRow">
<td id="password-labelCell" class="x-field-label-cell" width="105" valign="top"
halign="left" style="">
<td id="password-bodyEl" class="x-form-item-body " role="presentation"
colspan="2" style="width: 100%;">
<input id="password-inputEl" class="x-form-field x-form-required-field x-form-text "
type="password" autocomplete="on" style="width: 100%; -moz-user-select: text;"
name="password" size="1" aria-invalid="false" data-errorqtip="">
</td>
</tr>
</tbody>
</table>
<div id="loginform-1041-overflowPadderEl" style="font-size: 1px; width: 1px; height: 1px; display: none;"></div>
</div>
<div id="toolbar-1042" class="x-toolbar x-docked x-toolbar-footer x-docked-bottom x-toolbar-docked-bottom x-toolbar-footer-docked-bottom x-box-layout-ct"
style="width: 350px; left: 0px; top: 628px;">
</form>

So that is all I can tell you. Has anyone got this to work in Ext 4?

Thanks for taking the time to read this - I appreciate it.
Murray

murrah
24 Nov 2012, 2:51 AM
I moved the submit button to be an item rather than using the button config. It didn't help. So then I used FireBug to copy out the form from the DOM that Ext made and ran it in it's own html file, and included the ext css file. I didnt modify the file in any way then ran it (see below).

The result is that it works in all browsers including IE. So, the html that Ext makes works, but when it is in the viewport it doesnt. And it doesnt need the "extra" form as was suggested (well not in this situation, anyway).

Any ideas?

Thanks,
Murray

Here is my complete test file. Just point the ext-all.css at your copy or remove it altogether. It works either way.


<html>

<head>
<meta charset="UTF-8">
<title>Login 3 test</title>
<link rel="stylesheet" type="text/css" href="../../../ExtJS4/resources/css/ext-all.css">
</head>

<body>
<form id="loginform-1041" class="x-panel x-border-item x-box-item x-panel-default"
method="post" action="http://mysite.com/user/authenticate"
style="width: 350px; height: 657px; margin: 0px; left: 1250px; top: 60px;">
<div id="loginform-1041_header" class="x-panel-header x-docked x-panel-header-default x-horizontal x-panel-header-horizontal x-panel-header-default-horizontal x-top x-panel-header-top x-panel-header-default-top x-docked-top x-panel-header-docked-top x-panel-header-default-docked-top x-unselectable"
style="-moz-user-select: -moz-none; width: 350px; left: 0px; top: 0px;">
<div id="loginform-1041_header-body" class="x-panel-header-body x-panel-header-body-default x-panel-header-body-horizontal x-panel-header-body-default-horizontal x-panel-header-body-top x-panel-header-body-default-top x-panel-header-body-docked-top x-panel-header-body-default-docked-top x-panel-header-body-default-horizontal x-panel-header-body-default-top x-panel-header-body-default-docked-top x-box-layout-ct"
style="width: 340px;">
<div id="loginform-1041_header-innerCt" class="x-box-inner " role="presentation"
style="width: 340px; height: 17px;">
<div id="loginform-1041_header-targetEl" style="position:absolute;width:20000px;left:0px;top:0px;height:1px">
<div id="loginform-1041_header_hd" class="x-component x-panel-header-text-container x-box-item x-component-default"
style="text-align: left; left: 0px; top: 0px; margin: 0px; width: 340px;">
<span id="loginform-1041_header_hd-textEl" class="x-panel-header-text x-panel-header-text-default">Please log in</span>

</div>
</div>
</div>
</div>
</div>
<div id="loginform-1041-body" class="x-panel-body x-panel-body-default x-panel-body-default"
style="width: 350px; left: 0px; top: 24px; height: 633px;">
<table id="autocompletefield-1042" class="x-field x-form-item x-field-default x-anchor-form-item"
cellpadding="0" style="width: 400px; table-layout: fixed;">
<tbody>
<tr id="autocompletefield-1042-inputRow">
<td id="autocompletefield-1042-labelCell" class="x-field-label-cell" width="105"
valign="top" halign="left" style="">
<label id="autocompletefield-1042-labelEl" class="x-form-item-label x-form-item-label-left"
style="width:100px;margin-right:5px;" for="autocompletefield-1042-inputEl">User name:</label>
</td>
<td id="autocompletefield-1042-bodyEl" class="x-form-item-body " role="presentation"
colspan="2" style="width: 100%;">
<input id="autocompletefield-1042-inputEl" class="x-form-field x-form-required-field x-form-text "
type="text" autocomplete="on" style="width: 100%; -moz-user-select: text;"
name="username" size="1" aria-invalid="false" data-errorqtip="">
</td>
</tr>
</tbody>
</table>
<table id="autocompletefield-1043" class="x-field x-form-item x-field-default x-anchor-form-item"
cellpadding="0" style="width: 400px; table-layout: fixed;">
<tbody>
<tr id="autocompletefield-1043-inputRow">
<td id="autocompletefield-1043-labelCell" class="x-field-label-cell" width="105"
valign="top" halign="left" style="">
<label id="autocompletefield-1043-labelEl" class="x-form-item-label x-form-item-label-left"
style="width:100px;margin-right:5px;" for="autocompletefield-1043-inputEl">Password:</label>
</td>
<td id="autocompletefield-1043-bodyEl" class="x-form-item-body " role="presentation"
colspan="2" style="width: 100%;">
<input id="autocompletefield-1043-inputEl" class="x-form-field x-form-required-field x-form-text "
type="password" autocomplete="on" style="width: 100%; -moz-user-select: text;"
name="password" size="1" aria-invalid="false" data-errorqtip="">
</td>
</tr>
</tbody>
</table>
<div id="button-1044" class="x-btn x-btn-default-small x-noicon x-btn-noicon x-btn-default-small-noicon"
style="border-width: 1px;">

<em id="button-1044-btnWrap">
<button id="button-1044-btnEl" class="x-btn-center" autocomplete="off" role="button" hidefocus="true" type="submit" style="height: 18px;">
<span id="button-1044-btnInnerEl" class="x-btn-inner" style="">submit</span>
<span id="button-1044-btnIconEl" class="x-btn-icon "></span>
</button>
</em>

</div>
<div id="loginform-1041-overflowPadderEl" style="font-size: 1px; width: 1px; height: 1px; display: none;"></div>
</div>
</form>
</body>

</html>