20 Replies Latest reply: Feb 15, 2011 4:53 PM by Justin Daily RSS

    DataGrid Data Entry - Make Enter Behave Like Tab

    F.Bowman

      I have a DataGrid with some editable rows and some uneditable rows. What I need is for data entry to happen across the editable columns before advancing down a row. Just like how the DataGrid behaves when the Tab button is used.

       

      Basically, I want the Enter key to behave just like the Tab key.

       

      How do I go about achieving this?

        • 1. Re: DataGrid Data Entry - Make Enter Behave Like Tab
          Flex harUI Adobe Employee

          Add a high priority listener for KEY_DOWN.  Call stopImmediatePropagation.

          Display a FocusEvent.KEY_FOCUS_CHANGE event instead.

          • 2. Re: DataGrid Data Entry - Make Enter Behave Like Tab
            F.Bowman Community Member

            Thanks for the response. I tried it out but it didn't work. Here is the code that I used. Maybe I did something incorrectly.

             

             

            Monthly.addEventListener(KeyboardEvent.KEY_DOWN, keyCapture, false, -100);
            
            private function keyCapture(event:KeyboardEvent):void
            {
                 if(event.keyCode == 13)
                 {
                      event.stopImmediatePropagation();
                      Monthly.dispatchEvent(new FocusEvent(FocusEvent.KEY_FOCUS_CHANGE));
                 }
            }
            

            • 3. Re: DataGrid Data Entry - Make Enter Behave Like Tab
              F.Bowman Community Member

              I changed

              Monthly.addEventListener(KeyboardEvent.KEY_DOWN, keyCapture, false, -100);
              
              

               

              to

              Monthly.addEventListener(KeyboardEvent.KEY_DOWN, keyCapture, true, -100);
              
              

               

              and it prevents the ENTER key from going through but I don't think the KEY_FOCUS_CHANGE is being broadcast properly.

              • 4. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                Flex harUI Adobe Employee

                Set a breakpoint on keyFocusChangeHandler and see what is in the event and

                mimic it.  You may need to dispatch from itemEditorInstance

                • 5. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                  F.Bowman Community Member

                  This is a little confusing.

                   

                  Is there a place to find the code of the way the Tab key in a DataGrid behaves?

                   

                  I've been trying but so far, I can't get this to work.

                  • 6. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                    Flex harUI Adobe Employee

                    Open DataGrid.as, put a breakpoint on keyFocusChangeHandler, run the app,

                    hit Tab, you can examine the event.  You want to dispatch a similar event.

                    • 7. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                      F.Bowman Community Member

                      Ok. I'll try that and see if it works.

                       

                      Which one do I dispatch the event from? The DataGrid or the ItemEditorInstance?

                       

                      Also, do I add the event to the DataGrid as:-

                       

                      Monthly.addEventListener(KeyboardEvent.KEY_DOWN, keyCapture, true, -100);

                      Monthly.addEventListener(KeyboardEvent.KEY_DOWN, keyCapture, false, -101);

                       

                      Or

                       

                      Monthly.addEventListener(KeyboardEvent.KEY_DOWN, keyCapture, false, -101);

                       

                      Or

                       

                      Monthly.addEventListener(KeyboardEvent.KEY_DOWN, keyCapture, true, -100);

                       

                      ??

                      • 8. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                        F.Bowman Community Member

                        Ok. I broke out at the event and these are the details:-

                         

                        event: flash.events.FocusEvent (@983bd01)

                         

                        [inherited]

                        bubbles: true

                        cancelable: true

                        currentTarget: mx.controls.DataGrid (@97800a1)

                        eventPhase: 3

                        target: mx.core.UITextField (@9614791)

                        type: "keyFocusChange"

                         

                        keyCode: 9

                        relatedObject: null

                        shiftKey: false

                        • 9. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                          F.Bowman Community Member

                          Excellent news. I got it to work!!!

                           

                          I'll post the code for the benefit of anyone else who may want to do this:-

                           

                           

                          Add a high priority event listener to the datagrid to capture keyboard events:

                           

                          myDG.addEventListener(KeyboardEvent.KEY_DOWN, keyCapture, true, -10000);
                          

                           

                          Listen for the Enter key, prevent it from executing and broadcast a keyFocusChange event instead:

                           

                          function keyCapture(event:KeyboardEvent):void
                          {
                              if(event.keyCode == 13)
                              {
                                  event.stopImmediatePropagation();
                                  myDG.dispatchEvent(new FocusEvent("keyFocusChange",true,true,null,false,9));
                              }
                          }
                          

                           

                          That should work like a charm. It did for me.

                           

                          Thanks again. I really appreciate it.

                          • 10. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                            Flex harUI Adobe Employee

                            Yeah, so create the same event and dispatch it off the itemEditorInstance

                            and see what happens.

                            • 11. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                              F.Bowman Community Member

                              It seems to be behaving the same as far as I can see. Was it supposed to behave differently?

                              • 12. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                                Justin Daily Community Member

                                I used the code that F.Bowman came up with and was able to get it to work on my dataGrid just fine.  However, the dataGrid in my form is only part of the form.  I'd like to be able to use this on things like text inputs, combo boxes, and my dataGrid all in the same form.  If I change the code posted above to attach the event handler to and dispatch the event from the stage, I can use the Enter key to move from text box to text box to combo box to whatever just fine, but then when it focuses on the dataGrid, the dataGrid no longer uses Enter in place of Tab, nor does it default back to moving down one row either.  Here is my current code:

                                 

                                public function applicationCompleteHandler():void {
                                  stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandlerStage, true, -10000);
                                }
                                
                                private function keyHandlerStage(e:KeyboardEvent):void {
                                  if(e.keyCode == 13) {
                                    e.stopImmediatePropagation();
                                    stage.dispatchEvent(new FocusEvent("keyFocusChange",true,true,null,false,9));
                                  }
                                }
                                

                                 

                                I tried setting one event listener on the stage and then one on the DataGrid, with different priorities for each, and got nothing.  Also, if I use a trace to display the keyCode of the button pressed in the stage's event Handler, it displays "13", which is normal.  But, if I trace the keyCode of the dataGrid's event handler, it doesn't display "13" when the Enter key is pressed, but it will display the keyCodes of every other key I press in the dataGrid.

                                 

                                Any idea what I'm doing wrong?

                                • 13. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                                  Flex harUI Adobe Employee

                                  By calling from the stage stopImmediatePropagation, you are blocking the

                                  DataGrid from getting the event.

                                   

                                  You could add a test to see if the event.target is the DataGrid or its

                                  editor and not call stopImmediatePropagation.

                                  • 14. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                                    Justin Daily Community Member

                                    Okay, well, I'm closer.   With this code, I can use the Enter key just like the tab key both in  and out of the DataGrids, except when I hit a custom itemEditor in the  dataGrid.  Here's what I have now:

                                     

                                    public function applicationCompleteHandler():void {
                                      stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandlerStage, true, -10000);
                                    }
                                    
                                    private function keyHandlerStage(e:KeyboardEvent):void {
                                      if(e.keyCode == 13) {
                                        var focused:Object = e.target.parent.parent.parent;
                                        var check:Boolean = focused is DataEntryDataGrid;
                                        if(check == false) {
                                          e.stopImmediatePropagation();
                                          stage.dispatchEvent(new FocusEvent("keyFocusChange",true,true,null,false,9));
                                        } else {
                                          focused.dispatchEvent(new FocusEvent("keyFocusChange",true,true,null,false,9));
                                        }
                                      }
                                    }
                                    

                                     

                                    DataEntryDataGrid on line 8 is a subclass of mx:DataGrid.  If I trace e.target while an editable cell of the datagrid is selected, I get this:

                                     

                                    HerringSurveySpawn2.ApplicationSkin2._ApplicationSkin_Group1.contentGroup.Group6.crewGrid.ListBaseContentHolder105.HerringSurveySpawn2InnerClass0_364.UITextField366
                                    

                                     

                                    In the above line, "crewGrid" is the id of the dataGrid that is focused on when the Enter key is pressed. This is what led me to the e.target.parent.parent.parent idea in the code block above.  But, when I hit a custom itemEditor, like a comboBox or something, the whole thing breaks.  There are three levels after "crewGrid" in a regular textInput-style cell, but only two levels after "crewGrid" when tracing from a comboBox itemEditor cell.  What I'd really like is to be able to check if e.target is a child of a dataGrid at any level, but I'm not sure how to accomplish that.  I'm sure that if I could get that figured out, it would work like a charm.

                                    • 15. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                                      Flex harUI Adobe Employee

                                      Try:

                                          var check:Boolean = focusManager.getFocus() is DataEntryDataGrid

                                       

                                      I think even if you're in an item editor, the focusManager thinks that the

                                      focused component is the DataGrid

                                      • 16. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                                        Justin Daily Community Member

                                        Tried that and it didn't work.  It broke the Enter key for the regular textInputs inside the dataGrid as well.  When I traced the output of focusManager.getFocus() while a datagrid cell was selected, I got:

                                         

                                        HerringSurveySpawn2.ApplicationSkin2._ApplicationSkin_Group1.contentGroup.Group6.crewGrid. ListBaseContentHolder105.HerringSurveySpawn2InnerClass0_364

                                         

                                        When what I think I was looking for was simply:

                                         

                                        HerringSurveySpawn2.ApplicationSkin2._ApplicationSkin_Group1.contentGroup.Group6.crewGrid

                                        • 17. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                                          Flex harUI Adobe Employee

                                          How many of these datagrids do you have?

                                           

                                          If you only have one, you can special case the test to use contains().  You

                                          could also build a list of them to check against, or you can do a parent

                                          walk to see if they are contained in a grid.

                                          • 18. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                                            Justin Daily Community Member

                                            The form has two different dataGrids in it, both used for data entry.  How would a "parent walk" work?

                                            • 19. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                                              Flex harUI Adobe Employee

                                              Var check:Boolean = event.target is DataGrid;

                                              If (!check)

                                              {

                                                  Var o:DisplayObjectContainer = event.target.parent

                                                  while (o != this.stage)

                                                  {

                                                      if (o is DataGrid)

                                                      {

                                                          check = true;

                                                          break;

                                                      }

                                                      o = o.parent;

                                                  }

                                              }

                                              • 20. Re: DataGrid Data Entry - Make Enter Behave Like Tab
                                                Justin Daily Community Member

                                                That's perfect.  It works like a Swiss clock now.  Here's the final code, for anyone else who might find this thread and need it:

                                                 

                                                // Call this function in your application's "applicationComplete" event
                                                public function applicationCompleteHandler():void {
                                                  stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandlerStage, true, -10000);
                                                }
                                                
                                                private function keyHandlerStage(e:KeyboardEvent):void {
                                                  if(e.keyCode == 13) {
                                                    var focused:Object;
                                                    var check:Boolean = e.target is DataEntryDataGrid;
                                                    if (!check)
                                                    {
                                                      var o:DisplayObjectContainer = e.target.parent
                                                      while (o != this.stage)
                                                      {
                                                        if (o is DataEntryDataGrid)
                                                        {
                                                          check = true;
                                                          focused = o;
                                                          break;
                                                        }
                                                        o = o.parent;
                                                      }
                                                    }
                                                    if(check == false) {
                                                      e.stopImmediatePropagation();
                                                      stage.dispatchEvent(new FocusEvent("keyFocusChange",true,true,null,false,9));
                                                    } else {
                                                      focused.dispatchEvent(new FocusEvent("keyFocusChange",true,true,null,false,9));
                                                    }
                                                  }
                                                }
                                                

                                                 

                                                Thanks, Flex!