Showing posts with label flex. Show all posts
Showing posts with label flex. Show all posts

Saturday, January 16, 2010

Strong Password Validator

Recently I was needed to create a password strength validator, which will basically info user how strong is the entered password. There are different standards for the strong password, I decided to go on with these:

- Must contain eight characters or more
- Should not contain spaces

Previous two are required criteria, it means that if the entered password doesn't match this requirements it is not valid.

Contain characters from one or more of the following three character classes:
- Alphabetic (e.g., a-z, A-Z)
- Numeric (i.e. 0-9)
- Punctuation and other characters (e.g., !@#$%^&*()_+|~-=\`{}[]:";'<>?,./)

It is pretty easy to validate password based on those requirements, but sometimes we don't want requirements to be hard-coded. That's why I decided to store requirements as regular expressions. You can store each requirement as a separate reg exp in DB, you can also store additional "required" flag (if password doesn't match required criteria it is invalid). In my demo regular expressions are hard-coded, but they can be easily retrieved from DB.


Tuesday, September 23, 2008

mx:TextInput bug from Flexosaurus

Nearly five months ago I noticed mx:TextInput's bug. The following steps will reproduce the bug.

In the Application 1

- Enter some long string in the mx:TextInput e.g. "asd asdsa sadsadsa sadsad asdsa"

- Click on the "Button" button(it is setting text in the mx:TextInput to "yes")

- You will not be able to see the text in the mx:TextInput, you will be able to see the text if you e.g. click on the mx:TextInput

Application 1




<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
width="300" height="50" layout="absolute">

<mx:Script>

<![CDATA[

private function clickBtn(event:MouseEvent):void
{
txtInput.text = "yes";

}
]]>

</mx:Script>

<mx:Button id="btnSubmit" x="178" y="10" label="Button"
click="clickBtn(event)"/>
<mx:TextInput id="txtInput" x="10" y="10"/>

</mx:Application>



There is a few ways for fixing this problem. Here is one of them. We will create custom text input component and override public function set text(value:String):void function. In the text setter we will call initialize mx:TextInput text property (super.text = value;) and then we'll just bring the cursor to the begging.

Reproduce the bug for the Application 2 and you will be able to see the text.

Application 2




<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:ns1="*"
width="300" height="50" layout="absolute">

<mx:Script>

<![CDATA[

private function clickBtn(event:MouseEvent):void
{
txtInput.text = "yes";

}
]]>

</mx:Script>

<mx:Button id="btnSubmit" x="178" y="10" label="Button"
click="clickBtn(event)"/>
<ns1:CustomTextInput id="txtInput" x="10" y="10"/>

</mx:Application>


CustomTextInput.as

package
{
import mx.controls.Alert;
import mx.controls.TextInput;

public class CustomTextInput extends TextInput
{
public function CustomTextInput()
{
super();
}

override public function set text(value:String):void
{
super.text = value;

// Bringing cursor to the beginning
setSelection(1,1);
}
}
}

Sunday, August 3, 2008

3D Ferris Wheel from Flexosaurus

I just tried to implement something "3D" and here it is:) Actually it's just number of planes which you can rotate in the way the Ferris Wheel get rotated. You can also change the X,Y,Z angles of scene. E.g. you can change the angles, place the planes horizontally and you'll get whirling photo album. It is also very easy to make this planes clickable. The sample is powered by Away3D and Caurina Tweener.

SOURCE | SAMPLE

Thursday, July 17, 2008

Flexosaurus about Blogger API for ActionScript

Yesterday I was trying to get authenticating to the Blogger service, but I was getting following error. Error: [IOErrorEvent type="ioError" bubbles=false cancelable=false
eventPhase=2 text="Error #2032: Stream Error. URL:
https://www.google.com/accounts/ClientLogin"]. URL:
https://www.google.com/accounts/ClientLogin.

I found out that Google currently do not support cross-domain requests to Google Accounts from Flash. There is currently an issue filed against this here: http://code.google.com/p/gdata-issues/issues/detail?id=406 .

Anyhow I was able to get authorization token(it worked for Mozilla FireFox, but not for IE6), but not more than that. But it may be able to work around this by proxying requests through own domain, however. So maybe I will try.


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
applicationComplete="authotize()">

<mx:Script><![CDATA[

import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.mxml.HTTPService;

//Authorization Token
private var _auth:String;

public function authotize():void
{
var urlLoader:URLLoader = new URLLoader();
var urlRequest:URLRequest = new URLRequest();
var urlVariables:URLVariables = new URLVariables();

urlVariables.Email = {you_e-mail_here}
urlVariables.Passwd = {your_password_here}
urlVariables.service = "blogger";
urlVariables.source = "exampleCo-exampleApp-1";

urlRequest.url = "https://www.google.com/accounts/ClientLogin";
urlRequest.data = urlVariables;
urlRequest.method = URLRequestMethod.POST;

urlLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHTTPStatus);
urlLoader.addEventListener(Event.COMPLETE, onComplete);

urlLoader.load(urlRequest);
}

private function onComplete(event:Event):void
{
var str:String = event.currentTarget.data;
var index:int = str.indexOf("Auth=");
_auth = str.substring(index + 5, str.length - 1);
}

private function onHTTPStatus(event:HTTPStatusEvent):void
{
trace(event);
}

private function onError(event:Event):void
{
trace(event);
}

]]></mx:Script>

</mx:Application>

Tuesday, July 15, 2008

Editable chart with custom axis from Flexosaurus

Nearly one month ago I was needed to create a custom axis which contains controls. We have little time and we decided to round this problem and chose another approach. On previous weekend I decided to find out how it is possible to insert controls into axis and found it very easy. Following example is adding one image and one button with every label, it is also providing a way of editing chart run-time.




<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="{init()}"
width="460" height="450">


<mx:ColumnChart id="championsChart" dataProvider="{champions}">
<mx:horizontalAxis>
<mx:CategoryAxis id="horAxis" dataProvider="{champions}"
categoryField="Team"/>
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries xField="Team" yField="Count"
displayName="Team">
<mx:fill>
<mx:SolidColor color="0xc02314"/>
</mx:fill>
</mx:ColumnSeries>
</mx:series>
<mx:horizontalAxisRenderers>
<mx:AxisRenderer axis="{horAxis}">
<mx:labelRenderer>
<mx:Component>
<mx:VBox horizontalAlign="center">
<mx:HBox>
<mx:Image source="@Embed('../assets/f1logo.png')"/>
<mx:Label id="newLabel"/>
</mx:HBox>
<mx:Button label="EDIT" click="{outerDocument.onClick(event)}"/>
<mx:Script><![CDATA[
override public function set data(value:Object):void
{
if(value == null)
{
return;
}

newLabel.text = value.text;
}
]]></mx:Script>
</mx:VBox>
</mx:Component>
</mx:labelRenderer>
</mx:AxisRenderer>
</mx:horizontalAxisRenderers>
</mx:ColumnChart>

<mx:Script><![CDATA[

import mx.containers.*;
import mx.controls.Button;
import mx.controls.TextInput;
import mx.collections.ArrayCollection;
import mx.managers.PopUpManager;

private var titleWindow:TitleWindow;
private var countTextInput:TextInput;
private var saveButton:Button;
private var cancelButton:Button;
private var index:int;

[Bindable]

public var champions:ArrayCollection = new ArrayCollection
([
{Team:"Ferrari", Count:15},
{Team:"Williams", Count:9},
{Team:"McLaren", Count:8}
]);

public function onClick(e:Event):void
{
index = searchName(e.target.parent.newLabel.text);
titleWindow.title = e.target.parent.newLabel.text + " championships number";
PopUpManager.addPopUp(titleWindow,this,true);
PopUpManager.centerPopUp(titleWindow);
}

private function init():void
{
var vbox:VBox = new VBox();
var hbox:HBox = new HBox();

titleWindow = new TitleWindow();
countTextInput = new TextInput();
saveButton = new Button();
cancelButton = new Button()

cancelButton.addEventListener(MouseEvent.CLICK, onCancel);
saveButton.addEventListener(MouseEvent.CLICK, onSave);

saveButton.label = "SAVE";
cancelButton.label = "CANCEL";

hbox.addChild(saveButton);
hbox.addChild(cancelButton);

vbox.addChild(countTextInput);
vbox.addChild(hbox);

titleWindow.addChild(vbox);
}

private function onCancel(e:Event):void
{
PopUpManager.removePopUp(titleWindow);
countTextInput.text = "";
}

private function onSave(e:Event):void
{
champions.getItemAt(index).Count = (countTextInput.text == "") ? 10 : int(countTextInput.text);

PopUpManager.removePopUp(titleWindow);
countTextInput.text = "";

championsChart.dataProvider = champions;
}

private function searchName(name:String):int
{
for(var i:int = 0; i < champions.length; i++)
{
if(champions.getItemAt(i).Team == name)
{
return i;
}
}
return -1;
}

]]></mx:Script>
</mx:Application>