<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" 
      xmlns:thr="http://purl.org/syndication/thread/1.0">
  <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-12.html" />
  <link rel="self" type="application/atom+xml" href="http://www.insideria.com/atom.xml" />
  <id>tag:www.insideria.com,2009://34/tag:www.insideria.com,2008://34.23811-</id>
  <updated>2009-11-16T15:43:14Z</updated>
  <title>Comments for Anatomy of an Enterprise Flex RIA Part 19: User Section: The Search Process (http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-12.html)</title>
  <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.21-en</generator>
  <entry>
    <id>tag:www.insideria.com,2008://34.23811</id>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-12.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://blogs.oreilly.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=34/entry_id=23811" title="Anatomy of an Enterprise Flex RIA Part 19: User Section: The Search Process" />
    <published>2008-05-27T17:40:36Z</published>
    <updated>2009-06-08T17:20:15Z</updated>
    <title>Anatomy of an Enterprise Flex RIA Part 19: User Section: The Search Process</title>
    <summary>In the last installment of Anatomy of an Enterprise Flex RIA, we worked on building the Flex view. In this installment we&apos;re going to continue looking into the Flex view by examining the search tools in our application.</summary>
    <author>
      <name>Tony Hillerson</name>
      
    </author>
    
    <category term="Features" />
    
    <content type="html" xml:lang="en" xml:base="http://www.insideria.com/">
      <![CDATA[<p>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.</p>

<p>The rest of the user section is fairly straightforward, once you see how a Cairngorm application works. I&#8217;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).</p> 

<div class="ap_c"><a href="http://www.insideria.com/upload/2008/05/anatomy_of_an_enterprise_flex/series19_figure24.jpg" class="highslide" onclick="return hs.expand(this)"><img src="http://www.insideria.com/upload/2008/05/anatomy_of_an_enterprise_flex/series19_figure24.jpg" alt="series19_figure24.jpg" title="Click to enlarge" width="400"/></a><div class="apcaption">Figure 24. Searching by author</div></div>

<p>If you open TitleSearch, BookSearch, or AuthorSearch, you&#8217;ll find that it extends SearchPanel, and each search calls SearchPanel.findBooks with different arguments depending on the type of search. Let&#8217;s look at SubjectSearch.mxml as an example.</p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
&lt;search:SearchPanel
...
&gt;
    &lt;mx:Script&gt;
    ...
    <span class="category1">private</span> <span class="category1">function</span> showAll():<span class="category1">void</span> {
          <span class="category1">new</span> GetAllSubjectsEvent().dispatch();
     }
    
    <span class="category1">private</span> <span class="category1">function</span> subjectSearch():<span class="category1">void</span> {
          <span class="category1">new</span> FindSubjectsByNameEvent(subjectName.<span class="category2">text</span>).dispatch();
          clearSearches();
     }

    <span class="category1">private</span> <span class="category1">function</span> findBooksBySubject():<span class="category1">void</span> {
          findBooks(
               SearchEvent.SUBJECT_SEARCH_TYPE,
               subjectList.selectedItem);
     }
    &lt;/mx:Script&gt;
...</pre>
</code>

</div></div>

<p>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&#8217;ll see the code for that, but first here&#8217;s the rest of the SubjectSearch code:</p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
...
    &lt;mx:List id="<span class="quote">subjectList</span>"
         dataProvider="<span class="quote">{model.subjects}</span>" labelField="<span class="quote">name</span>" 
         <span class="category2">width</span>="<span class="quote">100%</span>"
    /&gt;
    &lt;mx:TextInput id="<span class="quote">subjectName</span>" enter="<span class="quote">subjectSearch()</span>" /&gt;
    &lt;mx:HBox&gt;
         &lt;mx:<span class="category2">Button</span> id="<span class="quote">searchButton</span>" <span class="category1">label</span>="<span class="quote">Search Subjects</span>"
              click="<span class="quote">subjectSearch()</span>"
              <span class="category2">enabled</span>="<span class="quote">{subjectName.text != ''}</span>"
         /&gt;
         &lt;mx:<span class="category2">Button</span>
              id="<span class="quote">searchAllButton</span>"
              <span class="category1">label</span>="<span class="quote">Show all Subjects</span>"
              click="<span class="quote">showAll()</span>"
         /&gt;
         &lt;mx:<span class="category2">Button</span>
              id="<span class="quote">findBooksButton</span>"
              <span class="category1">label</span>="<span class="quote">Books on this Subject</span>"
              click="<span class="quote">findBooksBySubject()</span>"
              <span class="category2">enabled</span>="<span class="quote">{subjectList.selectedItem != null}</span>"
         /&gt;
    &lt;/mx:HBox&gt;
&lt;/search:SearchPanel&gt;</pre>
</code>

</div></div>

<p>There&#8217;s the list I mentioned, subjectList, which binds to the collection of subjects (if any) a command finds on the service. Then there&#8217;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&#8217;s a term in the search text input. searchAllButton will call the showAll method, and findBooksButton calls the &#8220;find books&#8221; method. I disable the Find button unless there is a selected item in the subject list.</p>

<p>Now let&#8217;s look up the chain to the SearchPanel:</p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
&lt;mx:Panel ...&gt;
    &lt;mx:Metadata&gt;
         [Event(<span class="category2">name</span>="<span class="quote">bookSearch</span>",
              <span class="category2">type</span>="<span class="quote">lcds.examples.bookie.event.SearchEvent</span>")]
    &lt;/mx:Metadata&gt;

    &lt;mx:Script&gt;
         &lt;![CDATA[
              [Bindable]
              protected <span class="category1">var</span> model:BookieModel =
                   BookieModel.getInstance();

              protected <span class="category1">function</span> findBooks(searchType:<span class="category2">String</span>, 
                                        searchData:<span class="category2">Object</span>):<span class="category1">void</span> {
                    <span class="category1">var</span> event:SearchEvent = <span class="category1">new</span> SearchEvent();
                    event.searchType      = searchType;
                    event.searchData      = searchData;
                    dispatchEvent(event);
               }
...</pre>
</code>

</div></div>

<p>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&#8217;ll be emitting this type of event.</p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
...
<span class="category1">private</span> <span class="category1">function</span> searchBooks(searchEvent:SearchEvent):<span class="category1">void</span> {
     <span class="category1">new</span> FindBooksEvent(searchEvent).dispatch();
}
...
&lt;search:TitleSearch
    id="<span class="quote">titleSearch</span>"
    <span class="category1">label</span>="<span class="quote">Search by Title</span>"
    bookSearch="<span class="quote">searchBooks(event)</span>"
/&gt;
&lt;search:AuthorSearch
    id="<span class="quote">authorSearch</span>"
    <span class="category1">label</span>="<span class="quote">Search by Author</span>"
    bookSearch="<span class="quote">searchBooks(event)</span>"
/&gt;
&lt;search:SubjectSearch
    id="<span class="quote">subjectSearch</span>"
    <span class="category1">label</span>="<span class="quote">Search by Subject</span>"
    bookSearch="<span class="quote">searchBooks(event)</span>"
/&gt;
... </pre>
</code>

</div></div>

<p>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:</p>

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;">
<code language="perl">
<pre>
package lcds.examples.bookie.command {
 ...
     <span class="category1">public</span> <span class="category1">class</span> FindBooksCommand <span class="category1">implements</span> ICommand, IResponder {
  
           <span class="category1">public</span> <span class="category1">function</span> execute(event:CairngormEvent):<span class="category1">void</span> {
                 <span class="category1">var</span> evt:FindBooksEvent = event as FindBooksEvent;
                 <span class="category1">var</span> searchData:SearchEvent = evt.searchEvent;
                 <span class="category1">var</span> delegate:BookieDelegate = 
                      <span class="category1">new</span> BookieDelegate(<span class="category1">this</span>);
   
                 <span class="category1">switch</span>(searchData.searchType) {
                       <span class="category1">case</span> SearchEvent.AUTHOR_SEARCH_TYPE :
                            delegate.findBooksByAuthor(
                                 Person(searchData.searchData));
                       <span class="category1">break</span>;
                       <span class="category1">case</span> SearchEvent.TITLE_SEARCH_TYPE :
                            delegate.findBooksByTitle(
                                 <span class="category2">String</span>(searchData.searchData));
                       <span class="category1">break</span>;
                       <span class="category1">case</span> SearchEvent.SUBJECT_SEARCH_TYPE :
                            delegate.findBooksBySubject(
                                 Subject(searchData.searchData));
                       <span class="category1">break</span>;
                  }
            }
  
           <span class="category1">public</span> <span class="category1">function</span> result(event:<span class="category2">Object</span>):<span class="category1">void</span> {
                 BookieModel.getInstance().books = event.result;
            }
  ...</pre>
</code>

</div></div>

<div class="ap_r" style="width:180px;"><a href="http://www.oreilly.com/catalog/9780596514402/?CMP=ILC-dm_nav_related-books" target="_blank"><img border="0" src="http://www.oreilly.com/catalog/covers/9780596514402_cat.gif" width="180" height="233" /></a>
<div class="apcaption"><a href="http://www.oreilly.com/catalog/9780596514402/?CMP=ILC-dm_nav_related-books" target="_blank">Get your copy of Tony Hillerson's Enterprise Application Development with Flex.</a></div></div>

<p>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&#8217;ll notice that the main DataGrid&#8217;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.</p>

<p>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<br />BooksPanel.</p>

<p>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 <a href="http://www.insideria.com/series-anatomy-flex.html">here</a>.</p>
]]>
      
    </content>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23811-comment:2017402</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23811" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-12.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-12.html#comment-2017402" />
    <title>Comment from Flexi on 2008-05-28</title>
    <author>
        <name>Flexi</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Hi Tony,<br />
First of all, I wish to say that these are the greatest articles I've came across in a long time. seriously, great work.<br />
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.<br />
am I missing something?<br />
Many thanks and keep up the good work!</p>]]>
    </content>
    <published>2008-05-28T07:13:59Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.23811-comment:2017407</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.23811" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-12.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/05/anatomy-of-an-enterprise-flex-12.html#comment-2017407" />
    <title>Comment from Tony Hillerson on 2008-05-28</title>
    <author>
        <name>Tony Hillerson</name>
        <uri>http://thillerson.blogspot.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://thillerson.blogspot.com">
        <![CDATA[<p>@Flexi (nice name) you should be able to see all the articles from the beginning here on this site.</p>]]>
    </content>
    <published>2008-05-28T15:22:34Z</published>
  </entry>

</feed
