You are on page 1of 27

Id do

Spis treci
Przykadowy rozdzia
Katalog ksiek

Hello! Flex 4
Autor: Peter Armstrong
Tumaczenie: Krzysztof Sawka
ISBN: 978-83-246-2881-0
Tytu oryginau: Hello! Flex 4
Format: 158235, stron: 272

Katalog online
Zamw drukowany
katalog
Twj koszyk
Dodaj do koszyka
Cennik i informacje
Zamw informacje
o nowociach
Zamw cennik
Czytelnia
Fragmenty ksiek
online

Kontakt
Helion SA
ul. Kociuszki 1c
44-100 Gliwice
tel. 32 230 98 63
e-mail: helion@helion.pl
Helion 19912010

Najnowszy Flex aktualna ksika. Wykorzystaj szans!


Jak stworzy swj pierwszy projekt?
Jak projektowa style?
Co wybra: AJAX czy Flex? A moe je poczy?
Flex w wersji 4 to najnowszy krzyk mody na rynku aplikacji webowych. Pozwala na tworzenie
rozwiza internetowych w niczym nieprzypominajcych tych, z ktrymi mamy do czynienia na
co dzie. S one atrakcyjne pod wzgldem graficznym, charakteryzuj si wysok interakcyjnoci
oraz nieprawdopodobnie ogromnymi moliwociami. Jeeli wspomnie jeszcze o tym, e jest to
rodowisko zupenie darmowe pora przygotowa si na rewolucj w wiecie aplikacji
internetowych!
Od marca 2010 roku dostpna jest najnowsza wersja Fleksa, oznaczona numerem 4. Warto
poznawa t wersj z podrcznikiem Hello! Flex 4 w doni. Znajdziesz tu wszechstronn wiedz
na temat jzykw ActionScript, XML, E4X, obiektw pierwotnych oraz zasad projektowania stylw.
Ponadto dowiesz si, jak tworzy efekty, animacje oraz jak wykorzysta obiekty typu DataGrid.
Jednak zanim dojdziesz do tych interesujcych, lecz zoonych zagadnie, bdziesz mia okazj
zapozna si z samym rodowiskiem oraz najlepszymi praktykami i metodami pracy. Jeeli chcesz
rozpocz przygod z najnowsz wersj rodowiska Flex nie moge lepiej trafi! Rozpocznij j
ju dzi!
Pierwsze kroki we Fleksie omwienie platformy
Nasuchiwanie zdarze
Wizanie danych adnotacja Bindable
Struktura aplikacji pisanych w rodowisku Flex
Jzyki ActionScript, XML, E4X
Definiowanie zmiennych i przestrzenie nazw
Obiekty, tablice oraz sterowanie przepywem
Dziedziczenie i inne pojcia obiektowe w rodowisku Flex
Skadniki typu Spark
Stany widoku
Projektowanie stylw
Tworzenie animacji i efektw specjalnych
Wykorzystanie obiektw typu DataGrid
Zastosowanie pojemnikw nawigacyjnych oraz elementw wyskakujcych
Projektowanie i tworzenie formularzy
Rozpocznij przygod z Flex 4 bez najmniejszych problemw!

Spis treci
PRZEDMOWA

PODZIKOWANIA

13
17

INFORMACJE NA TEMAT KSIKI


INFORMACJE O SERII HELLO!
1 PIERWSZE KROKI

21

23

2 JZYKI ACTIONSCRIPT 3, XML I E4X

51

3 WITAJ, SPARKU: OBIEKTY PIERWOTNE,


SKADNIKI, GRAFIKA FXG I MXML, A NAWET WIDEO

77

4 POJEMNIKI TYPU SPARK,


STANY WIDOKU, EFEKTY I PROJEKTOWANIE STYLW

121

5 HALO FLEX 4: STOSOWANIE OBIEKTW DATAGRID,


POJEMNIKW NAWIGACYJNYCH I ELEMENTW WYSKAKUJCYCH

6 TWORZENIE ATWYCH W OBSUDZE


FORMULARZY ZA POMOC FORMATERW
I ANALIZATORW POPRAWNO CI W RODOWISKU FLEX

7 CAIRNGORM W AKCJI:
SOCIALSTALKR (TWITTER + YAHOO! MAPS)
SKOROWIDZ

251

199

175

157

6
Tworzenie atwych
w obsudze formularzy
za pomoc
formaterw
i analizatorw poprawnoci
w rodowisku Flex
tym rozdziale nauczymy si obsugi formaterw i analizatorw poprawnoci, dziki ktrym tworzenie formularzy do wprowadzania danych staje
si przyjemnoci przynajmniej w porwnaniu z innymi rodowiskami
programistycznymi. Formatery rodowiska Flex s uywane gwnie do formatowania danych wywietlanych uytkownikowi w kontrolkach takich jak przedstawiony w rozdziale 5. obiekt DataGrid. Mog one rwnie by wykorzystywane do
pobierania danych wprowadzanych przez uytkownika i przeksztacania ich w poprawnie sformatowane dane wejciowe. Analizatory poprawnoci (ang. validator)
su w tym rodowisku do sprawdzania poprawnoci wprowadzanych danych
oraz wywietlania odpowiednich komunikatw w przypadku wprowadzenia nieprawidowych informacji.

Dokumentacja interfejsw API dotyczca formaterw i analizatorw poprawnoci


jest pod wieloma wzgldami znakomita, jednak jej sabym punktem zawsze byo
przedstawienie jednoczesnego zastosowania wspomnianych elementw dla jednej
kontrolki wykorzystywanej przez uytkownika. Istnieje pewne dobre usprawiedliwienie: wcale nie jest tak atwo przeprowadzi tak czynno poprawnie! Jeeli

176

ROZDZIA 6. Tworzenie formularzy za pomoc formaterw i analizatorw poprawnoci

jednak zaley nam, aby formularze byy jak najbardziej przydatne, jest to droga, na
ktr prdzej czy pniej musimy wstpi. Jeli tak si stanie, czas, jaki zaoszczdzicie po przeczytaniu tego rozdziau, moe by wart ceny caego podrcznika.
Ju od czasw rodowiska Flex 1.0 obsuga formatowania bya w nim przemylana
dobrze, a obsuga analizatorw poprawnoci jeszcze lepiej. Najwiksz innowacj
od tamtej pory jest wprowadzenie do klas analizatorw poprawnoci waciwoci
id oraz moliwo powizania danych z ich waciwociami. Zatem proces tworzenia aplikacji integrujcej formatowanie i analiz poprawnoci w tych samych
skadnikach zosta uatwiony.

Rozpoczniemy od utworzenia malutkiej aplikacji prbnej, ktra bdzie bezporednio wykorzystywaa wbudowane formatery i analizatory poprawnoci. Naszym zadaniem bdzie zaobserwowanie, w jaki sposb te obiekty dziaaj bez naszej
dodatkowej pomocy. Przejdziemy nastpnie do nieco bardziej skomplikowanego
zadania i napiszemy formularz AddressForm, w ktrym zostanie zaprezentowana
wsppraca formaterw i analizatorw poprawnoci w prawdziwej aplikacji. To
zadanie wymaga z naszej strony nieco wysiku: formularz AddressForm skada si
z okoo 180 linijek kodu, wic jest to najbardziej zoony przykad, z jakim mielimy dotychczas do czynienia. Nam to jednak nie przeszkadza lepiej zakoczy
ostatnie samodzielne sesje wielk eksplozj ni chlipaniem. Poza tym, chocia
omawiany kod moe wydawa si nudny, dla wielu programistw aplikacji w rodowisku Flex moe okaza si prawdziwym asem w rkawie podczas poszukiwania
pracy. Nie wspominajc o tym, e istnieje wiele moliwoci strzelenia sobie w stop
na etapie wizania danych podczas integracji formatowania z analiz poprawnoci,
przez co ten rozdzia okazuje si bardzo na miejscu.
W nastpnym rozdziale wprowadzimy jeszcze duszy przykad, w ktrym przez
okoo 50 stron bdziemy tworzy poczenie serwisw Twitter i Yahoo! Maps,
zatem moemy uzna przepraw przez kilka stron powiconych kodowi for-

Sesja 25. Formatery i analizatory poprawnoci

177

mularza za przystawk przed gwnym daniem. Wreszcie, bdziemy korzysta


w formularzu AddressForm ze skadnikw Form i FormItem typu Halo nie powiedzielimy wic jeszcze wszystkiego o tej architekturze.
Na pocztek jednak, zgodnie z obietnic, napiszmy niewielki przykad wykorzystujcy wbudowane formatery i analizatory poprawnoci.

SESJA 25. Formatery i analizatory poprawnoci

Obecn sesj rozpoczniemy od sprawdzenia moliwoci wbudowanych formaterw


i analizatorw poprawnoci w rodowisku Flex. Mgbym teraz zaprezentowa olbrzymi przykad wykorzystujcy wszystkie standardowe formatery i analizatory
poprawnoci, jednak nie ma to sensu, gdy dziaaj one na tej samej zasadzie (z wyjtkiem analizatora CreditCardValidator; szczegy znajdziemy w dokumentacji
interfejsw API).
Wszystkie formatery s podklasami wza mx.formatters.Formatter. W rodowisku
Flex 4 znajdziemy w tej klasie nastpujce podklasy: CurrencyFormatter, Date
Formatter, NumberFormatter, PhoneFormatter i ZipCodeFormatter. Klasa Formatter
definiuje metod format(), ktra musi zosta przesonita przez jej uywane
podklasy.
W analogiczny sposb wszystkie analizatory poprawnoci stanowi podklasy
wza mx.validators.Validator, ktry pozwala na implementacj analizy poprawnoci wobec danego pola poprzez ustanowienie wartoci true we waciwoci
required obiektu Validator. W rodowisku Flex 4 mamy do czynienia z nastpujcymi podklasami klasy Validator: CreditCardValidator, CurrencyValidator,

178

ROZDZIA 6. Tworzenie formularzy za pomoc formaterw i analizatorw poprawnoci

DateValidator, EmailValidator, NumberValidator, PhoneNumberValidator, RegExp


Validator, SocialSecurityValidator, StringValidator, StyleValidator oraz
ZipCodeValidator.

Skoro wic mechanizm ich dziaania jest taki sam, w tej sesji przyjrzymy si
jednemu formaterowi i jednemu analizatorowi poprawnoci: odpowiednio Currency
Formatter i CurrencyValidator. Wybraem je, poniewa przedstawienie ich interakcji nie stanowi problemu, a formatowanie walut moe by przez Was bardzo
podane. Zbudujemy niewielki programik, w ktrym obydwa obiekty bd wykorzystywane wobec tego samego pola TextInput typu Spark. Podczas tworzenia
formularza adresowego w nastpnej sesji poznamy wiele innych rodzajw formaterw i analizatorw poprawnoci.
Wygld tworzonej przez nas aplikacji podczas wprowadzania tekstu w pole Text
Input zosta zaprezentowany na rysunku 6.1.

Rysunek 6.1.
Wprowadzanie
tekstu
w formularzu
walutowym

Po przeniesieniu aktywnoci (za pomoc klawisza Tab) obiekt CurrencyFormatter


sformatuje tekst, co wida na rysunku 6.2.
Rysunek 6.2.
Sformatowanie
wprowadzonego
tekstu

Jeeli wprowadzimy niepoprawne dane i przeniesiemy aktywno, ich warto merytoryczna zostanie zakwestionowana i analizator poprawnoci wywietli komunikat widoczny na rysunku 6.3.
Rysunek 6.3.
Odpowied na
wprowadzenie
nieprawidowych
danych

Sesja 25. Formatery i analizatory poprawnoci

179

Widzimy tu implementacj wielu funkcji, ktre w niektrych rodowiskach programistycznych wymagayby olbrzymiej iloci kodu. Spjrzmy, jak sobie z tym radzi
rodowisko Flex (listing 6.1).
Listing 6.1. sesja25/src/Tester.mxml

n
o

p
q

<?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"
width="100%" height="100%">
<fx:Script><![CDATA[
protected function moneyTIFocusOutHandler(event:FocusEvent):void {
var formattedText:String =
currencyFormatter.format(moneyTI.text);
if (formattedText != "") {
moneyTI.text = formattedText;
}
}
]]></fx:Script>
<fx:Declarations>
<mx:CurrencyFormatter id="currencyFormatter"
precision="2" rounding="nearest"/>
<mx:CurrencyValidator id="currencyValidator" precision="2"
source="{moneyTI}" property="text" triggerEvent="focusOut"/>
</fx:Declarations>
<s:layout>
<s:VerticalLayout paddingTop="10" paddingLeft="10"/>
</s:layout>
<s:TextInput id="moneyTI"
focusOut="moneyTIFocusOutHandler(event)"/>
<s:Button label="Tak naprawd jestem tu po to, aby przenie na mnie
aktywno..."/>
</s:Application>

n Ta funkcja formatuje tekst w reakcji na zdarzenie focusOut.


o Przydzielamy tekst do obiektu moneyTI.text jedynie po jego pomylnym
sformatowaniu.
p Formater CurrencyFormatter bdzie zaokrgla kwot do penego centa.
q Analizator poprawnoci CurrencyValidator analizuje warto
waciwoci text obiektu moneyTI.
r Tutaj obsugujemy zdarzenie focusOut pola textInput obiektu moneyTI.

180

ROZDZIA 6. Tworzenie formularzy za pomoc formaterw i analizatorw poprawnoci

Zwrmy uwag, e gdybymy nie wprowadzili instrukcji dozoru o wewntrz


procedury moneyTIFocusOutHandler n, formater CurrencyFormatter p przydzielaby tekst do obiektu moneyTI r w kadym przypadku. Wynik nie byby
satysfakcjonujcy, poniewa nawet w przypadku wywietlenia przez analizator
CurrencyValidator q bdu byby to jedynie bd polegajcy na braku wpisanych
danych (poniewa formater CurrencyFormatter zostaby uruchomiony przed analizatorem). Wida to na rysunku 6.4.
Rysunek 6.4.
Komunikat o braku
wpisanych danych

Tak jest! Dowiedzielimy si, jak sprawi, aby formatery wsppracoway z analizatorami poprawnoci, i mamy ju pewno, e przy odrobinie ostronoci
w sprawdzaniu danych wyjciowych formatera moemy utworzy bardzo praktyczny interfejs uytkownika.

Punkty do zapamitania

Formatery su do eleganckiego formatowania danych.

Analizatory poprawnoci s stosowane do sprawdzania, czy warto odpowiada


zdefiniowanym w nich kryteriom. Zazwyczaj s one uywane wraz z polami
TextInput, jednak mog by rwnie implementowane w takich obiektach
jak DropDownList (przekonamy si o tym w nastpnej sesji).

Sesja 26. Praktyczne formularze, formatery i analizatory poprawnoci

W razie niepowodzenia formatery zwracaj pusty cig znakw, powinnimy


wic sprawdza je pod tym ktem, zanim przelemy ich warto gdzie dalej.
W przeciwnym razie bdzie analizowana za warto.

Jak dowiemy si z nastpnej sesji, moemy pisa wasne formatery i analizatory


poprawnoci.

181

SESJA 26. Praktyczne formularze, formatery


i analizatory poprawnoci
W tej sesji pogbimy nasz znajomo formaterw i analizatorw poprawnoci
poprzez zbudowanie formularza AddressForm, ktry bdzie tak podobny do normalnego formularza uywanego w rzeczywistoci, jak to tylko moliwe. Oczywicie
w prawdziwym wiecie nic nie jest tak proste jak w przypadku ksikowego przykadu, wic ta sesja rwnie nie bdzie atwa. Wykorzystamy tu wiele rodzajw
analizatorw poprawnoci, zwaszcza NumberValidator, RegExpValidator, String
Validator i ZipCodeValidator. Wprowadzimy rwnie klas ZipCodeFormatter.
W tabeli 6.1 zostao wyjanione zastosowanie kadej z wymienionych klas w naszym
przykadzie.
Tabela 6.1. Klasy zastosowane w sesji 26.
Klasa

Zastosowanie w sesji

NumberValidator

Sprawdzanie, czy obiekty DropDownList posiadaj wybrane wartoci.

RegExpValidator

Przeprowadzanie niestandardowej analizy kanadyjskich kodw


pocztowych.

StringValidator

Sprawdzanie, czy w polach Ulica i Miasto zostaa wprowadzona


minimalna ilo tekstu.

ZipCodeValidator

Sprawdzanie amerykaskich kodw pocztowych (ang. zip code).

ZipCodeFormatter

Formatowanie amerykaskich i kanadyjskich kodw pocztowych.

Rysunek 6.5 przedstawia wygld aplikacji budowanej w tej sesji.


Tworzymy skadnik AddressForm wielokrotnego uytku, element Address, ktry
bdzie w nim wykorzystywany, oraz aplikacj Tester demonstrujc przeczanie
si pomidzy elementami Address i prawidow odpowied formularza Address
Form (podobnie jak pozostae fragmenty kodu umieszczone w tej ksice i ten
jest objty licencj MIT, moemy wic wprowadzi go do wasnej aplikacji).

182

ROZDZIA 6. Tworzenie formularzy za pomoc formaterw i analizatorw poprawnoci

Rysunek 6.5.
Przykadowy
formularz
adresowy

Jak zostao to pokazane na rysunku 6.6, po zaznaczeniu elementu Address umieszczonego w obiekcie List formularz AddressForm zostaje wypeniony danymi wybranego adresu.
Rysunek 6.6.
Wprowadzenie
do formularza
gotowych danych
adresowych

Zachowanie naszej aplikacji bdzie przedstawiane na kolejnych rysunkach podczas


omawiania kodu. Tymczasem przyjrzyjmy si na listingu 6.2 aplikacji Tester.
Listing 6.2. sesja26/src/Tester.mxml
<?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"

Sesja 26. Praktyczne formularze, formatery i analizatory poprawnoci

xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:comp="components.*"
width="100%" height="100%">
<fx:Script><![CDATA[
import mx.controls.Alert;
import mx.collections.ArrayCollection;
import model.Address;
n

[Bindable]
private var _addresses:ArrayCollection = new ArrayCollection([
new Address("1944 S El Camino Real", "", "San Mateo",
"Kalifornia", "USA", "94403"),
new Address("788 Denman Street", "", "Vancouver",
"Kolumbia Brytyjska", "Kanada", "V6G 2L5"),
new Address("25 Oxford Street", "", "Londyn",
"", "Wielka Brytania", "W1D 2DW"),
new Address("21 Water Street", "#400", "Vancouver",
"Kolumbia Brytyjska", "Kanada", "V6B 1A1")]);
protected function submitClickHandler(event:MouseEvent):void {
if (addressForm.validateAndSave()) {
Alert.show("Dostan teraz numer karty kredytowej?",
"Adres prawidowy!");
} else {
Alert.show("Dostrzegam bdy", "O nie!");
}
}

private function enterNewAddress():void {


addressList.selectedItem = null;
}
]]></fx:Script>
<s:layout>
<s:VerticalLayout paddingLeft="10" paddingTop="10" gap="5"/>
</s:layout>
q
<s:List id="addressList" dataProvider="{_addresses}"
width="380" height="60"/>
<s:Button label="Wprowad nowy adres" click="enterNewAddress()"/>
<s:Panel title="Adres">
<s:layout>
<s:VerticalLayout paddingLeft="5" paddingTop="5" gap="10"/>
</s:layout>
<comp:AddressForm id="addressForm"
r
address="{addressList.selectedItem}"/>
</s:Panel>
s
<s:Button label="Wylij" click="submitClickHandler(event)"/>
</s:Application>

183

184

ROZDZIA 6. Tworzenie formularzy za pomoc formaterw i analizatorw poprawnoci

n Zmienna _addresses typu ArrayCollection przechowuje adresy, ktrych


bdziemy uywa (dwa pierwsze s adresami uwielbianych przeze mnie
restauracji, odpowiednio Santa Ramen i Kintaro Ramen).
o Funkcja submitClickHandler sprawdza i zapisuje wprowadzony adres, a take
wywietla odpowiedni alert w oparciu o wynik.
p Funkcja enterNewAddress po prostu ustanawia warto null dla elementu
selectedItem i jednoczenie powoduje utworzenie wizania z waciwoci
address.
q Obiekt addressList posiada dostawc dataProvider zmiennej _addresses.
r Formularz addressForm zawiera waciwo address powizan z waciwoci
selectedItem obiektu addressList.
s Zdarzenie typu click wobec przycisku Wylij powoduje uruchomienie
procedury submitClickHandler.
Rozpoczynamy od utworzenia tablicy ArrayCollection n dla zmiennej _addresses,
ktra peni funkcj dostawcy danych dataProvider z listy addressList q. Warto
waciwoci selectedItem z tej listy zostaje przekazana do tworzonego przez nas
formularza AddressForm r. Posiadamy take przycisk Wylij s, ktrego zdarzenie
typu click jest obsugiwane przez funkcj wywoujc metod validateAndSave o
formularza AddressForm oraz ktry powoduje wywietlenie jednego z dwch
alertw w zalenoci od wyniku. Moemy wybra rwnie przycisk Wprowad nowy
adres wywoujcy funkcj enterNewAddress p, ktra powoduje wyczyszczenie pl
z wprowadzonymi danymi.
Rysunek 6.7 ilustruje zachowanie programu po wykryciu bdnych danych.
Rysunek 6.7.
Alert informujcy
o niewaciwych
danych

Sesja 26. Praktyczne formularze, formatery i analizatory poprawnoci

185

W podobny sposb przedstawiamy na rysunku 6.8 informacje o wprowadzeniu


danych zakoczonym sukcesem.
Rysunek 6.8.
Informacja
o wprowadzeniu
poprawnego
adresu

Stworzymy teraz model klasy Address (listing 6.3).


Listing 6.3. sesja26/src/model/Address.as
n

package model {
[Bindable]
public class Address {
public var lineOne:String;
public var lineTwo:String;
public var city:String;
public var zipCode:String;
public var state:String;
public var country:String;
public function Address(
lineOne:String = "",
lineTwo:String = "",
city:String = "",
state:String = "",
country:String = "",
zipCode:String = "") {
this.lineOne = lineOne;
this.lineTwo = lineTwo;
this.city = city;
this.state = state;
this.country = country;
this.zipCode = zipCode;
}

186

ROZDZIA 6. Tworzenie formularzy za pomoc formaterw i analizatorw poprawnoci

private function getAddrStr(str:String):String {


return (str == null || str == "") ? "" : str + " ";
}
p

public function toString():String {


return getAddrStr(lineOne) + getAddrStr(lineTwo) +
getAddrStr(city) + getAddrStr(state) +
getAddrStr(country) + getAddrStr(zipCode);
}
}
}

Model Address nie jest skomplikowany: chcemy, aby mona byo powiza dane
z kad zmienn, zatem wprowadzamy adnotacj [Bindable] n na pocztku klasy
(tworzenie powizanych danych generuje wiksz ilo kodu, zatem nie powinnimy go naduywa). Po drugie, tworzymy konstruktor o posiadajcy domylne
wartoci (puste cigi znakw) dla wszystkich swoich parametrw. Moemy w ten
sposb okreli niektre z tych parametrw (lub nie zdefiniowa adnego z nich)
podczas tworzenia nowego obiektu Address. Wreszcie tworzymy funkcj toString
p, ktra wykorzystuje metod getAddrStr suc do pomijania dodatkowych
spacji w przypadku obiektw Address posiadajcych wypenionych tylko kilka
pl (tak, na samym kocu znajdzie si jedna niepotrzebna spacja; wiczeniem
dla czytelnikw bdzie pozbycie si jej).
Podobnie jak w jzyku Java, metoda toString zostaje wywoana zawsze wtedy, gdy
obiekt ma zosta zaprezentowany jako obiekt typu String, czsto natomiast jest
przesaniana w sposb umoliwiajcy bardziej uyteczne przedstawienie danych.
Zwrmy uwag, e nie robi w tej metodzie toString nic zego, generalnie jednak
kod modelu nie powinien definiowa informacji dotyczcych poziomu widoku.
Zanim utworzymy formularz AddressForm, zaprezentuj kilka zrzutw ekranu
przedstawiajcych rne jego funkcje oraz wywietlanie bdw walidacji.
Po pierwsze, rysunek 6.9 przedstawia sytuacj, w ktrej wpisywany jest kod
pocztowy Stanw Zjednoczonych zamiast kanadyjskiego, co powoduje wywietlenie odpowiedniej informacji (jest to niekonwencjonalne zachowanie analizatora ZipCodeValidator, ktre naprawiamy w tym przykadzie).
Zwrmy take uwag, e dla Kanady etykiety formularza maj nazwy Prowincja
i Kod poczt., a nie Stan i Kod pocztowy (zarezerwowane dla Stanw Zjednoczonych).

Sesja 26. Praktyczne formularze, formatery i analizatory poprawnoci

187

Rysunek 6.9.
Efekt wpisania
niewaciwego
kodu pocztowego

Odnotujmy teraz fakt, e jeeli wpiszemy kanadyjski kod pocztowy w miejscu


przeznaczonym na kod Stanw Zjednoczonych, zostanie wywietlony bd, a nieprawidowe dane nie zostan wyczyszczone przez formater (rysunek 6.10).
Rysunek 6.10.
Kanadyjski
kod pocztowy
wpisany w miejsce
amerykaskiego

Po napisaniu tego przykadu ujrzycie formatery w akcji: bdziecie mogli aktualizowa kody pocztowe Stanw Zjednoczonych do nowego stylu 5+4, pisa kody
pocztowe Kanady od duej litery i dodawa spacje pomidzy ich segmentami.
Tak, naprawd jest to tak pasjonujce, jak si wydaje.

188

ROZDZIA 6. Tworzenie formularzy za pomoc formaterw i analizatorw poprawnoci

Wreszcie na rysunku 6.11 widzimy, e wykorzystujemy analizator poprawnoci


rwnie do wprowadzenia wymogu, aby uytkownik wybra jeden ze stanw USA
(lub prowincj w Kanadzie), a take wpisa odpowiedni kod pocztowy.
Rysunek 6.11.
Proba o wybr
stanu

Dla krajw innych ni Stany Zjednoczone lub Kanada nie wymagamy wyboru prowincji czy wpisania kodu pocztowego, co wida na rysunku 6.12.
Rysunek 6.12.
Obsuga pastwa
innego ni USA
lub Kanada

Nie tylko zostaj pominite bdy, lecz take znikaj czerwone gwiazdki oznaczajce,
e uzupenienie danego pola jest wymagane.

Sesja 26. Praktyczne formularze, formatery i analizatory poprawnoci

189

Bez niepotrzebnego przeduania przejdmy do tworzenia formularza AddressForm


(nareszcie!). Mamy tu do czynienia ze spor iloci kodu, wic rozbijemy go na
kilka czci, z ktrych kada zostanie dokadnie objaniona. Zaczniemy od
pocztku (listing 6.4).
Listing 6.4. sesja26/src/components/AddressForm.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Form
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="400">
<fx:Script><![CDATA[
import mx.collections.ArrayCollection;
import mx.events.ValidationResultEvent;
import mx.validators.Validator;
import model.Address;
n

private var _address:Address = new Address();

public function validateAndSave():Boolean {


if (isFormValid()) {
address.lineOne = addressOneTI.text;
address.lineTwo = addressTwoTI.text;
address.city = cityTI.text;
address.country = countryDDL.selectedItem;
if (stateDDL.dataProvider.length == 0) {
address.state = "";
} else {
address.state = stateDDL.selectedItem;
}
address.zipCode = zipTI.text;
return true;
} else {
return false;
}
}
private function isFormValid():Boolean {
var validators:Array = [addressValidator, cityValidator,
countryValidator, stateValidator];
var zipCodeValid:Boolean = validateAndFormatZipCode();
var results:Array = Validator.validateAll(validators);
return results.length == 0 && zipCodeValid;
}
private function setFormFromAddress():void {

190

ROZDZIA 6. Tworzenie formularzy za pomoc formaterw i analizatorw poprawnoci

addressOneTI.text = address.lineOne;
addressTwoTI.text = address.lineTwo;
cityTI.text = address.city;
countryDDL.selectedItem = address.country;
var states:ArrayCollection = getStates(address.country);
stateDDL.dataProvider = states;
stateDDL.selectedIndex = states.source.indexOf(address.state);
zipTI.text = address.zipCode;
}

n Zmienna _address przechowuje obiekt Address edytowany w formularzu


AddressForm.
o Metoda validateAndSave jest wywoywana przez aplikacj Tester. Wywouje
ona z kolei funkcj isFormValid, ktra sprawdza poprawno wszystkich
skadnikw formularza. Jeeli skadniki te s prawidowe, adres zostaje
zaktualizowany o umieszczone w nich wartoci. Takie rozwizanie zapobiega
wprowadzeniu do obiektu Address nieprawidowych lub tylko czciowo
poprawnych danych.
p Przydzielamy dla danego stanu warto "", jeli warto waciwoci
selectedItem jest rwna null (nie wybralimy adnego skadnika),
na przykad gdy lista stanw (prowincji) jest pusta dla danego kraju.
q Metoda isFormValid uruchamia analizatory poprawnoci poprzez utworzenie
ich tablicy Array i wywoanie wobec niej funkcji Validator.validateAll.
Aktywuje ona rwnie oddzielnie analizator kodu pocztowego poprzez
wywoanie funkcji o nazwie validateAndFormatZipCode, ktr w dalszej czci
opisu przeanalizujemy. Jeeli w wywoaniu funkcji Validator.validateAll
pojawi si jakiekolwiek bdy walidacji, warto obiektu results.length
bdzie niezerowa. Zwrmy uwag, e stosujemy tymczasow zmienn
dla obiektu zipCodeValid, poniewa nie chcemy, aby w trakcie analizy
poprawnoci nastpio uproszczenie skutkujce pominiciem metody
validateAndFormatZipCode (mamy zamiar wywoa naraz wszystkie
analizatory poprawnoci i wywietli wszystkie bdy walidacji).
r Metoda setFormFromAddress aktualizuje stan formularza w oparciu o stan
adresu. Poniewa jest to przeprowadzane wewntrz jednej metody, mamy
pewno, e wybralimy waciwe pastwo, zanim zaktualizujemy stany.
Po przejrzeniu kodu formularza widocznego na listingu 6.5 znaczenie tego
rozwizania stanie si bardziej zrozumiae.

Sesja 26. Praktyczne formularze, formatery i analizatory poprawnoci

191

Listing 6.5. sesja26/src/components/AddressForm.mxml (kontynuacja)

s public function set address(value:Address):void {


if (value == null) {
_address = new Address();
setFormFromAddress();
} else {
_address = value;
setFormFromAddress();
callLater(isFormValid);
}
}
[Bindable]
public function get address():Address {
return _address;
}
t

private static const EMPTY:ArrayCollection =


new ArrayCollection([]);
private static const COUNTRIES:ArrayCollection =
new ArrayCollection(["USA", "Kanada", "Wielka Brytania", "Francja"]);
private static const STATES:ArrayCollection =
new ArrayCollection(["Kalifornia", "Oregon", "Waszyngton"]);
private static const PROVINCES:ArrayCollection =
new ArrayCollection(["Kolumbia Brytyjska", "Alberta",
"Saskatchewan"]);

private function getStates(country:String):ArrayCollection {


if (isUSA(country)) {
return STATES;
} else if (isCanada(country)) {
return PROVINCES;
} else {
return EMPTY;
}
}
private function usaOrCanada(country:String):Boolean {
return isUSA(country) || isCanada(country);
}
private function isUSA(country:String):Boolean {
return country == "USA";
}
private function isCanada(country:String):Boolean {
return country == "Kanada";

192

ROZDZIA 6. Tworzenie formularzy za pomoc formaterw i analizatorw poprawnoci

}
private function getStateMsg(country:String):String {
return isUSA(country) ? "Prosz wybra stan." :
"Prosz wybra prowincj.";
}

s Setter adresu tworzy nowy obiekt Address, jeeli przekazana warto wynosi
null. W kadym przypadku po ustanowieniu tego adresu wywoywana jest
funkcja setFormFromAddress, jednak tam, gdzie zostaje przekazana
niezerowa warto, wywoujemy take metod isFormValid (zostaa
wczeniej zaprezentowana) poprzez wywoanie metody callLater.
Za jej pomoc dajemy kontrolkom formularza czas na odzwierciedlenie
nowych wartoci, ktre zostay dla nich ustanowione (nie omawiaem
w tym podrczniku metody callLater, gdy stanowi ona zaawansowan
technologi. W oglnym zarysie opnia ona uruchomienie funkcji zostaje
ona uruchomiona w nastpnym cyklu odwieania ekranu dziki czemu
wartoci mog zosta odzwierciedlone). Powodem przeprowadzania przez
nas analizy poprawnoci jedynie w przypadku niezerowych wartoci obiektu
Address jest ch uniknicia wielu bdw walidacji w przypadku pustego
formularza wygldaoby to po prostu brzydko (poza tym mogoby by
mylce, poniewa uytkownik nie popeni jeszcze adnego bdu
w pustym formularzu!). Tworzymy rwnie pod metod isFormValid getter
adresu, ktry jest o wiele prostszy.
t Te stae stanowi oczywicie podrcznikowy przykad. Na wiecie istnieje
o wiele wicej pastw, stanw i prowincji, ni przedstawiem to w aplikacji.
Wanie uratowaem drzewo przed przerobieniem na papier.
u Funkcja getStates zwraca warto STATES dla Stanw Zjednoczonych,
PROVINCES dla Kanady i EMPTY dla reszty wiata. Jest to tak lubiane przez
nas amerykocentryczne zachowanie; midzynarodowi czytelnicy mog
w razie potrzeby dowolnie modyfikowa ten kod!
v Te cztery wygodne funkcje s wykorzystywane w formularzu do ukazywania
(chowania) gwiazdek przy polach wymagajcych uzupenienia, obok
potomkw obiektw FormItem. Wprowadziem je do kodu, poniewa
wykorzystuj je w wizaniu danych oraz dlatego, e s w prosty sposb
odczytywane.
Czas na dalsz cz kodu (listing 6.6).

Sesja 26. Praktyczne formularze, formatery i analizatory poprawnoci

Listing 6.6. sesja26/src/components/AddressForm.mxml (kontynuacja)

private function validateAndFormatZipCode():Boolean {


var unformattedText:String =
zipTI.text.toUpperCase().replace(/\W/g, "");
var country:String = countryDDL.selectedItem;
var result:ValidationResultEvent;
var usa:Boolean = isUSA(country);
var canada:Boolean = isCanada(country);
zipCodeValidator.required = usa;
postalCodeValidator.required = canada;
if (usa) {
postalCodeValidator.validate("");
result = zipCodeValidator.validate(unformattedText);
} else if (canada) {
zipCodeValidator.validate("");
result = postalCodeValidator.validate(unformattedText);
} else {
postalCodeValidator.validate("");
zipCodeValidator.validate("");
return true;
}
if (result.type == ValidationResultEvent.VALID) {
if (usa) {
zipTI.text = zipCodeFormatter.format(unformattedText);
} else {
zipTI.text = postalCodeFormatter.format(unformattedText);
}
return true;
} else {
return false;
}
}
]]></fx:Script>
<fx:Declarations>
<mx:StringValidator id="addressValidator" minLength="5"
source="{addressOneTI}" property="text" required="true"
requiredFieldError="To pole jest wymagane."/>
<mx:StringValidator id="cityValidator" minLength="2"
source="{cityTI}" property="text" required="true"
requiredFieldError="To pole jest wymagane."/>
<mx:NumberValidator id="countryValidator"
lowerThanMinError="Prosz wybra kraj."
source="{countryDDL}" property="selectedIndex" minValue="0"/>
<mx:NumberValidator id="stateValidator"
lowerThanMinError="{getStateMsg(countryDDL.selectedItem)}"

193

194

ROZDZIA 6. Tworzenie formularzy za pomoc formaterw i analizatorw poprawnoci

source="{stateDDL}" property="selectedIndex"
enabled="{usaOrCanada(countryDDL.selectedItem)}"
minValue="0"/>
<mx:ZipCodeFormatter id="zipCodeFormatter"
formatString="#####-####"/>
<mx:ZipCodeFormatter id="postalCodeFormatter"
formatString="### ###"/>
<mx:ZipCodeValidator id="zipCodeValidator"
listener="{zipTI}"
wrongUSFormatError="Kod pocztowy ZIP+4 musi mie format '12345-6789'."
requiredFieldError="To pole jest wymagane."/>
<mx:RegExpValidator id="postalCodeValidator"
listener="{zipTI}"
expression="^[A-Z]\d[A-Z]\d[A-Z]\d$"
noMatchError="Kod pocztowy jest nieprawidowy."/>
</fx:Declarations>

w Funkcja validateAndFormatZipCode zwraca wynik walidacji i analizy


formatowania kodu pocztowego.
Dla Stanw Zjednoczonych zostaje uruchomiona funkcja zipCodeValidator.
Dla Kanady zostaje uruchomiona funkcja postalCodeValidator.
Jeeli otrzymamy warto VALID, zostan uruchomione formatery. Dla Stanw
Zjednoczonych zostanie uruchomiony formater zipCodeFormatter; dla
Kanady bdzie to postalCodeFormatter (poniewa kody pocztowe s
sprawdzane tylko dla Stanw Zjednoczonych i Kanady, uzasadnione jest
wprowadzenie przypadku else).
Tworzymy wystpienia analizatora StringValidator zapewniajce zachowanie
okrelonej minimalnej dugoci danych wejciowych. Obiekt source jest
skadnikiem przechowujcym analizowan waciwo.
Analizatory countryValidator i stateValidator s wystpieniami analizatora
NumberValidator uruchamianymi wobec waciwoci selectedIndex list
DropDownList zawierajcych dany kraj i stan. Tak, jest to powszechnie
uwaane za najlepsze rozwizanie.
Analizator stateValidator jest dostpny wycznie dla Stanw Zjednoczonych
lub Kanady.
Formater zipCodeFormatter wykorzystuje amerykaski format kodw
pocztowych 5+4.
Jakby poziom zagmatwania by zbyt may, postalCodeFormatter jest
formaterem ZipCodeFormatter.

Sesja 26. Praktyczne formularze, formatery i analizatory poprawnoci

195

Analizator zipCodeValidator wykorzystuje wbudowany analizator


ZipCodeValidator.
Analizator postalCodeValidator wykorzystuje wbudowany analizator
RegExpValidator do sprawdzania kanadyjskich kodw pocztowych
za pomoc wyrae regularnych.
Przechodzimy do ostatniej czci kodu (listing 6.7).
Listing 6.7. sesja26/src/components/AddressForm.mxml (kontynuacja)

<mx:FormItem label="Ulica" required="true" width="100%">


<s:TextInput id="addressOneTI" width="250"/>
<s:TextInput id="addressTwoTI" width="250"/>
</mx:FormItem>
<mx:FormItem label="Miasto" required="true" width="100%">
<s:TextInput id="cityTI" width="100%"/>
</mx:FormItem>
<mx:FormItem label="Kraj" required="true">
<s:DropDownList id="countryDDL" width="150"
dataProvider="{COUNTRIES}" prompt="Wybierz..."
change="validateAndFormatZipCode();"/>
</mx:FormItem>
<mx:FormItem
label="{isUSA(countryDDL.selectedItem) ? 'Stan' : 'Prowincja'}"
required="{usaOrCanada(countryDDL.selectedItem)}">
<s:DropDownList id="stateDDL" width="150"
dataProvider="{getStates(countryDDL.selectedItem)}"
prompt="Wybierz..."
enabled="{stateDDL.dataProvider.length > 0}"/>
</mx:FormItem>
<mx:FormItem
label="Kod {isUSA(countryDDL.selectedItem) ? 'pocztowy' : 'poczt.'}"
width="100%" required="{usaOrCanada(countryDDL.selectedItem)}">
<s:TextInput id="zipTI" width="150"
focusOut="validateAndFormatZipCode()"/>
</mx:FormItem>
</mx:Form>

Skadniki FormItem stanowi jedynie elementy ukadu graficznego, podobnie


jak sam pojemnik Form. Pojemnik ten nie posiada adnych dodatkowych
funkcji w przeciwiestwie do formularzy jzyka HTML obecne w rodowisku
Flex obiekty Form typu Halo s wycznie narzdziami ukadu graficznego.

196

ROZDZIA 6. Tworzenie formularzy za pomoc formaterw i analizatorw poprawnoci

Nazwy pastw znajduj si w obiekcie countryDDL listy DropDownList.


Podczas zmiany pastwa wywoujemy metod
validateAndFormatZipCode() w celu sprawdzenia kodu pocztowego.
Waciwo selectedItem obiektu countryDDL jest uywana do sprawdzania,
czy obiekty FormItem s wymagane. Jedynym skutkiem wprowadzenia tej
waciwoci jest wywietlenie niewielkiej czerwonej gwiazdki. Nie ma ona
adnego wpywu na kontrolki znajdujce si we wntrzu obiektu FormItem,
chyba e jest wykorzystywana rwnie przez te elementy.
Waciwo dataProvider obiektu stateDDL jest okrelana przez waciwo
selectedItem obiektu countryDDL.
Waciwo selectedItem obiektu countryDDL jest uywana do okrelenia
etykiety obiektu FormItem dla pl Kod pocztowy (Kod poczt.) oraz Stan
(Prowincja).
Zdarzenie focusOut obiektu zipTI uruchamia funkcj validateAndFormat
ZipCode, dziki czemu bdy w kodzie pocztowym s natychmiast
wychwytywane.
Ufffff!
To by bardzo dugi przykad, przez ktry przewiny si nawet wyraenia regularne.
Przepraszam za to gdybym na samym pocztku powiedzia, co Was tu czeka,
moglibycie omin t sesj! Cae szczcie w rodowisku Flex znajduje si klasa
RegExpValidator pozwalajca nam w bardzo atwy sposb konstruowa analizatory
poprawnoci wykorzystujce wyraenia regularne.
Kto by si spodziewa, e kody pocztowe mog by tak skomplikowane (co wicej,
cakowicie zignorowalimy ca reszt wiata, wic waciwy przebieg tego wiczenia
mgby wyglda jeszcze gorzej!)?

Sesja 26. Praktyczne formularze, formatery i analizatory poprawnoci

197

Punkty do zapamitania
}

rodowisko Flex zawiera pewn liczb przydatnych formaterw


i analizatorw poprawnoci.

We Fleksie mona (wzgldnie) atwo tworzy niestandardowe skadniki, ktre


pozwalaj na jednoczesne wykorzystywanie wbudowanych formaterw
i analizatorw poprawnoci, dziki czemu zwiksza si atwo obsugi
aplikacji.

Naley by ostronym podczas stosowania wizania danych wobec


wspzalenych skadnikw formularza, na przykad wobec list DropDownList
zawierajcych nazwy pastw i prowincji. Moemy utworzy formularz
waciwie dziaajcy podczas modyfikowania nowego modelu obiektowego,
ale nie rozwie to problemu obsugi modelu obiektowego ustanowionego
w zewntrznym wiecie.

W pewnych sytuacjach funkcja callLater moe zosta wykorzystana


do rozwizania problemw z synchronizacj czasow interfejsu uytkownika.
Rozwizanie takie naley jednak stosowa ostronie, poniewa istnieje pokusa
jego naduywania przy jednoczesnym ignorowaniu lecych u podstaw
problemw.

Obiekty Form i FormItem stanowi jedynie narzdzia ukadu graficznego.


Nie ma potrzeby, aby stosowa je do wysyania formularzy inaczej ni
ma to miejsce w jzyku HTML. Uznajmy je za pojemniki VGroup pozwalajce
na adne rozmieszczenie pl formularza.

198

ROZDZIA 6. Tworzenie formularzy za pomoc formaterw i analizatorw poprawnoci

Co dalej?

Na przestrzeni caej ksiki staram si pokaza, e w rodowisku Flex mona


w bardzo prosty sposb tworzy niestandardowe skadniki. W tej sesji zgbilimy
wiat formaterw i analizatorw poprawnoci, tworzc midzy innymi wasny analizator poprawnoci i zoony, niestandardowy formularz.
Nie wiem jak Wy, ale ja mam ju zupenie do formularzy pomimo ich przydatnoci. W nastpnym rozdziale zrobimy co z zupenie innej beczki i bdziemy
si wreszcie bawi podczas budowania naszego poczenia serwisw Twitter i Yahoo!
Maps. Dowiemy si, jak naley budowa prawdziw aplikacj, w jaki sposb mona
projektowa wiksze programy w rodowisku Cairngorm, a take jak mona porozumiewa si z serwerami za pomoc klasy HTTPService.