Setting dataprovider to Text control

There may be scenario where you will be getting collection of static or dynamic data that contains code/value pair and then you have code whose label needs to be displayed on the screen. Then in this case, generally you have to iterate the collection and find out the label for it and display the same on screen. Well, if it is for one screen, then its fine. Say you have many such screens, then you have to write one common class that does this iteration and identification of corresponding label and call the same for each component. Looks little dirty. Why dont you have the same logic in the Control itself and then set the dataprovider for that control and the job is done? - the same way as it works for ComboBox. If you look at below image, I passed "IN" as text to the Text control and it displayed "Indianapolis" on the screen because I set states array as dataprovider to Text control.


Dataprovider to Text control

Lets see how you can build this.

Step 1: As a first step, you need to create your custom Text control that contains dataProvider property. Also I added idField and labelField for more flexibility so that you can define what field in the object of Array/Arraycollection you can use as Id and Label of the control.



 public class CustomText extends Text {
	
   private var _idField : String;
   private var _labelField : String;	
   private var _dataProvider: Object;

   public function CustomText(idField:String="id",labelField:String="label") {
      super();
      this.idField = idField;
      this.labelField = labelField;
   }

   public function get idField():String {
      return _idField;
   }

   public function set idField(id:String):void {
      this._idField = id;
   }

   public function get labelField():String {
      return _labelField;
   }

   public function set labelField(label:String):void {
      this._labelField = label;
   }

   public function get dataProvider():Object {
      return _dataProvider;
   }

   public function set dataProvider(dp:Object):void {
      this._dataProvider = dp;
   }
	
 }


Step 2: After setting the dataProvider, you need to find the matching object for the given input text by iterating over the collection assigned to dataProvider and get the matching idField field with the input text. Once the match is found, set the label of the matched object as "text" of the Text control. Thats it. Job done. Now the Text control will show the label of the matching id field.



 public class CustomText extends Text {
	
   ...

   public function set dataProvider(dp:Object):void {
      this._dataProvider = dp;

      // set the text now once the dataprovider is set.
      setTextFromDataprovider();
   }

   private function setTextFromDataprovider():void {
      var value:Object = this.text;

      if (dataProvider != null) {

         //Iterate over the array/arraycollection of values and match 
         //the id with the text and replace text with the label
         for each (var dpObj:Object in this.dataProvider) {
            
            if (dpObj.hasOwnProperty(idField) && dpObj.hasOwnProperty(labelField)) {

               if (value == dpObj[idField] || 
                  (value != null && String(value) == dpObj[idField])) { 

                  text = dpObj[labelField];
                  return;
               }
            }
         }

      } else {
         text = !value ? null : String(value);
      }
   }
	
 }


Step 3: Final step - use the custom Text control and set the dataProvider of it with your Array or ArrayCollection. Small convenient piece of code...... Isn't it?



<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    backgroundColor="#FFFFFF" 
    initialize="init()">

    ... 

   <customText:CustomText id="customTextControl" idField="code" labelField="name" 
    dataProvider="{this.stateArray}"  text="IN"/>
</mx:Application>	




You can download the example source code here.

Download the example code.



blog comments powered by Disqus