1 Reply Latest reply on Sep 21, 2012 3:12 AM by AndreasRuloffs

    validators and itemrenderers

    AndreasRuloffs Level 1

      Hi,

      I have a problem using ItemRenderer.

       

      I have a table implemented as DataGrid in which some cells are shown by a self written itemRenderer. Depending on the type of the cells data the cell will be also used by a validator. Executing the program everything looks fine, as long as the programs window is not too small. If you scroll in the table then really ugly things happen. The wrong cells get validated by wrong validators and I have even seen that a single cell is validated by several validators.

       

      I know that the ItemRenderer are recycled and I am pretty sure that this has dealing with the problem. But the validators should be activated and deactivated by databinding which should occure on every databinding. So I should work well? But why it doesn't?

       

      If I use a List, and set useVirtualLayout="false"then the problem occues no more (but it looks verry different).

       

      Thank you

       

      Andreas Ruloffs

       

       

      The main Application with the datagrid:

       

       

      ?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" 
       initialize="application1_initializeHandler(event)">
       <fx:Script>
       <![CDATA[
       import mx.collections.ArrayCollection;
       import mx.events.FlexEvent;
      
       private var data:ArrayCollection = new ArrayCollection();
      
       protected function application1_initializeHandler(event:FlexEvent):void
       {
       data.addItem(new MonoAttributeData("Text1", "Halloo", "String", true, true, 5 ));
       data.addItem(new MonoAttributeData("Dbl1", "1", "Double", false, true));
       data.addItem(new MonoAttributeData("Int1", "2", "Integer", false, true));
       data.addItem(new MonoAttributeData("Text2", "Welt", "String", true, true, 5 ));
       data.addItem(new MonoAttributeData("Dbl2", "", "Double", false, true));
       data.addItem(new MonoAttributeData("Int2", "54", "Integer", true, true));
       data.addItem(new MonoAttributeData("Text3", "Fix", "String", true, true, 5 ));
       data.addItem(new MonoAttributeData("Dbl3", "", "Double", false, true));
       data.addItem(new MonoAttributeData("Int3", "54", "Integer", true, true));
       dataGrid.dataProvider = data;
      
       }
       ]]>
       </fx:Script>
      
       <mx:AdvancedDataGrid id="dataGrid"
       verticalScrollPolicy="on"
       horizontalScrollPolicy="off"
       alternatingItemColors="[#969696,#787878]" 
       headerColors="[#969696,#787878]"
       width="100%"
       height="100%"
       sortableColumns="false" 
       sortItemRenderer="{null}">
       <mx:columns>
       <mx:AdvancedDataGridColumn dataField="fieldname" headerText="Name" />
       <mx:AdvancedDataGridColumn dataField="value"    headerText="Value"/>
       </mx:columns> 
       <mx:rendererProviders> 
       <mx:AdvancedDataGridRendererProvider 
       dataField="value" 
       renderer="MonoLangValueItemRenderer" 
       columnIndex="1"/>
       </mx:rendererProviders>
       </mx:AdvancedDataGrid>
      </s:Application>
      


      The data model for the ItemRenderer:

       

       

      package 
      {
       import mx.collections.ArrayCollection;
       import mx.collections.ArrayList;
      
       public class MonoAttributeData 
       {
       private var _value:String;
       private var _changeable:Boolean;
       private var _changed:Boolean;
       private var _valid: Boolean = true;
       private var _validationMessage: String; 
       private var _fieldType:String;                    //Double, Integer oder String
       private var _fieldLength:int;
       private var _fieldAllowNull:Boolean
       private var _fieldname:String;
      
       public function MonoAttributeData(fieldname:String, value:String, fieldType:String, fieldAllowNull:Boolean, changeable:Boolean, fieldLength:int = 0)
       {
       _value = value;
       _changeable = changeable;
       _changed = false;
       _valid = true;
       _validationMessage = "";
       _fieldType = fieldType;
       _fieldLength = fieldLength;
       _fieldAllowNull = fieldAllowNull;
       _fieldname = fieldname;
       }
      
       public function get fieldname():String
       {
       return _fieldname;
       }
      
       public function set fieldname(value:String):void
       {
       _fieldname = value;
       }
      
       public function get validationMessage():String
       {
       return _validationMessage;
       }
      
       public function set validationMessage(value:String):void
       {
       _validationMessage = value;
       }
      
       public function get valid():Boolean
       {
       return _valid;
       }
      
       public function set valid(value:Boolean):void
       {
       _valid = value;
       }
      
       [Bindable]
       public function get changeable():Boolean
       {
       return _changeable;
       }
      
       public function set changeable(value:Boolean):void
       {
       _changeable = value;
       }
      
       [Bindable]
       public function get changed():Boolean
       {
       return _changed;
       }
      
       public function set changed(value:Boolean):void
       {
       _changed = value;
       }
      
       [Bindable]
       public function get value():String
       {
       return _value;
       }
      
       public function set value(value:String):void
       {
       _value = value;
       }
      
       [Bindable]
       public function get fieldType():String
       {
       return _fieldType;
       }
      
       public function set fieldType(value:String):void
       {
       _fieldType = value;
       }
      
       [Bindable]
       public function get fieldLength():int
       {
       return _fieldLength;
       }
      
       public function set fieldLength(value:int):void
       {
       _fieldLength = value;
       }
      
       [Bindable]
       public function get fieldAllowNull():Boolean
       {
       return _fieldAllowNull;
       }
      
       public function set fieldAllowNull(value:Boolean):void
       {
       _fieldAllowNull = value;
       }
       }
      }
      

       

      and the ItemRenderer:

       

      <?xml version="1.0" encoding="utf-8"?>
      <s:MXAdvancedDataGridItemRenderer 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:Declarations> 
       <!-- value Commit keine Auswirkung
       dataChange von Anfang an
       Platzieren Sie nichtvisuelle Elemente (z.*B. Dienste, Wertobjekte) hier -->
      
       <mx:NumberValidator id="validatorDouble"  source="{textInput}" 
       property="text" 
       valid="validatorDouble_validHandler(event)"
       invalid="validatorDouble_invalidHandler(event)"
       required="{!MonoAttributeData(data).fieldAllowNull}"
       domain="real"
       enabled="{ MonoAttributeData(data).fieldType == 'Double'}"/>
       <mx:NumberValidator id="validatorInt" source="{textInput}" 
       property="text" 
       required="{!MonoAttributeData(data).fieldAllowNull}"
       valid="numbervalidatorInt_validHandler(event)"
       invalid="numbervalidatorInt_invalidHandler(event)"
       domain="int" 
       enabled="{ ( MonoAttributeData(data).fieldType == 'Integer')}"/>
      
       <mx:StringValidator id="validatorStr" source="{textInput}"
       property="text"
       valid="validatorStr_validHandler(event)"
       invalid="validatorStr_invalidHandler(event)"
       required="{!MonoAttributeData(data).fieldAllowNull}"
       minLength="NaN"
       maxLength="{MonoAttributeData(data).fieldLength}"
       enabled="{MonoAttributeData(data).fieldType == 'String'}"/>
      
       </fx:Declarations>
       <fx:Script>
       <![CDATA[
       import mx.collections.ArrayList;
       import mx.core.UIComponent;
       import mx.events.ValidationResultEvent;
      
       private function dataChanged():void
       { 
       if(data.value != textInput.text)
       {
       var newValue:String = textInput.text;
       MonoAttributeData(data).changed = true; 
       MonoAttributeData(data).value = newValue;
       }
       }
      
       protected function validatorDouble_validHandler(event:ValidationResultEvent):void
       {
       data.valid = true;
       MonoAttributeData(data).validationMessage = "";
       }
      
       protected function validatorDouble_invalidHandler(event:ValidationResultEvent):void
       {
       data.valid = false;
       MonoAttributeData(data).validationMessage =  MonoAttributeData(data).fieldname + ": " + event.message + "\n";
       }
      
       protected function numbervalidatorInt_validHandler(event:ValidationResultEvent):void
       {
       data.valid = true;
       MonoAttributeData(data).validationMessage = "";
       }
      
       protected function numbervalidatorInt_invalidHandler(event:ValidationResultEvent):void
       {
       data.valid = false;
       MonoAttributeData(data).validationMessage =  MonoAttributeData(data).fieldname + ": " + event.message + "\n";
       }
      
       protected function validatorStr_validHandler(event:ValidationResultEvent):void
       {
       data.valid = true;
       MonoAttributeData(data).validationMessage = "";
       }
      
       protected function validatorStr_invalidHandler(event:ValidationResultEvent):void
       {
       data.valid = false;
       MonoAttributeData(data).validationMessage =  MonoAttributeData(data).fieldname + ": " + event.message + "\n";
       }
       ]]>
       </fx:Script>
       <s:Group width="100%" height="100%">
       <s:TextInput  id="textInput"
       change="dataChanged()"
       color="{data.changed?0x666666:0x000000}"
       enabled="{data.changeable}" 
       text="{data.value}"
       textAlign="center"
       width="100%" height="100%"/>
       </s:Group>
      </s:MXAdvancedDataGridItemRenderer>
      
        • 1. Re: validators and itemrenderers
          AndreasRuloffs Level 1

          Hello,

          I have solved the problem myself.

          The problem was not the validators. As I proposed were they activated and deactivated correctly by databinding on each recycling.

          But the textfield in the itemrenderer got a property called ‘errorText’ which was not reseted on recycling. This caused my problem. This little enhancement finally solved my problem:

           

          private function resetValidation():void
          {
               textInput.errorString = "";
               textInput.toolTip = "";
               validatorDouble.validate();
               validatorInt.validate();
               validatorStr.validate();
          }
                         
          override public function set data(value:Object):void
          {
               super.data = value;
               resetValidation();
          }
          
          

           

          Best regards,

          Andreas Ruloffs