Adobe Flex – Presentation & Cookbook

Here is a little thing that I made up for people using Flex/Flash and amfphp a little cheat sheet to use as a reference.

I have two different versions of this:

  1. Is use without any framework and without a services-config.xml file in the compiler.
  2. Second version is for use with the Cairngorm Framework.

These example are snippets from my Flash Remoting presentation and Snippr Air application. Source files will be provided at the end.

Table Of Contents:

  1. Installation Setup
  2. Service Proxy for managing calls
  3. Value Objects
  4. Model Locator
  5. Getting Data
  6. Sending Data
  7. Removing Data
  8. Views
  9. Source

 

Amfphp Installation Setup

Server folder structure:

amfphp_root

Snippets MySQL Table:

 

   1: CREATE TABLE `snippets` (                                 
   2:            `snippet_id` int(11) NOT NULL auto_increment,           
   3:            `snippet_title` varchar(255) NOT NULL,                  
   4:            `snippet_code` text NOT NULL,                           
   5:            `snippet_type` varchar(3) default 'as',                 
   6:            `snippet_created` timestamp NULL default NULL,          
   7:            `snippet_user` varchar(200) NOT NULL,                   
   8:            PRIMARY KEY  (`snippet_id`)                             
   9:          ) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1  

 

Service Proxy

Here is how you create a Service Proxy file that handles all of your calls, this makes all calls to and from amfphp really easy.

Use in SnipprService.as

   1: package com.jonniespratley.snippr.services
   2: {
   3:     import com.jonniespratley.snippr.model.ModelLocator;
   4:     import com.jonniespratley.snippr.vo.SnippetVO;
   5:     
   6:     import flash.net.NetConnection;
   7:     import flash.net.Responder;
   8:     
   9:     import mx.collections.ArrayCollection;
  10:     import mx.controls.Alert;
  11:     
  12:     /**
  13:      * This file is for use without! using the services-config.xml file 
  14:      * @author Jonnie
  15:      * 
  16:      */    
  17:     public class SnipprService
  18:     {
  19:         private static var _service:NetConnection;
  20:         private var model:ModelLocator = ModelLocator.getInstance();
  21:         
  22:         //Here we are creating a new connection to our amfphp service, when this is instantiated, it connects to our service
  23:         public function SnipprService()
  24:         {
  25:             _service = new NetConnection();
  26:             _service.connect( "http://YOURSERVER.COM/amfphp/gateway.php" );
  27:         }        
  28:         
  29:         
  30:         /* ***************************************
  31:         *** Service Calls
  32:         *****************************************/
  33:         
  34:         //Here we are calling the getSnippets on our server (amfphp) and setting the result and fault handlers
  35:         public function getSnippets():void
  36:         {
  37:             _service.call( "snippr.SnipprService.getSnippets", new Responder( snippetResultHandler, snipprFaultHandler ) );
  38:         }
  39:         
  40:         //We take one argument here, and that is a snippet, because our server (amfphp) is expecting a snippetVO
  41:         public function saveSnippet( snippet:SnippetVO ):void
  42:         {
  43:             _service.call( "snippr.SnipprService.saveSnippet", new Responder( snippetSavedHandler, snipprFaultHandler ), snippet );
  44:         }
  45:         
  46:         //We take one argument here, and that is the id of the snippet we are wanting to remove
  47:         public function removeSnippet( snippet_id:uint ):void
  48:         {
  49:             _service.call( "snippr.SnipprService.removeSnippet", new Responder( snippetRemoveHandler, snipprFaultHandler ), snippet_id );
  50:         }
  51:         
  52:         
  53:         /* ***************************************
  54:         *** Result and Fault Handlers
  55:         *****************************************/
  56:         
  57:         //Here we are handling the result coming back as an array of snippets, then we add our snippets to our model        
  58:         private function snippetResultHandler( data:Array ):void
  59:         {            
  60:             model.snippetCollection = initVO( data );
  61:         }
  62:         
  63:         //Helper for the result
  64:         private function initVO( resultArray:Array ):ArrayCollection
  65:         {
  66:             var tempArray:ArrayCollection = new ArrayCollection();
  67:             
  68:             for ( var s:String in resultArray )
  69:             {
  70:                 tempArray.addItem( new SnippetVO( resultArray[s] ) );
  71:                 
  72:             }
  73:             return tempArray;
  74:         }
  75:         
  76:         //Here we are handling the result and adding it to the value of serviceResponse in our model
  77:         private function snippetSavedHandler( data:Object ):void
  78:         {
  79:             ModelLocator.getInstance().serviceResponse = data.toString();
  80:         }
  81:         
  82:         /*
  83:         Here we are handling the result that is being returned, which will be the id of the removed snippet, and 
  84:         removing it from our model, at the snippet index
  85:         */
  86:         private function snippetRemoveHandler( data:Object ):void
  87:         {
  88:             getSnippets();
  89:         }
  90:         
  91:         //Here we are alerting the user that there was an error connection to our server
  92:         private function snipprFaultHandler( fault:Object ):void
  93:         {
  94:  
  95:             Alert.show( "There was an error connecting to the server.", "Snippr Service Error" );
  96:         }        
  97:     }        
  98: }

 

Use in SnipprService.php:

   1: <?php
   2: /** *******************************************************************
   3:  * Copyright (c) 2008 Jonnie Spratley. All Rights Reserved.
   4:  *
   5:  * THE SOFTWARE IS PROVIDED "AS" IS, WITHOUT WARRANTY OF ANY KIND,
   6:  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   7:  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   8:  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
   9:  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  10:  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  11:  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  12:  *
  13:  * @author  Jonnie Spratley
  14:  * @contact jonniespratley@gmail.com
  15:  * @internal
  16:  ******************************************************************* */
  17:  
  18: class SnipprService
  19: {
  20:     //Specify our output temp directory
  21:     var $output_dir = "screenshots";
  22:     //Specify our output url 
  23:     var $server_url = "http://snippr.jonniespratley.com/";
  24:     //Specify our table name
  25:     private $table = "snippets";
  26:         
  27:     public function SnipprService()
  28:     {
  29:         mysql_connect("localhost", "spratley_guest", "guest");
  30:         mysql_select_db("spratley_snippr") ;    
  31:     }
  32:  
  33:  
  34:     private function mapRecordSet( $recordset )
  35:     {
  36:         require_once( "../vo/SnippetVO.php" );
  37:         $list = array();
  38:         
  39:         while( $data = mysql_fetch_array( $recordset ) )
  40:         {
  41:             $vo = new SnippetVO();
  42:             $vo->mapObject( $data );
  43:             array_push( $list, $vo );
  44:         }        
  45:         return $list;    
  46:     }    
  47:  
  48:  
  49:     public function getSnippets()
  50:     {
  51:         //We must specify our vo, because we need to map correctly
  52:         require_once( "../vo/SnippetVO.php" );
  53:         
  54:         $sql = mysql_query( "SELECT * FROM ". $this->table. "" );
  55:         
  56:         $result = array();
  57:  
  58:         while( $snip = mysql_fetch_array( $sql ) )
  59:         {
  60:             //Create a new snippet vo
  61:             $snippet = new SnippetVO();
  62:             $snippet->snippet_id             = $snip[snippet_id];
  63:             $snippet->snippet_title         = $snip[snippet_title];
  64:             $snippet->snippet_code             = $snip[snippet_code];
  65:             $snippet->snippet_type             = $snip[snippet_type];
  66:             $snippet->snippet_created         = $snip[snippet_created];
  67:             $snippet->snippet_user             = $snip[snippet_user];
  68:             //Result is a snippet
  69:             $result[] = $snippet;
  70:         }
  71:         //Print out the result
  72:         return $result;
  73:     }
  74:  
  75:     //This is used for returning the created or updated snippet for flex
  76:     public function getOne( $id )
  77:     {
  78:         $rs = mysql_query( "SELECT * FROM ".$this->table." WHERE snippet_id = ".$id );
  79:         //Map the recordset to our vo
  80:         $list = $this->mapRecordSet( $rs );
  81:         //Return our vo
  82:         return $list[ 0 ];        
  83:     }
  84:     
  85:     //Creates a new snippet
  86:     public function saveSnippet( $snippet )
  87:     {
  88:         require_once( "../vo/SnippetVO.php" );
  89:         //Check to see if the snippet has an id of 0
  90:         if ( $snippet[snippet_id] == 0 ) 
  91:         {
  92:         $query = "INSERT INTO ".$this->table."
  93:                                 ( snippet_title,
  94:                                 snippet_code,
  95:                                 snippet_type,
  96:                                 snippet_created,
  97:                                 snippet_user )        
  98:                                 VALUES (
  99:                                 '".mysql_real_escape_string($snippet[snippet_title])."',
 100:                                 '".mysql_real_escape_string($snippet[snippet_code])."',
 101:                                 '".mysql_real_escape_string($snippet[snippet_type])."',
 102:                                 '".mysql_real_escape_string($snippet[snippet_created])."',
 103:                                 '".mysql_real_escape_string($snippet[snippet_user])."')";
 104:         if( !mysql_query( $query ) ) 
 105:         {        
 106:             return false;
 107:         }                
 108:             return $this->getOne( mysql_insert_id() );
 109:             
 110:             } else {
 111:                     $id = $snippet[snippet_id];
 112:             
 113:                     $query = "UPDATE ".$this->table." SET 
 114:                     snippet_title = '".mysql_real_escape_string($snippet[snippet_title])."',
 115:                     snippet_code = '".mysql_real_escape_string($snippet[snippet_code])."',
 116:                     snippet_type = '".mysql_real_escape_string($snippet[snippet_type])."',
 117:                     snippet_created = '".mysql_real_escape_string($snippet[snippet_created])."',
 118:                     snippet_user = '".mysql_real_escape_string($snippet[snippet_user])."'
 119:             
 120:                     WHERE snippet_id =". $id;
 121:                 
 122:                     if( !mysql_query( $query ) )
 123:                     {        
 124:                         return false;        
 125:                     }                
 126:                     //Return the created snippet
 127:                     return $this->getOne( $id );                
 128:                 }                
 129:     }
 130:  
 131:     public function removeSnippet($id)
 132:     {
 133:         $sql = mysql_query( "DELETE FROM ".$this->table." WHERE snippet_id = ".$id );
 134:         
 135:         if( !$sql )
 136:         {
 137:         //    trigger_error("Unable to delete Snippets", E_USER_ERROR);
 138:             return "There was an error removing this snippet";
 139:         }
 140:         else return $id;        
 141:     }      
 142:       
 143:     /** *******************************************************************************
 144:     Save image from the given bytearray and return the path of the saved image
 145:     ***********************************************************************************/
 146:    public function takeScreenshot( $byteArray, $filename, $compressed = false )
 147:     {
 148:         if( !file_exists( $this->output_dir ) || !is_writeable( $this->output_dir ) )
 149:             trigger_error ( "Please create a directory first with write access", E_USER_ERROR );
 150:  
 151:         $data = $byteArray->data;
 152:  
 153:         if( $compressed )
 154:         {
 155:             if( function_exists( gzuncompress ) )
 156:             {
 157:                 $data = gzuncompress( $data );
 158:             } else {
 159:                 trigger_error ( "GZip method does not exists, please send uncompressed data", E_USER_ERROR );
 160:             }
 161:         }
 162:         //Put the File in the Directory, and Rename it, what the User wanted the Name to be.
 163:         file_put_contents( $this->output_dir . "/$filename", $data );
 164:        
 165:        return $this->server_url . $this->output_dir . "/$filename";
 166:     }
 167: }
 168: ?>

 

The Model Locator

Here is our ModelLocator.as file that will hold all of our data.

   1: /** *******************************************************************
   2:  * Snippr AIR
   3:  * Copyright (c) 2008 Jonnie Spratley. All Rights Reserved.
   4:  *
   5:  * THE SOFTWARE IS PROVIDED "AS" IS, WITHOUT WARRANTY OF ANY KIND,
   6:  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   7:  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   8:  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
   9:  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  10:  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  11:  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  12:  *
  13:  * @author  Jonnie Spratley
  14:  * @contact jonniespratley@gmail.com
  15:  * @internal
  16:  ******************************************************************* */
  17: package com.jonniespratley.snippr.model
  18: {
  19:     import com.adobe.cairngorm.model.IModelLocator;
  20:     import com.jonniespratley.snippr.vo.SnippetVO;
  21:     
  22:     import mx.collections.ArrayCollection;
  23:  
  24:     /**
  25:      * The Model Locator pattern is a singleton and was created purely 
  26:      * to be used with Flex/Air application development. In this case, 
  27:      * a singleton is a design pattern that allows for only one 
  28:       * instance of the Model Locator to be present within your a
  29:      * application's memory. Any data that you think is required to live 
  30:      * in the application's state should be stored inside the Model Locator. 
  31:      * The Model Locator creates a central area where all the states 
  32:      * can be held in your Flex/Air application. This allows the view 
  33:      * components to bind to the model or state of the application 
  34:      * and keep everything up to date.
  35:      *
  36:      */
  37:     
  38:     [Bindable]
  39:     public final class ModelLocator implements IModelLocator
  40:     {
  41:         /**
  42:          * Defines the Singleton instance of the Application ModelLocator
  43:          */
  44:         private static var instance:ModelLocator;
  45:  
  46:         public function ModelLocator()
  47:         {
  48:             if( instance != null ) throw new Error( "Error: Singletons can only be instantiated via getInstance() method!" );
  49:  
  50:             ModelLocator.instance = this;
  51:         }
  52:  
  53:         /**
  54:          * Returns the Singleton instance of the Application ModelLocator
  55:          */
  56:         public static function getInstance():ModelLocator
  57:         {
  58:             if( instance == null )    instance = new ModelLocator();
  59:  
  60:             return instance;
  61:         }
  62:  
  63:         // *********** Public Variables that our views are going to bind to ************** 
  64:         
  65:         /* Snippet Collection for all lists/datagrids */
  66:         public var snippetCollection:ArrayCollection;
  67:         
  68:         /* The selected snippet */
  69:         public var selectedSnippet:SnippetVO;
  70:                 
  71:         public var serviceResponse:String = "";
  72:  
  73:         // ***************** Public Static Variables for Work View States ************* 
  74:         public var workflowState:uint = 0;
  75:         public static const LOGIN_SCREEN:uint = 0;
  76:         public static const WELCOME_SCREEN:uint = 1;
  77:     }
  78: }

 

Value Objects

Code for both server and client are provided as follows.

Use in SnippetVO.as

   1: package com.jonniespratley.snippr.vo
   2: {    
   3:     [RemoteClass(alias="vo.SnippetVO")]
   4:     
   5:     /**
   6:      * VOs are used to create a layer of business objects that can be 
   7:      * transferred between tiers, instead of using records, results sets, and datasets.
   8:      */
   9:     [Bindable]
  10:     public class SnippetVO
  11:     {
  12:         public var snippet_id:int;
  13:         public var snippet_title:String;
  14:         public var snippet_code:String;
  15:         public var snippet_type:String;
  16:         public var snippet_created:String;
  17:         public var snippet_user:String;        
  18:         
  19:         /**
  20:          * Helper function for building the data. 
  21:          * @param source
  22:          */        
  23:         public function SnippetVO( source:Object = null )
  24:         {
  25:             if ( source != null )
  26:             {
  27:                 for ( var item:String in source )
  28:                 {
  29:                     try 
  30:                     {
  31:                         this[item] = source[item];
  32:                     }
  33:                     catch ( error:Error )
  34:                     {
  35:                         throw new Error( "SnippetVO: " + error );
  36:                     }
  37:                 }
  38:             }
  39:         }
  40:     }
  41: }

 

Use in SnippetVO.php

   1: <?php
   2: /** *******************************************************************
   3:  * @author  Jonnie Spratley
   4:  * @contact jonniespratley@gmail.com
   5:  * @internal
   6:  ******************************************************************* */
   7: class SnippetVO 
   8: {
   9:     //AMFPHP only
  10:     var $_explicitType="com.jonniespratley.snippr.vo.SnippetVO";
  11:     
  12:     public $snippet_id;
  13:     public $snippet_title;
  14:     public $snippet_code;
  15:     public $snippet_type;
  16:     public $snippet_created;
  17:     public $snippet_user;
  18:     
  19:     public function SnippetVO(){}
  20:     
  21:     //Maps the data to the specific table names
  22:     public function mapObject( $data )
  23:     {        
  24:         $this->snippet_id = $data[snippet_id];
  25:         $this->snippet_title = $data[snippet_title];
  26:         $this->snippet_code = $data[snippet_code];
  27:         $this->snippet_type = $data[snippet_type];
  28:         $this->snippet_created = $data[snippet_created];
  29:         $this->snippet_user = $data[snippet_user];
  30:     }
  31: }
  32: ?>

 

Getting Data

Code for both server and client are provided as follows.

Use in SnippetList.mxml
 
   1: //Here we are calling the getSnippets on our server (amfphp) and setting the result and fault handlers
   2: public function getSnippets():void
   3: {
   4:     var _service:NetConnection = new NetConnection();
   5:     _service.connect( "http://localhost/Snippr/amfphp/gateway.php" );
   6:     _service.call( "snippr.SnipprService.getSnippets", 
   7: new Responder( snippetResultHandler, snipprFaultHandler ) );
   8: }

 
Use in SnippetService.php
   1: public function getSnippets()
   2: {
   3:     //We must specify our vo, because we need to map correctly
   4:     require_once( "../vo/SnippetVO.php" );
   5:     
   6:     $sql = mysql_query( "SELECT * FROM ". $this->table. "" );
   7:  
   8:     $result = array();
   9:  
  10:     while( $snip = mysql_fetch_array( $sql ) )
  11:     {
  12:         //Create a new snippet vo
  13:         $snippet = new SnippetVO();
  14:         $snippet->snippet_id             = $snip[snippet_id];
  15:         $snippet->snippet_title         = $snip[snippet_title];
  16:         $snippet->snippet_code             = $snip[snippet_code];
  17:         $snippet->snippet_type             = $snip[snippet_type];
  18:         $snippet->snippet_created         = $snip[snippet_created];
  19:         $snippet->snippet_user             = $snip[snippet_user];
  20:         //Result is a snippet
  21:         $result[] = $snippet;
  22:     }
  23:     //Print out the result
  24:     return $result;
  25: }

 

To Save Data

Code for both server and client are provided as follows.

Use in SnippetForm.mxml

   1: /* 
   2: The saveSnippet function that gets called when there is no errors in our form
   3: This is one function that is going to handle both creating a new snippet, and
   4: updating an existing one. Our server side php script says that if the snippetVO[snippet_id]
   5: is equal to 0, then go ahead and insert it as a new snippet. But if the snippetVO[snippet_id]
   6: is not set to 0, then update that snippet where the recieved id is equal to the id we are updating.
   7: */
   8: private function saveSnippet():void
   9: {
  10:     /* If the selectedSnippet is empty create a new snippet */
  11:     if ( model.selectedSnippet == null ) 
  12:     {                    
  13:     var createS:SnippetVO = new SnippetVO();
  14:         createS.snippet_id = 0;
  15:         createS.snippet_title = txt_title.text;
  16:         createS.snippet_code = txt_code.text;
  17:         createS.snippet_user = txt_author.text;
  18:         createS.snippet_type = txt_type.text;
  19:     
  20:     /* Service proxy */
  21:     service.saveSnippet( createS );            
  22:     
  23:     } else {
  24:         /* Set the snippet id to the value of the selected snippet_id */                    
  25:         var updateS:SnippetVO = new SnippetVO();
  26:             updateS.snippet_id = model.selectedSnippet.snippet_id;
  27:             updateS.snippet_title = txt_title.text;
  28:             updateS.snippet_code = txt_code.text;
  29:             updateS.snippet_user = txt_author.text;
  30:             updateS.snippet_type = txt_type.text;
  31:         
  32:     service.saveSnippet( updateS );
  33:                             
  34:     }
  35:     /* Do nothing */
  36: }

Use in SnippetSerivce.php

   1: //Saves a snippet if the id == 0, otherwise it updates it
   2: public function saveSnippet( $snippet )
   3: {
   4:     require_once( "../vo/SnippetVO.php" );
   5:  
   6:     //Check to see if the snippet has an $snippet[snippet_id] == 0 from Flex
   7:     if ( $snippet[snippet_id] == 0 ) 
   8:     {
   9:     $query = "INSERT INTO ".$this->table."
  10:                             ( snippet_title,
  11:                             snippet_code,
  12:                             snippet_type,
  13:                             snippet_created,
  14:                             snippet_user )        
  15:                             VALUES (
  16:                             '".mysql_real_escape_string($snippet[snippet_title])."',
  17:                             '".mysql_real_escape_string($snippet[snippet_code])."',
  18:                             '".mysql_real_escape_string($snippet[snippet_type])."',
  19:                             '".mysql_real_escape_string($snippet[snippet_created])."',
  20:                             '".mysql_real_escape_string($snippet[snippet_user])."')";
  21:     if( !mysql_query( $query ) ) 
  22:     {    
  23:         //Return False 
  24:         return false;
  25:     }                
  26:     //Return the new snippet
  27:     return $this->getOne( mysql_insert_id() );            
  28:     } else {
  29:         $id = $snippet[snippet_id];
  30:         //Set up the query
  31:         $query = "UPDATE ".$this->table." SET 
  32:                 snippet_title = '".mysql_real_escape_string($snippet[snippet_title])."',
  33:                 snippet_code = '".mysql_real_escape_string($snippet[snippet_code])."',
  34:                 snippet_type = '".mysql_real_escape_string($snippet[snippet_type])."',
  35:                 snippet_created = '".mysql_real_escape_string($snippet[snippet_created])."',
  36:                 snippet_user = '".mysql_real_escape_string($snippet[snippet_user])."'                
  37:                 WHERE snippet_id =". $id;
  38:             //If there was a problem
  39:             if( !mysql_query( $query ) )
  40:             {    
  41:                 //Return false
  42:                 return false;        
  43:             }                
  44:                 //Return the created snippet
  45:                 return $this->getOne( $id );                
  46:             }                
  47: }

 

To Delete Data

Code for both server and client are provided as follows.

Use in SnippetList.mxml

   1: //Display an alert to confirm the delete
   2: private function removeSnippet():void
   3: {        
   4:     Alert.show( "Are you sure?", "Remove Snippet", 3, null, removeSnippetAlertHandler );                        
   5: }
   6:  
   7: //If they click yes in the alert then call the removeSnippet method passing the selected snippet as the id
   8: private function removeSnippetAlertHandler( event:CloseEvent ):void
   9: {
  10:     if ( event.detail == Alert.YES )
  11:     {
  12:         service.removeSnippet( lt_snippets.selectedItem.snippet_id );
  13:     }
  14: }

 

Use in SnippetService.php

   1: //Remove a snippet by the id
   2: public function removeSnippet($id)
   3: {
   4:     $sql = mysql_query( "DELETE FROM ".$this->table." WHERE snippet_id = ".$id );
   5:     
   6:     if( !$sql )
   7:     {
   8:     //    trigger_error("Unable to delete Snippets", E_USER_ERROR);
   9:         return "There was an error removing this snippet";
  10:     }
  11:     else return $id;        
  12: }      

 

Views

SnippetForm.mxml

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <!--SnippetFormProxyService-->
   3: <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" 
   4:     creationComplete="init()" 
   5:     xmlns:components="com.jonniespratley.snippr.view.components.*">
   6:     
   7:     <mx:Script>
   8:         <![CDATA[
   9:             import mx.validators.Validator;
  10:             import mx.controls.Alert;
  11:             import mx.rpc.events.FaultEvent;
  12:             import mx.rpc.events.ResultEvent;
  13:         
  14:             import com.jonniespratley.snippr.vo.SnippetVO;
  15:             import com.jonniespratley.snippr.model.ModelLocator;
  16:             import com.jonniespratley.snippr.services.SnipprService;        
  17:  
  18:             /* Out Model so we can bind to the selectedSnippet */
  19:             [Bindable] private var model:ModelLocator = ModelLocator.getInstance();
  20:             
  21:             /* Our validation array to hold the values of our validators */
  22:             [Bindable] private var validators:Array = new Array();            
  23:             
  24:             /* Our custom remote proxy service for connection to amfphp */
  25:             private var service:SnipprService;
  26:             
  27:             /* 
  28:             On init we create a new instance of our service proxy 
  29:             We alway set our validators to our validator array
  30:             */
  31:             private function init():void
  32:             {
  33:                 service = new SnipprService();
  34:                 
  35:                 validators = [ titleV, authorV, codeV, typeV ];
  36:             }
  37:             
  38:             /* 
  39:             When the save button is clicked instead of sending the data right away
  40:             we first check it to see if it is indeed valid. If our validation array 
  41:             is empty, then we can go ahead and send our value object to amfphp, other
  42:             wise we need to alert the user that there are some errors in the form
  43:             */
  44:             private function checkForm():void
  45:             {
  46:                 var vals:Array = new Array();
  47:                     vals = Validator.validateAll( validators );
  48:                 
  49:                 //If no errors
  50:                 if ( vals.length == 0 )
  51:                 {
  52:                     saveSnippet();
  53:                     //cleanForms();
  54:                 } else {
  55:                     Alert.show( "Please correct invalid form entries", "Validation Error" );
  56:                 }
  57:             }
  58:                         
  59:             /* Clears all form inputs, and resets the selected index of the snippet list */
  60:             private function cleanForms():void
  61:             {
  62:                 //Set the model.selectedSnippet to null, so we dont have any fields used up
  63:                 //model.selectedSnippet = null;    
  64:                 txt_title.text = "";
  65:                 txt_author.text = "";
  66:                 txt_code.text = "";
  67:                 txt_type.text = "";
  68:             }
  69:  
  70:             /* 
  71:             The saveSnippet function that gets called when there is no errors in our form
  72:             This is one function that is going to handle both creating a new snippet, and
  73:             updating an existing one. Our server side php script says that if the snippetVO[snippet_id]
  74:             is equal to 0, then go ahead and insert it as a new snippet. But if the snippetVO[snippet_id]
  75:             is not set to 0, then update that snippet where the recieved id is equal to the id we are updating.
  76:             */
  77:             private function saveSnippet():void
  78:             {
  79:                 /* If the selectedSnippet is empty create a new snippet */
  80:                 if ( model.selectedSnippet == null ) 
  81:                 {                    
  82:                 var createS:SnippetVO = new SnippetVO();
  83:                     createS.snippet_id = 0;
  84:                     createS.snippet_title = txt_title.text;
  85:                     createS.snippet_code = txt_code.text;
  86:                     createS.snippet_user = txt_author.text;
  87:                     createS.snippet_type = txt_type.text;
  88:                 
  89:                 /* Service proxy */
  90:                 service.saveSnippet( createS );            
  91:                 
  92:                 } else {
  93:                     /* Set the snippet id to the value of the selected snippet_id */                    
  94:                     var updateS:SnippetVO = new SnippetVO();
  95:                         updateS.snippet_id = model.selectedSnippet.snippet_id;
  96:                         updateS.snippet_title = txt_title.text;
  97:                         updateS.snippet_code = txt_code.text;
  98:                         updateS.snippet_user = txt_author.text;
  99:                         updateS.snippet_type = txt_type.text;
 100:                     
 101:                 service.saveSnippet( updateS );
 102:                                         
 103:                 }
 104:                 /* Do nothing */
 105:             }
 106:             
 107:             /* ******************* MXML Result and Fault handlers ********************* */
 108:             private function onResult( event:ResultEvent ):void
 109:             {
 110:                 Alert.show(event.result.toString(), "Success" );
 111:             }            
 112:             
 113:             private function onFault( event:FaultEvent ):void
 114:             {
 115:                 Alert.show( event.fault.faultString );
 116:             }
 117:                     
 118:         
 119:                             
 120:         ]]>
 121:     </mx:Script>
 122:     
 123:     <!--MXML Remote Object-->
 124:         
 125:     <!--Remote Object-->
 126:     <mx:RemoteObject id="snipprSvc"    source="snippr.SnipprService" 
 127:         destination="amfphp" 
 128:         showBusyCursor="true" 
 129:         fault="onFault( event )">
 130:             <!--Methods that are on our server-->        
 131:             <mx:method name="saveSnippet" result="onResult( event )"/>
 132:             <mx:method name="getSnippets" result="onResult( event )"/>
 133:     </mx:RemoteObject>    
 134:     
 135:     <mx:ApplicationControlBar width="100%" styleName="formBar">
 136:         <mx:HBox width="100%" verticalAlign="middle">            
 137:             <mx:Label text="Author:" fontWeight="bold"/>
 138:             <mx:TextInput id="txt_author"
 139:                 text="{ model.selectedSnippet.snippet_user }" 
 140:                 width="100%"/>            
 141:         </mx:HBox>                
 142:     </mx:ApplicationControlBar>
 143:     
 144:     <mx:ApplicationControlBar width="100%" styleName="formBar">        
 145:         <mx:HBox width="100%" verticalAlign="middle">
 146:                 
 147:                 <mx:Label text="Title:" fontWeight="bold"/>
 148:                 <mx:TextInput id="txt_title"
 149:                     text="{ model.selectedSnippet.snippet_title }"
 150:                      width="100%"/>    
 151:                          
 152:                 <mx:Label text="Type:" fontWeight="bold"/>
 153:                 <mx:TextInput id="txt_type"
 154:                     text="{ model.selectedSnippet.snippet_type }" 
 155:                     width="100%"/>
 156:         
 157:             <mx:Button id="btn_clear"
 158:                 click="cleanForms()"
 159:                  label="Clear"/>
 160:             <mx:Button id="btn_save"
 161:                 click="checkForm()" 
 162:                  label="Save"/>
 163:         </mx:HBox>
 164:     </mx:ApplicationControlBar>
 165:             <mx:VBox width="100%" height="100%" label="Edit">                
 166:                 <mx:TextArea id="txt_code"
 167:                     text="{ model.selectedSnippet.snippet_code }"
 168:                     width="100%" 
 169:                     height="100%" 
 170:                      styleName="codeView"/>                
 171:             </mx:VBox>    
 172:     
 173:     <!-- Validators -->
 174:     <mx:StringValidator id="titleV"
 175:         source="{ txt_title }"
 176:         minLength="1"
 177:         maxLength="200"
 178:         required="true"
 179:         property="text"/>
 180:     <mx:StringValidator id="authorV"
 181:         source="{ txt_author }"
 182:         minLength="1"
 183:         maxLength="200"
 184:         required="true"
 185:         property="text"/>
 186:     <mx:StringValidator id="codeV"
 187:         source="{ txt_code }"
 188:         minLength="5"
 189:         required="true"
 190:         property="text"/>
 191:     <mx:StringValidator id="typeV"
 192:         source="{ txt_type }"
 193:         minLength="1"
 194:         maxLength="200"
 195:         required="true"
 196:         property="text"/>        
 197: </mx:VBox>

SnippetList.mxml

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <!--SnippetList-->
   3: <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="200" height="100%" creationComplete="init()">
   4:  
   5:     <mx:Script>
   6:         <![CDATA[
   7:             import mx.controls.Alert;
   8:             import mx.events.CloseEvent;
   9:             import com.jonniespratley.snippr.services.SnipprService;
  10:             import com.jonniespratley.snippr.vo.SnippetVO;
  11:             import com.jonniespratley.snippr.events.SnippetGetEvent;
  12:             import com.jonniespratley.snippr.model.ModelLocator;            
  13:             
  14:             //Make a instance of our model for our data display
  15:             [Bindable] private var model:ModelLocator = ModelLocator.getInstance();                
  16:             
  17:             //Make a variable to check weither there is a selected snippet or not
  18:             [Bindable] private var isSelected:Boolean = false;
  19:             
  20:             //Make variable of our service
  21:             private var service:SnipprService; 
  22:         
  23:             
  24:             private function init():void
  25:             {
  26:                 service = new SnipprService();
  27:                 getSnippets();
  28:             }
  29:             
  30:             //Send a call to get the snippets
  31:             private function getSnippets():void
  32:             {            
  33:                 service.getSnippets();    
  34:             }
  35:             
  36:             private function removeSnippet():void
  37:             {        
  38:                 Alert.show( "Are you sure?", "Remove Snippet", 3, null, removeSnippetAlertHandler );                        
  39:             }
  40:             
  41:             private function removeSnippetAlertHandler( event:CloseEvent ):void
  42:             {
  43:                 if ( event.detail == Alert.YES )
  44:                 {
  45:                     service.removeSnippet( lt_snippets.selectedItem.snippet_id );
  46:                 }
  47:             }
  48:             
  49:             //Make sure we handle the selected snippet and bind it to our model
  50:             private function selectHandler( event:Event ):void
  51:             {
  52:                 isSelected = true;
  53:                 model.selectedSnippet = event.target.selectedItem as SnippetVO;
  54:             }
  55:             
  56:         ]]>
  57:     </mx:Script>
  58:     
  59:     <!--Helper for Data Binding-->
  60:     <mx:Binding destination="lt_snippets.selectedItem" source="model.selectedSnippet"/>        
  61:         
  62:         <!--List of Snippets-->
  63:         <mx:List id="lt_snippets"
  64:             dataProvider="{ model.snippetCollection }"
  65:             change="selectHandler( event )"
  66:             labelField="snippet_title" 
  67:             width="100%" 
  68:             height="100%"/>
  69:             
  70:         <!--Remove Button-->
  71:         <mx:Button label="Remove"
  72:             click="removeSnippet()"
  73:             enabled="{ isSelected }"
  74:             width="100%"/>
  75: </mx:VBox>

 MainView.mxml

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <!--MainView-->
   3: <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" 
   4:     xmlns:snippets="com.jonniespratley.snippr.view.components.*" 
   5:     xmlns:view="com.jonniespratley.snippr.view.*">
   6:  
   7:     <!--ApplicationControll Bar-->
   8:     <view:ApplicationBar id="applicationBar"/>
   9:         
  10:     <!--MainViewStack-->
  11:     <mx:ViewStack id="vs_main" width="100%" height="100%" paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10">    
  12:         <view:SnipprProxyView id="snippetsProxyView" label="Snippets Proxy"/>
  13:     </mx:ViewStack>
  14:             
  15:     <!--ViewToggle-->
  16:     <mx:ToggleButtonBar dataProvider="vs_main" width="100%"/>
  17:     
  18: </mx:VBox>

 

Ok, with that said, here is a list of files that goes with this

Related Posts

Adobe Flex -  Presentation & Cookbook Adobe Flex - FlexpatternAir

So when the original idea came into my head about mixing Textpattern and the Flex Fra... Read More

Adobe Flex -  Presentation & Cookbook Adobe Flex - Flex 3 & AIR Exam Guide (Vol 1)

I have constructed a Flex 3 & AIR ACE Exam Study Guide. There is maybe two mo... Read More

Adobe Flex - Presentation & Cookbook

Here is a little thing that I made up for people using Flex/Flash and amfphp a little... Read More

Adobe Flex -  Presentation & Cookbook Adobe Flex - Amfphp Tutorial

I put together this little walk through for the visual learners out there. We do the ... Read More

Adobe Flex -  Presentation & Cookbook CodeGen 1.7

This is a pretty big release, I found out that some of the classes didn't work in the... Read More

Recent Posts

Advanced Guide To Flex
I haven't had much time to complete that Advanced Guide To Flex project that I brough... Read More
PHP - RESTful Data Access Object
You may use this class as a REST type service or as a general class. Its great, CRUD ... Read More
Adobe Flex - Flash Clothing
Adobe Flex - Flash Clothing
Here is a fun little library (kinda) that I created because I wanted to learn how to ... Read More
Flex Application Architecture
Flex Application Architecture
As you may not know, but I selected to write a article for the great people over at F... Read More
Textpattern: My Flexible Plugin Attempt
Textpattern: My Flexible Plugin Attempt
My First plugin attempt, I wanted to make a power user editor for making quick edits... Read More

Leave Your Response

* Name, Email, Comment are Required

Popular Posts

Tags

Search