Skip to content

Commit

Permalink
An Ajax check on the username field at registration
Browse files Browse the repository at this point in the history
  • Loading branch information
lukerobinson authored and Doug Bell committed Mar 8, 2010
1 parent d0884af commit c61e745
Show file tree
Hide file tree
Showing 8 changed files with 274 additions and 2 deletions.
30 changes: 28 additions & 2 deletions lib/WebGUI/Auth/WebGUI.pm
Expand Up @@ -165,7 +165,7 @@ sub createAccount {
unless($setting->get('webguiUseEmailAsUsername')){
my $username = $form->process("authWebGUI.username");
$vars->{'create.form.username'}
= WebGUI::Form::text($self->session, {
= WebGUI::Form::username($self->session, {
name => "authWebGUI.username",
value => $username,
extras => $self->getExtrasStyle($username)
Expand Down Expand Up @@ -326,6 +326,32 @@ sub deactivateAccountConfirm {
return $self->displayLogin(sprintf( $i18n->get("deactivateAccount success"), $username ));
}

#-------------------------------------------------------------------

=head2 checkField ( )
Performs AJAX checks on form field input. For example, can check whether a user
name is free for registration.
Returns the JSON {"error":"errorString"} where errorString is an error message
or an empty string if the check was successful.
=cut

sub checkField {
my $self = shift;
my $session = $self->session;
$session->http->setMimeType( 'application/json' );

my $input = $session->form->param('input');
my $fieldName = $session->form->param('fieldName');
my $fieldType = $session->form->param('fieldType');

my $checkClass = 'WebGUI::Form::'. ucfirst $fieldType;
my (%checkResults) = "$checkClass"->check($session, $input);
return JSON::encode_json(\%checkResults);
}

#-------------------------------------------------------------------
sub displayAccount {
my $self = shift;
Expand Down Expand Up @@ -774,7 +800,7 @@ sub new {
my $session = shift;
my $authMethod = $_[0];
my $userId = $_[1];
my @callable = ('validateEmail','createAccount','deactivateAccount','displayAccount','displayLogin','login','logout','recoverPassword','resetExpiredPassword','recoverPasswordFinish','createAccountSave','deactivateAccountConfirm','resetExpiredPasswordSave','updateAccount', 'emailResetPassword', 'emailResetPasswordFinish');
my @callable = ('validateEmail','createAccount','deactivateAccount','displayAccount','displayLogin','login','logout','recoverPassword','resetExpiredPassword','recoverPasswordFinish','createAccountSave','deactivateAccountConfirm','resetExpiredPasswordSave','updateAccount', 'emailResetPassword', 'emailResetPasswordFinish','checkField');
my $self = WebGUI::Auth->new($session,$authMethod,$userId,\@callable);
bless $self, $class;
}
Expand Down
124 changes: 124 additions & 0 deletions lib/WebGUI/Form/Username.pm
@@ -0,0 +1,124 @@
package WebGUI::Form::Username;

=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=cut

use strict;
use base 'WebGUI::Form::Text';
use WebGUI::International;

=head1 NAME
Package WebGUI::Form::Username
=head1 DESCRIPTION
Creates a text input box form field specifically for a user name.
=head1 SEE ALSO
This is a subclass of WebGUI::Form::Text.
=head1 METHODS
The following methods are specifically available from this class. Check the superclass for additional methods.
=cut

#-------------------------------------------------------------------

=head2 definition ( [ additionalTerms ] )
See the super class for additional details.
=head3 additionalTerms
The following additional parameters have been added via this sub class.
=head4 maxlength
Defaults to 255. Determines the maximum number of characters allowed in this field.
=head4 size
Defaults to the setting textBoxSize or 30 if that's not set. Specifies how big of a text box to display.
=cut

#-------------------------------------------------------------------

=head2 getValue ( [ value ] )
Retrieves a value from a form GET or POST and returns it. If the value comes back as undef, this method will return the defaultValue instead. Strip newlines/carriage returns from the value.
=head3 value
An optional value to process, instead of POST input.
=cut

sub getValue {
my $self = shift;
my $value = $self->SUPER::getValue(@_);
$value =~ tr/\r\n//d;
return $value;
}

#-------------------------------------------------------------------

=head2 toHtml ( )
Renders a user name field.
=cut

sub toHtml {
my $self = shift;
$self->session->style->setScript($self->session->url->extras('form/fieldCheck.js'),{ type=>'text/javascript' });
$self->session->style->setScript($self->session->url->extras('yui/build/yahoo-dom-event/yahoo-dom-event.js'), {type=>'text/javascript'});
$self->session->style->setScript($self->session->url->extras('yui/build/connection/connection-min.js'), {type => 'text/javascript'});
$self->session->style->setScript($self->session->url->extras('yui/build/json/json-min.js'), {type=>'text/javascript'});
$self->session->style->setScript($self->session->url->extras('yui/build/datasource/datasource-min.js'), {type=>'text/javascript'});
$self->session->style->setScript($self->session->url->extras('yui-webgui/build/i18n/i18n.js'), {type=>'text/javascript'});
my $value = $self->fixMacros($self->fixQuotes($self->fixSpecialCharacters(scalar $self->getOriginalValue)));
$self->set("extras", $self->get('extras') . ' onblur="new WebGUI.FieldCheck(\''. $self->get("id").'\',\'username\',1);"');
return '<input id="'.$self->get('id').'" type="text" name="'.$self->get("name").'" value="'.$value.'" size="'.$self->get("size").'" maxlength="'.$self->get("maxlength").'" '.$self->get("extras").' />';
}

#-------------------------------------------------------------------

=head2 check ( $session, $input )
check() is called as a class method.
It checks whether a user name is free for registration. Returns a hash
(error => $error)
if the username is not free.
=cut

sub check {
my ($class, $session, $input) = @_;
my $i18n = WebGUI::International->new($session, 'Form_Username');

my $error = '';
my ($existingUserId) = $session->db->quickArray("select userId from users where username=".$session->db->quote($input));
$error = $i18n->get('username in use') if $existingUserId;

my %checkInfo = (error => $error);
return %checkInfo;
}

1;

11 changes: 11 additions & 0 deletions lib/WebGUI/i18n/English/Form.pm
@@ -0,0 +1,11 @@
package WebGUI::i18n::English::Form;
use strict;

our $I18N = {
'field required' => {
message => q|This field is required.|,
lastUpdated => 1217216725
},
};

1;
11 changes: 11 additions & 0 deletions lib/WebGUI/i18n/English/Form_Username.pm
@@ -0,0 +1,11 @@
package WebGUI::i18n::English::Form_Username;
use strict;

our $I18N = {
'username in use' => {
message => q|Sorry, that account name is already in use by another member of this site.|,
lastUpdated => 1217216725
},
};

1;
Binary file added www/extras/form/cross.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
100 changes: 100 additions & 0 deletions www/extras/form/fieldCheck.js
@@ -0,0 +1,100 @@
if (typeof WebGUI == "undefined" || !WebGUI) {
var WebGUI = {};
}

WebGUI.FieldCheck = function (fieldId,fieldType,required) {
this.fieldId=fieldId;
this.fieldType=fieldType;
this.required=required;
var obj = this;

this.i18nObj = new WebGUI.i18n( {
namespaces : {
'Form' : ['field required']
},
onpreload : {
fn : this.initialize,
obj : this,
override : true
}
} );
this.i18n = function (key) {
return this.i18nObj.get('Form',key)
};

return this;
}

WebGUI.FieldCheck.prototype.initialize = function() {
var fieldId=this.fieldId;
var fieldType=this.fieldType;
var required=this.required;
var field=document.getElementById(fieldId);
var fieldName=field.name;
var input=field.value;

var myAjaxEvent = new WebGUI.FieldCheck.AjaxEvent();
myAjaxEvent.startThrobber(fieldId);

if (required && !input) {
var imgEltId=fieldId+"_Img";
var imgElt=document.getElementById(imgEltId);
imgElt.setAttribute('src','/extras/form/cross.png');
alert(this.i18n('field required'));
return false;
}

myAjaxEvent.connect(fieldId,'/?op=auth;method=checkField;fieldName='+fieldName+';fieldType='+fieldType+';input='+input);
}

WebGUI.FieldCheck.AjaxEvent = function() {
return this;
}

WebGUI.FieldCheck.AjaxEvent.prototype = {
startThrobber: function(fieldId) {
this.field = document.getElementById(fieldId);
var imgEltId=fieldId+"_Img";
var imgElt;
if(document.getElementById(imgEltId)==undefined){
var formElt=this.field.parentNode;
var imgElt=document.createElement('img');
imgElt.setAttribute('id',imgEltId);
WebGUI.FieldCheck.insertAfter(imgElt,this.field);
}else{
var imgElt=document.getElementById(imgEltId);
}
imgElt.setAttribute('src','/extras/form/throbber.gif');
},
connect: function(fieldId,sUri) {
if (!sUri && !this.sUri) {
return false;
} else {
this.sUri = (!sUri) ? this.sUri : sUri;
YAHOO.util.Connect.asyncRequest('GET', this.sUri, {
success: function (o) {
var oJSON = eval("(" + o.responseText + ")");
var imgEltId=fieldId+"_Img";
var imgElt=document.getElementById(imgEltId);
document.getElementById(imgEltId);
if(oJSON.error == ""){
imgElt.setAttribute('src','/extras/form/tick.png');
}else{
imgElt.setAttribute('src','/extras/form/cross.png');
alert(oJSON.error);
}
},
scope: this
});
}
}
};

WebGUI.FieldCheck.insertAfter = function(newElement,targetElement) {
var parent = targetElement.parentNode;
if(parent.lastchild == targetElement) {
parent.appendChild(newElement);
}else{
parent.insertBefore(newElement, targetElement.nextSibling);
}
};
Binary file added www/extras/form/throbber.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added www/extras/form/tick.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c61e745

Please sign in to comment.