30 Replies Latest reply on Jun 4, 2009 8:46 AM by Flex harUI

    TextInputs in large amount - RIA killer

    mraak Level 1

      I recently got a project with huge screens of calculations to be perfomered. Imagine a scenario to calculate house building expenses from every nail to every meal for workers. Naturally the user has to be able to insert a lot of variables to get the final calc done, and those variables get inserted through TextInput. It is a perfect RIA scenario.

       

      However, when we got to the point that we had to place all those textfields on the screen, the performance falls to unusable levels even on better machines. There are only about 200 TextInputs and it is amazingly slow.

       

      Is there a way to do improve performance or is it better to start rebuilding in JS or Silverlight ASAP? After 9 years of being Flash (and later Flex) enthusiast, I really doubt Flex is the right platform for RIA if the performance is that bad.

       

      Thanks a lot.

        • 1. Re: TextInputs in large amount - RIA killer
          Flex harUI Adobe Employee

          I would use an editable DataGrid, then you wouldn't have 200 TextInputs sitting around.

           

          Alex Harui

          Flex SDK Developer

          Adobe Systems Inc.

          Blog: http://blogs.adobe.com/aharui

          • 2. Re: TextInputs in large amount - RIA killer
            mraak Level 1

            Hmm, those TextInputs are in fact a little bit special, my own component based on TextInput, so I don't know if I can achieve the same with DataGrid. They can be placed randomly all over the screen however designer chooses.

             

            Which DataGrid you recommend? Can I "extend" the DataGrid field somehow to inject additional functionality to each field?

             

            Cheers

            • 3. Re: TextInputs in large amount - RIA killer
              Flex harUI Adobe Employee

              Use the simplest DataGrid that supports your needs.  AdvancedDG supports hierarchy, regular DG does not.  If I were inputting lots of numbers, I wouldn't want a fancy layout, I'd want a column of numbers.  If you play with the editable DG examples you'll see that when you click on a field, a TextInput shows up.  You can easily swap in your custom TextInput instead.

               

              Alex Harui

              Flex SDK Developer

              Adobe Systems Inc.

              Blog: http://blogs.adobe.com/aharui

              1 person found this helpful
              • 4. Re: TextInputs in large amount - RIA killer
                mraak Level 1

                Thanks Alex, it's still better to use grid for large amount of inputs I guess. Though the limitation of technology with TextInputs is quite frustrating. I imagine generating 200 text fields with Javascript wouldn't impact browser performance a lot.

                 

                Either way, I think I'm onto something, grid is quite good performance wise. I wouldn't have as clean code and as customizable UI, but what can you do.

                • 5. Re: TextInputs in large amount - RIA killer
                  Flex harUI Adobe Employee

                  Someday I'll run a test with 200 TextInputs.  I wouldn't expect serious performance problems, but you never know.  200+ interactive items is a lot in Flash, but shouldn't be killer.  Did you try it with plain TextInputs instead of your custom ones?  Did you try running the profiler to see where the time is going?

                   

                  Alex Harui

                  Flex SDK Developer

                  Adobe Systems Inc.

                  Blog: http://blogs.adobe.com/aharui

                  • 6. Re: TextInputs in large amount - RIA killer
                    mraak Level 1

                    Not yet, someday I will test it

                     

                    Anyway, I think using the grid for large sets, and few TextInputs here and there can sort out our usability and design needs.

                     

                    One thing I would need though is direct access to existing item renderers in datagrid. I need to be able to programatically get and set the value od a particular field. I see a nice property in the datagrid called rendererArray but seems that it's private and I can't access it. I even tried extending DG but it still says not available.

                     

                    Any other way I can modify data in datagrid apart from changing the dataprovider and reassigning it?

                     

                     

                    <?xml version="1.0" encoding="utf-8"?>
                    <mx:DataGrid xmlns:mx="http://www.adobe.com/2006/mxml">
                        <mx:Script>
                            <![CDATA[
                               
                               
                                public function get renderers():Array
                                {
                                    return this.rendererArray(); // NO GO
                                }
                               
                            ]]>
                        </mx:Script>
                    </mx:DataGrid>

                    • 7. Re: TextInputs in large amount - RIA killer
                      Srirangan Level 2

                      Interesting..

                       

                      I am working on a similar calculator for the aerospace sector. Again plenty of inputs (primary and secondary). In fact the number of inputs itself is variable. On average at least 100 inputs in 2 input tabs and upto 10-12 output/visualization tabs.

                       

                      I do not notice any significant performance glitch. I think scrutinizing the internal architecture of the code would be important here.

                       

                      - Sri

                      • 8. Re: TextInputs in large amount - RIA killer
                        Flex harUI Adobe Employee

                        There are a set of events like ITEM_EDIT_BEGIN and ITEM_EDIT_END that you can use to customize what appears in the editor.   The editor is also assigned the data item from the dataProvider and you can customize the editor to show something other than the data item if you want.

                         

                        Alex Harui

                        Flex SDK Developer

                        Adobe Systems Inc.

                        Blog: http://blogs.adobe.com/aharui

                        • 9. Re: TextInputs in large amount - RIA killer
                          mraak Level 1

                          You were both right Seems like there was something else hampering the perormance and not TextInput as this works pretty well:

                           

                                          for (var i:int = 0; i < 70; i++)
                                          {
                                              for (var j:int = 0; j < 7; j++)
                                              {
                                                  var ti:TextInput = new TextInput();
                                                  ti.text = "row:" + i + ", col:" + j;
                                                  ti.x = j * 170;
                                                  ti.y = i * 30;
                                                 
                                                  addChild(ti);
                                              }
                                             
                                          }

                           

                          But now I got somehow hooked on the DataGrid as well, so I'll be developing it both ways.

                           

                          @sri: Seems like we'd have planty to talk about

                          • 10. Re: TextInputs in large amount - RIA killer
                            mraak Level 1

                            Alex, a question for you. ITEM_EDIT_END, as said in Flex docs, you can use to modify the value before asigning it back to the list.

                             

                            Right now I'm asigning the modified value like this (dataCollection:ArrayCollection is dataProvider for DataGrid)
                            :

                             

                            var modifiedObject:Object = dataCollection[evt.rowIndex];

                            modifiedObject.artist = "mraak";

                            dataCollection.setItemAt(modifiedObject, evt.rowIndex);

                             

                            If I just change the value in dataCollection it does not work:

                             

                            dataCollection[4].artist = "mraak";

                             

                            Is there a more elegant way than setItemAt?

                            • 11. Re: TextInputs in large amount - RIA killer
                              mraak Level 1

                              The reason why I'm asking this is because it seems that dataCollection.setItemAt trigers ITEM_EDIT_END with event reason = other.

                               

                              This in turn creates and endless loop.

                              • 12. Re: TextInputs in large amount - RIA killer
                                Flex harUI Adobe Employee

                                If your data is not then you have to call itemUpdated on the ArrayCollection.

                                 

                                Alex Harui

                                Flex SDK Developer

                                Adobe Systems Inc.

                                Blog: http://blogs.adobe.com/aharui

                                • 13. Re: TextInputs in large amount - RIA killer
                                  mraak Level 1

                                  The thing that bothers me is that ITEM_EDIT_END is called after setItemAt.

                                   

                                  After editing the field i get this event three times, let's say I edit a field and press ENTER, and in the event handler I call setItemAt.

                                   

                                  1. Event.reason = "newRow"

                                  2. Event.reason = "cancelled"

                                  3. Event.reason = "other"

                                   

                                   

                                  Really annoying, I think one event should do. It really messes up the development this way.

                                  • 14. Re: TextInputs in large amount - RIA killer
                                    Flex harUI Adobe Employee

                                    If you have a simple test case, file a bug.

                                     

                                    Alex Harui

                                    Flex SDK Developer

                                    Adobe Systems Inc.

                                    Blog: http://blogs.adobe.com/aharui

                                    • 15. Re: TextInputs in large amount - RIA killer
                                      mraak Level 1

                                      The thing is - I don't know if it's a bug or a feature

                                      • 16. Re: TextInputs in large amount - RIA killer
                                        Flex harUI Adobe Employee

                                        Unexpected.  In theory the only way to get CANCELLED is to hit escape.

                                         

                                        Alex Harui

                                        Flex SDK Developer

                                        Adobe Systems Inc.

                                        Blog: http://blogs.adobe.com/aharui

                                        • 17. Re: TextInputs in large amount - RIA killer
                                          mraak Level 1

                                          Try this and you'll see. Check the trace in onEditEnd.

                                           

                                           

                                          <?xml version="1.0" encoding="utf-8"?>
                                          <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCreationComplete()">
                                              <mx:Script>
                                                  <![CDATA[
                                                      import mx.controls.TextInput;
                                                      import mx.events.DataGridEvent;
                                                      import mx.collections.ArrayCollection;
                                                     
                                                      [Bindable]
                                                      private var src:ArrayCollection
                                                     
                                                      private function onCreationComplete():void
                                                      {
                                                          src = new ArrayCollection([{col1:"1", col2:"2", col3:"3"}, {col1:"1", col2:"2", col3:"3"}, {col1:"1", col2:"2", col3:"3"}]);
                                                         
                                                          var sdf:int = 0;

                                           

                                                          grd.addEventListener(DataGridEvent.ITEM_EDIT_END, onEditEnd);
                                                      }
                                                     
                                                      private function onEditEnd(evt:DataGridEvent):void
                                                      {
                                                         
                                                          trace(evt.reason);
                                                         
                                                          var o:Object = src[evt.rowIndex];
                                                          o[evt.dataField] = TextInput(grd.itemEditorInstance).text + " my change";
                                                          src.setItemAt(o,evt.rowIndex);
                                                         
                                                      }
                                                     
                                                  ]]>
                                              </mx:Script>
                                             
                                              <mx:DataGrid id="grd" editable="true" x="151" y="124" dataProvider="{src}">
                                                  <mx:columns>
                                                      <mx:DataGridColumn headerText="Column 1" dataField="col1"/>
                                                      <mx:DataGridColumn headerText="Column 2" dataField="col2"/>
                                                      <mx:DataGridColumn headerText="Column 3" dataField="col3"/>
                                                  </mx:columns>
                                              </mx:DataGrid>
                                             
                                          </mx:Application>

                                          • 18. Re: TextInputs in large amount - RIA killer
                                            Flex harUI Adobe Employee

                                            Sorry, I forgot that the only way for user to cause CANCEL is via ESC, but if the item being edited gets removed it also CANCELs the edit.

                                             

                                            Anyway, you should be using itemUpdated instead of setItemAt.

                                             

                                            Alex Harui

                                            Flex SDK Developer

                                            Adobe Systems Inc.

                                            Blog: http://blogs.adobe.com/aharui

                                            • 19. Re: TextInputs in large amount - RIA killer
                                              mraak Level 1

                                              I'm sorry but this does not show any update on the view.

                                               

                                               

                                                          private function onEditEnd(evt:DataGridEvent):void
                                                          {
                                                             
                                                              trace(evt.reason);
                                                             
                                                              var o:Object = src[evt.rowIndex];
                                                              o[evt.dataField] = TextInput(grd.itemEditorInstance).text + " my change";

                                                              src.itemUpdated(o, evt.dataField);
                                                          }

                                              • 20. Re: TextInputs in large amount - RIA killer
                                                Flex harUI Adobe Employee

                                                Sorry again.  I didn't notice that you were trying to modify the results of the edit session.  I would create a custom editor with a custom property that returns the modified value and use that property as the editorDataField.   Then you shouldn't need an ITEM_EDIT_END handler.

                                                 

                                                 

                                                Alex Harui

                                                Flex SDK Developer

                                                Adobe Systems Inc.

                                                Blog: http://blogs.adobe.com/aharui

                                                • 21. Re: TextInputs in large amount - RIA killer
                                                  mraak Level 1

                                                  Can you please give me some more hints on how to do that? It seems exactly the thing I need. But is it viable to add a custom editor if TextInput is exactly what I need? Does it make sense replacing TextInput with another TextInput?

                                                  • 22. Re: TextInputs in large amount - RIA killer
                                                    Flex harUI Adobe Employee

                                                    I think it is a valid enhancement request that modifying the results of the edit session should be easier, but a custom editor will be the easiest way to do this.

                                                     

                                                    The general idea is that you can make a subclass like this:

                                                    • 23. Re: TextInputs in large amount - RIA killer
                                                      mraak Level 1

                                                      He he, I think your message got truncated just above where you pasted the code. Nice teaser though.Can you please repost? Otherwise, I've seen in LiveDocs that ITEM_EDIT_END is the place to be if you want to do any changes to the data on it's way from itemEditor to dataProvider. That's why I'm using it.

                                                      • 24. Re: TextInputs in large amount - RIA killer
                                                        Flex harUI Adobe Employee

                                                        Yeah I know the doc says to do that, but it was harder than I expected it to be so I'm recommending this pattern:

                                                         

                                                         

                                                        ====== MyChangeEditor.as =====

                                                        package 

                                                        {

                                                          import mx.controls.TextInput;

                                                         

                                                          public class MyChangeEditor extends TextInput {

                                                         

                                                            public function get actualValue():String

                                                            {

                                                                return text + "my change";

                                                            }

                                                          }

                                                        }

                                                         

                                                        And remove the ITEM_EDIT_END handler and modify the datagrid columns

                                                         

                                                                    <mx:DataGridColumn headerText="Column 1" dataField="col1" itemEditor="MyChangeEditor" editorDataField="actualValue" />

                                                                    <mx:DataGridColumn headerText="Column 2" dataField="col2" itemEditor="MyChangeEditor" editorDataField="actualValue" />

                                                                    <mx:DataGridColumn headerText="Column 3" dataField="col3" itemEditor="MyChangeEditor" editorDataField="actualValue" />

                                                         

                                                        Alex Harui

                                                        Flex SDK Developer

                                                        Adobe Systems Inc.

                                                        Blog: http://blogs.adobe.com/aharui

                                                        • 25. Re: TextInputs in large amount - RIA killer
                                                          mraak Level 1

                                                          Thanks a ton, I'll see if this approach works for me. By the way LiveDocs are also referring to preventDefault(), which I can't find anywhere in the grid or editor. When is that Flex4 coming ?

                                                          • 26. Re: TextInputs in large amount - RIA killer
                                                            Flex harUI Adobe Employee

                                                            preventDefault() is a method on Event.  It's been there all the time and you needed to call it but didn't in your original example, however I found some issues after doing that so I think this subclass approach might be better

                                                             

                                                            Alex Harui

                                                            Flex SDK Developer

                                                            Adobe Systems Inc.

                                                            Blog: http://blogs.adobe.com/aharui

                                                            • 27. Re: TextInputs in large amount - RIA killer
                                                              mraak Level 1

                                                              My goodness, this code turns renderes in TextInputs too, not just the editors. I have full grid of TextInputs, what did I do wrong again.

                                                               

                                                                              for (j = 0; j < c; j++)
                                                                              {
                                                                                  var dc:DataGridColumn = new DataGridColumn("c"+j);
                                                                                  dc.itemRenderer = new ClassFactory(GridItemEditor);
                                                                                  dc.editorDataField = "actualValue" ;
                                                                                  cols.push(dc);
                                                                                 
                                                                              }

                                                               

                                                              --------------------------------------


                                                                public class GridItemEditor extends TextInput {

                                                                  public function get actualValue():String
                                                                  {
                                                                      return text + "my change";
                                                                  }
                                                                }

                                                              • 28. Re: TextInputs in large amount - RIA killer
                                                                Flex harUI Adobe Employee

                                                                dc.itemEditor, not dc.itemRenderer

                                                                 

                                                                Alex Harui

                                                                Flex SDK Developer

                                                                Adobe Systems Inc.

                                                                Blog: http://blogs.adobe.com/aharui

                                                                • 29. Re: TextInputs in large amount - RIA killer
                                                                  mraak Level 1

                                                                  I is genious, innit?

                                                                   

                                                                  It works like charm. When is that Fx4 coming, and are there any major changes to DataGrid?

                                                                  • 30. Re: TextInputs in large amount - RIA killer
                                                                    Flex harUI Adobe Employee

                                                                    Flex 4 is due by end of year, no changes to DataGrid in Flex4

                                                                     

                                                                    Alex Harui

                                                                    Flex SDK Developer

                                                                    Adobe Systems Inc.

                                                                    Blog: http://blogs.adobe.com/aharui