Home >
Anatomy of an Enterprise Flex RIA Part 19: User Section: The Search Process
Last installation we looked at the view and layout of our application, and now we're going to look at the search tools our application provides.
The rest of the user section is fairly straightforward, once you see how a Cairngorm application works. I’ve organized it into a series of panels in a TabNavigator to allow the user to choose which search type to use (see Figure 24).
If you open TitleSearch, BookSearch, or AuthorSearch, you’ll find that it extends SearchPanel, and each search calls SearchPanel.findBooks with different arguments depending on the type of search. Let’s look at SubjectSearch.mxml as an example.
<search:SearchPanel
...
>
<mx:Script>
...
private function showAll():void {
new GetAllSubjectsEvent().dispatch();
}
private function subjectSearch():void {
new FindSubjectsByNameEvent(subjectName.text).dispatch();
clearSearches();
}
private function findBooksBySubject():void {
findBooks(
SearchEvent.SUBJECT_SEARCH_TYPE,
subjectList.selectedItem);
}
</mx:Script>
...
First, notice that the root tag is SearchPanel, which means that we extend SearchPanel. Then there are some methods for the view: showAll looks for all subjects, firing off GetAllSubjectsEvent. subjectSearch executes FindSubjectsByNameEvent, passing in the text from the subject search text box. When one of these commands returns with a list of subjects, it puts them on the model, which is bound to a list on the view. findBooksBySubject calls the parent method, findBooks, which puts the subject in an event which fires up in the view chain to trigger a book search. We’ll see the code for that, but first here’s the rest of the SubjectSearch code:
...
<mx:List id="subjectList"
dataProvider="{model.subjects}" labelField="name"
width="100%"
/>
<mx:TextInput id="subjectName" enter="subjectSearch()" />
<mx:HBox>
<mx:Button id="searchButton" label="Search Subjects"
click="subjectSearch()"
enabled="{subjectName.text != ''}"
/>
<mx:Button
id="searchAllButton"
label="Show all Subjects"
click="showAll()"
/>
<mx:Button
id="findBooksButton"
label="Books on this Subject"
click="findBooksBySubject()"
enabled="{subjectList.selectedItem != null}"
/>
</mx:HBox>
</search:SearchPanel>
There’s the list I mentioned, subjectList, which binds to the collection of subjects (if any) a command finds on the service. Then there’s a text input that takes the subject name to find, and a few buttons. searchButton will call the subjectSearch method we saw before, and for safe searching, I disable that button unless there’s a term in the search text input. searchAllButton will call the showAll method, and findBooksButton calls the “find books” method. I disable the Find button unless there is a selected item in the subject list.
Now let’s look up the chain to the SearchPanel:
<mx:Panel ...>
<mx:Metadata>
[Event(name="bookSearch",
type="lcds.examples.bookie.event.SearchEvent")]
</mx:Metadata>
<mx:Script>
<![CDATA[
[Bindable]
protected var model:BookieModel =
BookieModel.getInstance();
protected function findBooks(searchType:String,
searchData:Object):void {
var event:SearchEvent = new SearchEvent();
event.searchType = searchType;
event.searchData = searchData;
dispatchEvent(event);
}
...
The findBooks method takes a search type and search data. These properties help to pick out whether the search is an author search, subject search, or title search. The method then dispatches a SearchEvent event with that data. The Metadata tag at the top of the page lets the compiler know that we’ll be emitting this type of event.
...
private function searchBooks(searchEvent:SearchEvent):void {
new FindBooksEvent(searchEvent).dispatch();
}
...
<search:TitleSearch
id="titleSearch"
label="Search by Title"
bookSearch="searchBooks(event)"
/>
<search:AuthorSearch
id="authorSearch"
label="Search by Author"
bookSearch="searchBooks(event)"
/>
<search:SubjectSearch
id="subjectSearch"
label="Search by Subject"
bookSearch="searchBooks(event)"
/>
...
The bookSearch event dispatched from each search panel is sent on to the searchBooks method in index.mxml, which dispatches an event that on the BookieController corresponds to a FindBooksCommand, whose execute method figures out what kind of search to do and calls the right delegate method:
package lcds.examples.bookie.command {
...
public class FindBooksCommand implements ICommand, IResponder {
public function execute(event:CairngormEvent):void {
var evt:FindBooksEvent = event as FindBooksEvent;
var searchData:SearchEvent = evt.searchEvent;
var delegate:BookieDelegate =
new BookieDelegate(this);
switch(searchData.searchType) {
case SearchEvent.AUTHOR_SEARCH_TYPE :
delegate.findBooksByAuthor(
Person(searchData.searchData));
break;
case SearchEvent.TITLE_SEARCH_TYPE :
delegate.findBooksByTitle(
String(searchData.searchData));
break;
case SearchEvent.SUBJECT_SEARCH_TYPE :
delegate.findBooksBySubject(
Subject(searchData.searchData));
break;
}
}
public function result(event:Object):void {
BookieModel.getInstance().books = event.result;
}
...
The result method of the command just sets the current collection of books to the appropriate model property: books. If you open lcds.examples.bookie.view.BookList you’ll notice that the main DataGrid’s dataProvider property is set to, you guessed it, BookieModel.books. Binding continues to amaze me in how simple it is and how easy it makes development.
Look at the reservation process and see whether you can track how it works. For the book selection process, start in lcds.examples.bookie.view.BookList, and for the reservation process, start in lcds.examples.bookie.view.Reserve
BooksPanel.
Next installment we're going to conclude by looking at the administration section of the application, look at managed data in Flex and LiveCycle Data Services, and see how server push works from JMS to Flex through LiveCycle Data Services. You can always find the entire series here.






Facebook Application Development
Hi Tony,
First of all, I wish to say that these are the greatest articles I've came across in a long time. seriously, great work.
Having said that, I missing the part of the jBoss deployment. as I read I see that it's not going to be discussed on the next installment, and I don't remember having read that on the previous ones.
am I missing something?
Many thanks and keep up the good work!
@Flexi (nice name) you should be able to see all the articles from the beginning here on this site.