3 Replies Latest reply on Jul 14, 2010 8:21 PM by Solydest

    Set focus to Text area of embedded NumericStepper control

    BRebey

      I have an application that requires that I use NumericStepper editing control as the ItemEditor of a DataGrid column.

       

      I have two problems that I can't overcome, one being the result of the solution to the other:

       

      1) I need to instantiate the NumericStepper at runtime, becuase I dont' know ahead of time what column(s) will require it.  More importantly, I need to specify some non-default attributes (styles, min, max, width, etc.).  I can't figure out how to specify these attributes other than in a .mxml file.  To handle this, I crreated a "wrapper component" that is an HBox with a NumericStepper inside of it, and I can specify my attributes on the NumericStepper tag.

       

      2) Now that I've done  #1  above, though, when I click on a DataGrid cell that uses that editing component, the editor comes up but the TextArea is NOT focused, which means the user has to click a second time if he wants to type a number.  This is very irritating, but I don't know how to manage the focus such that when my HBox-with-embedded-NumericStepper" control comes up, it's focused and its data selected, just like the "base" NumericStepper is.

       

      So...my questions are:

      1) Can I somehow assign property values to a standard NumericStepper at runtime, so that I can avoid using my HBox-embedded custom control?

      2) How can I manage focus so that when my HBox-based control comes up, the text area is selected and fucused?

       

      This sounds confusing, but I have a tiny program to demonstrate it.  The "QtyBad"   column uses my own HBos-based NumericStepper, and doesn't get proper focus when activated.  The "QtyGood" column demonstrated  the PROPER behavior, as exhibited by the native NumericStepper, but I can't  specify any additional/non-standard attributes on it.

       

      Here is the whole program - called 'DGNumStepperDemo' - right here:

       

      DGNumStepperDemo.mxml

       

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onInitialize()">
          <mx:Script source="DGNumStepperDemo.as"/>
          <mx:DataGrid id="dg1" editable="true" top="20" left="20" width="350" height="124">
          </mx:DataGrid>
      </mx:Application>

       

      DGNumStepperDemo.as


      // ActionScript file
      import mx.collections.ArrayCollection;
      import mx.controls.DataGrid;
      import mx.controls.dataGridClasses.DataGridColumn;
      //---------------------------------------------------------------------------------------- -------
      [bindable]
      private var gridData:ArrayCollection = new ArrayCollection([{Qty:0},{Qty:5},{Qty:10}]);

       

      private function onInitialize():void
      {
          var cols:Array=new Array();
          var dgc:DataGridColumn;

       

          dgc = new DataGridColumn("QtyBad");
              dgc.dataField="Qty";
              dgc.width = 75;
              dgc.itemEditor=new ClassFactory(EditorDGNumericStepper);
              dgc.editorDataField="value";
              cols.push(dgc);
             
          dgc = new DataGridColumn("QtyGood");
              dgc.dataField="Qty";
              dgc.width = 75;
              dgc.itemEditor=new ClassFactory(mx.controls.NumericStepper);
              dgc.editorDataField="value";
              cols.push(dgc);

       

          dg1.columns = cols;
          dg1.dataProvider = gridData;
      }

       

      EditorDGNumericStepper.mxml

       

      <?xml version="1.0" encoding="utf-8"?>
      <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" verticalAlign="middle" paddingRight="4" paddingLeft="4"  verticalScrollPolicy="off" horizontalScrollPolicy="off">
          <mx:Script>
          <![CDATA[
              public function get value() : Number {return itemQuantity.value;}
          ]]>
          </mx:Script>
          <mx:NumericStepper id="itemQuantity" value="{data.Qty}" minimum="0" maximum="100"/>
      </mx:HBox>

       

      If  anyone bothers to run this, you can see what I mean about the focus problem in the QtyGood and QtyBad columns.

       

      Any Help Is Appreciated!

        • 1. Re: Set focus to Text area of embedded NumericStepper control
          Solydest Level 2

          Quick answer to #2 is to change EditorDGNumericStepper.mxml to the following:

           

          <?xml version="1.0" encoding="utf-8"?>
          <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"
                     verticalAlign="middle" paddingRight="4" paddingLeft="4"
                     verticalScrollPolicy="off" horizontalScrollPolicy="off"
                     creationComplete="focusManager.setFocus(itemQuantity)">
               <mx:Script>
                    <![CDATA[
                         public function get value():Number
                         {
                              return itemQuantity.value; 
                         }
                    ]]>
               </mx:Script>
               <mx:NumericStepper id="itemQuantity" value="{data.Qty}" minimum="0" maximum="100" width="100%"/>
          </mx:HBox>
          

           

          The only thing I did was set the width of the NumericStepper to 100% so it fills the column just like the standard NumericStepper and it looks a little nicer and I added a creation complete event handler which sets the focus to the NumericStepper.  I tested it and it will set focus each time it is clicked just like a standard stepper.  There may be a more "preferred" way, but this is simple and effective.

           

          As for question #1, do you want to change properties, styles, etc. of a standard NumericStepper after it has been added to the datagrid?

          • 2. Re: Set focus to Text area of embedded NumericStepper control
            BRebey Level 1

            Thanks, Solvdest!  That SetFocus  bit did the trick perfectly, and thanks for the aesthetic tip with the 100% width and height - I agree: it looks nicer  that way.

             

            Regarding the "Issue #1", I don't really ever need to change the attributes of the NumericStepper after one has been instantiated in  the grid;   I just need to make sure that when one IS instantiated, it has the right attributes.  So, the concept would look something like this when I set up the column at right run time:

             

                (CAUTION to others: This code is WRONG;   Junk! 

                It's here to demonstate a concept that I don't know how to implement!

                Don't use it as an example!)


            var dgcQty:DataGridColumn = new DataGridColumn("Qty");
                   

                 dgcQty.itemEditor=new ClassFactory(mx.controls.NumericStepper);
               

                 /* Here's where it goes south.  It feels like I want to do something like this: ...  */

              dgcQty.itemEditor.min=0;          /* IMPOSSIBLE */

              dgcQty.itemEditor.max=100;        /* IMPOSSIBLE  */

              /* etc. */


            The above  is ridiculous, of course, becuase itemEditor isn't actually a NumericStepper, but rather an IFactory that makes NumericSteppers.

             

            What I'm trying to solve is the problem of assigning non-default attributes to teh NumericSteppers created by the itemEditor property at runtime.

             

            How is this done?

            • 3. Re: Set focus to Text area of embedded NumericStepper control
              Solydest Level 2

              OK, I think I see what you want to do.  I've changed up the code for your second column a bit for comparison.  Give this a shot:

               

              dgc = new DataGridColumn("QtyGood");
              dgc.dataField = "Qty";
              dgc.width = 75;
              var numStepperFactory:ClassFactory = new ClassFactory(EditorDGNumericStepper);
              numStepperFactory.properties = {minValue: 40, maxValue: 50};
              dgc.itemEditor = numStepperFactory;
              dgc.editorDataField = "value";
              cols.push(dgc);
              

               

              You need to create a variable of type ClassFactory and set it = to your new ClassFactory instance.  You can then set the "properties" property (which is of type Object) of the variable.  That is used by the ClassFactory when it creates a new instance of EditorDGNumericStepper to set its properties.  Here is the modified EditorDGNumericStepper code so it will make more sense:

               

              <?xml version="1.0" encoding="utf-8"?>
              <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"
                         verticalAlign="middle" paddingRight="4" paddingLeft="4"
                         verticalScrollPolicy="off" horizontalScrollPolicy="off"
                         creationComplete="focusManager.setFocus(itemQuantity)">
                   <mx:Script>
                        <![CDATA[
                             [Bindable]
                             public var maxValue:Number = 100; 
                             
                             [Bindable]
                             public var minValue:Number = 0;
                                            
                             public function get value():Number
                             {
                                  return itemQuantity.value; 
                             }
                        ]]>
                   </mx:Script>
                   <mx:NumericStepper id="itemQuantity" value="{data.Qty}" minimum="{minValue}" maximum="{maxValue}" width="100%"/>
              </mx:HBox>
              

               

              this class now has properties named maxValue and minValue that are set in this line above:

               

              numStepperFactory.properties = {minValue: 40, maxValue: 50};
              

               

              I made those properties bindable so that the properties of the NumericStepper could be bound to them.

               

              Hope that makes sense and gets you where you want to be.  If not just drop me a note.

               

              Cheers.