In this tutorial we will continue with the Login Box that we have been building in the last several tutorials. In this tutorial we are going to cover how to validate using a string validator and email validator. There are a number of validators available as well, but once you have the basic concept down, you will be able to implement the others without a hitch.
Lets Get Started
The first thing you need to do is figure out what fields you want to validate. In our case, we have six, as follows:
1. Username <loggedOut>
2. Password <loggedOut>
3. Email <forgotPW>
4. Username <register>
5. Email <register>
6. Password <register>
The second thing that you need to do is figure out if there are going to be any buttons that should be disabled/enabled based on TextInput field validation. In our case, the answer is yes:
1. Login <loggedOut>
2. Get Login Info <forgotPW>
3. Save <register>
Also, we need to note that we want the button in each state to be disabled until ALL textInput fields in the respective state pass validation.
Now that we have outlined our goals, you need to think about the validation rules, or what constitutes each field being considered valid. For the Username and Password fields, we just want to make sure that they are over six (6) characters long, and for the email address, we want to make sure that the properties of the string match that of a properly formed email address.
Importing the Necessary Classes
import mx.events.ValidationResultEvent; import mx.rpc.events.ResultEvent; import mx.validators.EmailValidator; import mx.validators.StringValidator;
Creating Variables
private var usernameVal:StringValidator = new StringValidator(); private var passwordVal:StringValidator = new StringValidator(); private var emailVal:EmailValidator = new EmailValidator(); private var emailVal2:EmailValidator = new EmailValidator(); private var usernameVal2:StringValidator = new StringValidator(); private var passwordVal2:StringValidator = new StringValidator();
Now that the variables have been created and the classes have been imported, we need to follow a series of steps for each state.
1. Write the Validation Function
2. Set the default state of the respective button to disabled
3. Decide when and how you want to call the function
loggedOut State Validation
In this state you have the username and password TextInput fields to validate. These two fields are only being validated to ensure that they have over 6 characters each. We will start by making the necessary changes to the loggedOut state to prepare it.
Step 1. Changes to State Components
Here, we are going to add the change event on each of the text boxes, add an id and enabled properties to the “Login” button.
Change From:
<s:TextInput x="77" y="13" includeIn="loggedOut" id="username"/>
Change To:
<s:TextInput x="110" y="10" id="username" change="loggedOut_changeHandler(event)" includeIn="loggedOut"/>
Change From:
<s:TextInput x="77" y="43" displayAsPassword="true" includeIn="loggedOut" displayAsPassword="true" id="password"/>
Change To:
<s:TextInput x="110" y="40" id="password" change="loggedOut_changeHandler(event)" displayAsPassword="true" includeIn="loggedOut"/>
Change From:
<s:Button x="8" y="72" label="Login" click="login_user.send();" includeIn="loggedOut"/>
Change To:
<s:Button x="10" y="72" id="loginBtn" label="Login" click="login_user.send();" enabled="false" includeIn="loggedOut"/>
Note: In the above code we have chosen to call loggedOut_changeHandler using the change event for the TextInput field. There are other events we could have chosen such as focusOut. The reason we are using the change event however, is so that as soon as the field has met the validation, the “Login” button will become enabled rather than waiting for the user to leave the TextInput field. It could be argued that this takes more system resources because it is checking validation on every text change, but the difference is really negligible. Nevertheless, use the method you feel most comfortable with.
Step 2. Validation Function
The function loggedOut_changeHandler could have been split up into two separate functions and would normally be written that way if we were not basing the login button enabled property on the validation of multiple TextInput fields.
protected function loggedOut_changeHandler(event:TextOperationEvent):void
{
if (username.text)
{
var valUsername:ValidationResultEvent;
usernameVal.source = username;
usernameVal.property = "text";
usernameVal.minLength=6;
}
if (password.text)
{
var valPassword:ValidationResultEvent;
passwordVal.source = password;
passwordVal.property = "text";
passwordVal.minLength=6;
}
valUsername = usernameVal.validate();
valPassword = passwordVal.validate();
if(valUsername.type == "valid" && valPassword.type == "valid")
loginBtn.enabled = true;
else
loginBtn.enabled = false;
}
Step 3. Changes to getCookie_resultHandler
Because you have the username and password TextInput boxes set to validate on the change event, when a cookie is set, the “Login” button is disabled and the only way to enable it is to make a change in one of the text boxes. To avoid this little problem, we have set loginBtn.enable = true;. We can do this because now that we are validating, we know that any cookie set will have already undergone validation. The getCookie_resultHandler should now look like:
protected function getCookie_resultHandler(event:ResultEvent):void
{
if(event.result.storedCookie == true)
{
cookieAction = true;
username.text = event.result.creds.username;
password.text = event.result.creds.password;
loginBtn.enabled = true;
}
else
{
cookieAction == false;
}
}
Step 4. Run and Test the application. Check to make sure that it is working both with and without the cookie set.
“forgotPW” State Validation
In this section we will check for validation on the email address of the forgotPW state. Here we are only checking to make sure that the email address is formatted correctly, not wether it is a working email address or not.
Tip: For more information on the validation criteria, you can view EmailValidator.as by holding Command and clicking “EmailValidator” in the import statement.
Step 1. Changes to State Components
Change From:
<s:TextInput x="110" y="39" id="email_to" includeIn="forgotPW"/>
Change To:
<s:TextInput x="110" y="39" id="email_to" change="email_to_changeHandler(event)" includeIn="forgotPW"/>
Change From:
<s:Button x="8" y="72" label="Get Login Info" click="get_password.send();" includeIn="forgotPW"/>
Change To:
<s:Button x="8" y="72" id="emailBtn" label="Get Login Info" click="get_password.send();" enabled="false" includeIn="forgotPW"/>
Step 2. Validation Function
protected function email_to_changeHandler(event:TextOperationEvent):void
{
if (email_to.text)
{
var valEmail:ValidationResultEvent;
emailVal.source = email_to;
emailVal.property = "text";
}
valEmail = emailVal.validate();
if(valEmail.type == "valid")
emailBtn.enabled = true;
else
emailBtn.enabled = false;
}
“register” State Validation
The register state is a combination of the above since we have the same textInput fields as we had in the first two section, just all in one state now.
Step 1. Changes to State Components
Change From:
<s:TextInput x="110" y="24" id="usernameTextInput2" text="{users.username}" includeIn="register"/>
Change To:
<s:TextInput x="110" y="24" id="usernameTextInput2" text="{users.username}" change="registerVal_changeHandler(event)" includeIn="register"/>
Change From:
<s:TextInput x="110" y="54" id="emailTextInput2" text="{users.email}" includeIn="register"/>
Change To:
<s:TextInput x="110" y="54" id="emailTextInput2" text="{users.email}" change="registerVal_changeHandler(event)" includeIn="register"/>
Change From:
<s:TextInput x="110" y="84" id="passwordTextInput2" text="{users.password}" displayAsPassword="true" includeIn="register"/>
Change To:
<s:TextInput x="110" y="84" id="passwordTextInput2" text="{users.password}" change="registerVal_changeHandler(event)" displayAsPassword="true" includeIn="register"/>
Change From:
<s:Button x="10" y="118" label="Save" id="saveBtn" click="saveBtn_clickHandler(event)" includeIn="register"/>
Change To:
<s:Button x="10" y="118" label="Save" id="saveBtn" click="saveBtn_clickHandler(event)" enabled="false" includeIn="register"/>
Step 2. Validation Function
protected function registerVal_changeHandler(event:TextOperationEvent):void
{
if (usernameTextInput2.text)
{
var valUsername2:ValidationResultEvent;
usernameVal2.source = usernameTextInput2;
usernameVal2.property = "text";
usernameVal2.minLength=6;
}
if (emailTextInput2.text)
{
var valEmail2:ValidationResultEvent;
emailVal2.source = emailTextInput2;
emailVal2.property = "text";
}
if (passwordTextInput2.text)
{
var valPassword2:ValidationResultEvent;
passwordVal2.source = passwordTextInput2;
passwordVal2.property = "text";
passwordVal2.minLength=6;
}
valUsername2 = usernameVal2.validate();
valEmail2 = emailVal2.validate();
valPassword2 = passwordVal2.validate();
if(valUsername2.type == "valid" && valPassword2.type == "valid" && valEmail2.type == "valid")
saveBtn.enabled = true;
else
saveBtn.enabled = false;
}
That’s it! Go ahead and save and run your application and check your validation in all three states. Make sure everything is working correctly. Your new application should look like:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
applicationComplete="init()"
minWidth="955" minHeight="600" xmlns:valueObjects="valueObjects.*"
xmlns:usersservice="services.usersservice.*">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.ValidationResultEvent;
import mx.rpc.events.ResultEvent;
import mx.validators.EmailValidator;
import mx.validators.StringValidator;
import spark.events.TextOperationEvent;
private var userid:int;
private var usertype:String;
private var usernameVal:StringValidator = new StringValidator();
private var passwordVal:StringValidator = new StringValidator();
private var emailVal:EmailValidator = new EmailValidator();
private var usernameVal2:StringValidator = new StringValidator();
private var emailVal2:EmailValidator = new EmailValidator();
private var passwordVal2:StringValidator = new StringValidator();
[Bindable]
private var cookieAction:Boolean;
protected function saveBtn_clickHandler(event:MouseEvent):void
{
var users2:Users = new Users();
users2.username = usernameTextInput2.text;
users2.email = emailTextInput2.text;
users2.password = passwordTextInput2.text;
users2.user_type = "user";
createUsersResult.token = usersService.createUsers(users2);
createUsersResult.token = usersService.commit();
currentState = 'loggedOut';
}
private function checkLogin(event:ResultEvent):void
{
userid = event.result.loginsuccess;
trace (userid);
usertype = event.result.usertype;
trace (usertype);
cookieAction = event.result.usertype;
trace (cookieAction);
if (userid != 0)
{
currentState = usertype;
}
else
{
mx.controls.Alert.show('Invalid username/password');
}
}
protected function createUsersResult_resultHandler(event:ResultEvent):void
{
mx.controls.Alert.show('Thank you for registering. You may login now!');
currentState = "loggedOut";
}
private function init():void
{
getCookie.send();
}
protected function getCookie_resultHandler(event:ResultEvent):void
{
if(event.result.storedCookie == true)
{
cookieAction = true;
username.text = event.result.creds.username;
password.text = event.result.creds.password;
loginBtn.enabled = true;
}
else
{
cookieAction == false;
}
}
private function getPassword(event:ResultEvent):void
{
if(event.result.getPassword == "yes")
{
mx.controls.Alert.show('Your password has been emailed to you.');
currentState = "loggedOut";
}
else
{
mx.controls.Alert.show('Invalid email, please try again.');
}
}
protected function loggedOutVal_changeHandler(event:TextOperationEvent):void
{
if (username.text)
{
var valUsername:ValidationResultEvent;
usernameVal.source = username;
usernameVal.property = "text";
usernameVal.minLength=6;
}
if (password.text)
{
var valPassword:ValidationResultEvent;
passwordVal.source = password;
passwordVal.property = "text";
passwordVal.minLength=6;
}
valUsername = usernameVal.validate();
valPassword = passwordVal.validate();
if(valUsername.type == "valid" && valPassword.type == "valid")
loginBtn.enabled = true;
else
loginBtn.enabled = false;
}
protected function email_toVal_changeHandler(event:TextOperationEvent):void
{
if (email_to.text)
{
var valEmail:ValidationResultEvent;
emailVal.source = email_to;
emailVal.property = "text";
}
valEmail = emailVal.validate();
if(valEmail.type == "valid")
emailBtn.enabled = true;
else
emailBtn.enabled = false;
}
protected function registerVal_changeHandler(event:TextOperationEvent):void
{
if (usernameTextInput2.text)
{
var valUsername2:ValidationResultEvent;
usernameVal2.source = usernameTextInput2;
usernameVal2.property = "text";
usernameVal2.minLength=6;
}
if (emailTextInput2.text)
{
var valEmail2:ValidationResultEvent;
emailVal2.source = emailTextInput2;
emailVal2.property = "text";
}
if (passwordTextInput2.text)
{
var valPassword2:ValidationResultEvent;
passwordVal2.source = passwordTextInput2;
passwordVal2.property = "text";
passwordVal2.minLength=6;
}
valUsername2 = usernameVal2.validate();
valEmail2 = emailVal2.validate();
valPassword2 = passwordVal2.validate();
if(valUsername2.type == "valid" && valPassword2.type == "valid" && valEmail2.type == "valid")
saveBtn.enabled = true;
else
saveBtn.enabled = false;
}
]]>
</fx:Script>
<s:states>
<s:State name="loggedOut"/>
<s:State name="forgotPW"/>
<s:State name="register"/>
<s:State name="user"/>
<s:State name="admin"/>
</s:states>
<fx:Declarations>
<s:HTTPService id="login_user" result="checkLogin(event)" showBusyCursor="true" method="POST"
url="login.php" useProxy="false">
<s:request xmlns="">
<username>
{username.text}
</username>
<password>
{password.text}
</password>
<logincookie>
{setCookie.selected}
</logincookie>
</s:request>
</s:HTTPService>
<s:HTTPService id="getCookie" result="getCookie_resultHandler(event)" method="POST" url="getCookie.php"/>
<mx:HTTPService id="get_password" result="getPassword(event)" showBusyCursor="true" method="POST"
url="forgotPW.php" useProxy="false">
<mx:request xmlns="">
<email_to>
{email_to.text}
</email_to>
</mx:request>
</mx:HTTPService>
<valueObjects:Users id="users"/>
<usersservice:UsersService id="usersService" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>
<s:CallResponder id="createUsersResult" result="createUsersResult_resultHandler(event)"/>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Panel width="250" height="200" title="Flex 4 Login Box" horizontalCenter="0" verticalCenter="0">
<s:Label x="10" y="18" text="Username" includeIn="loggedOut"/>
<s:TextInput x="110" y="10" id="username" change="loggedOutVal_changeHandler(event)" includeIn="loggedOut"/>
<s:Label x="12" y="47" text="Password" includeIn="loggedOut"/>
<s:TextInput x="110" y="40" id="password" change="loggedOutVal_changeHandler(event)" displayAsPassword="true" includeIn="loggedOut"/>
<s:Button x="10" y="72" id="loginBtn" label="Login" click="login_user.send();" enabled="false" includeIn="loggedOut"/>
<s:Button x="120" y="72" label="Forgot Login Info?" click="currentState='forgotPW'" includeIn="loggedOut"/>
<s:CheckBox x="10" y="101" label="Remember Me" id="setCookie" selected="{cookieAction}" includeIn="loggedOut"/>
<s:Label x="195" y="103" text="Sign Up" click="currentState='register'" includeIn="loggedOut"/>
<s:Label x="10" y="46" text="Email:" includeIn="forgotPW"/>
<s:TextInput x="110" y="39" id="email_to" change="email_toVal_changeHandler(event)" includeIn="forgotPW"/>
<s:Button x="8" y="72" id="emailBtn" label="Get Login Info" click="get_password.send();" enabled="false" includeIn="forgotPW"/>
<s:Button x="168" y="72" label="<< Login" click="currentState='loggedOut'" includeIn="forgotPW"/>
<s:Label x="10" y="31" text="Username:" includeIn="register"/>
<s:TextInput x="110" y="24" id="usernameTextInput2" text="{users.username}" change="registerVal_changeHandler(event)" includeIn="register"/>
<s:Label x="10" y="61" text="Email:" includeIn="register"/>
<s:TextInput x="110" y="54" id="emailTextInput2" text="{users.email}" change="registerVal_changeHandler(event)" includeIn="register"/>
<s:Label x="10" y="91" text="Password:" includeIn="register"/>
<s:TextInput x="110" y="84" id="passwordTextInput2" text="{users.password}" change="registerVal_changeHandler(event)" displayAsPassword="true" includeIn="register"/>
<s:Button x="10" y="118" label="Save" id="saveBtn" click="saveBtn_clickHandler(event)" enabled="false" includeIn="register"/>
<s:Button x="168" y="118" label="<< Login" click="currentState='loggedOut'" includeIn="register"/>
<s:Label x="10" y="10" text="Welcome User" includeIn="user"/>
<s:Button x="10" y="30" label="Log Out" click="currentState='loggedOut'" includeIn="user"/>
<s:Label x="10" y="10" text="Welcome Admin" includeIn="admin"/>
<s:Button x="10" y="30" label="Admin Log Out" click="currentState='loggedOut'" includeIn="admin"/>
</s:Panel>
</s:Application>


