13 Replies Latest reply on Jun 13, 2007 11:56 PM by Craig Grummitt

    item renderer

    Craig Grummitt Level 3
      help!
      i began with a List of editable text fields that works fine. now i need to add a button to each item, so i set up custom item renderers. my item renderers seem to be working okay until... scrolling is involved. even the adobe example: Using an item renderer as an item editor has the same problem... text disappears or doesn't update etc if you put enough lines in to force scrolling..

      I have read keytree's problem in forums which had some useful information about item renderers only being generated when they are visible(thanks peterent), but even after reading the full posts on that page, i am still having major difficulties working out how to modify my code to accomodate scrolling. can anyone help?

      as a sub-question, how does one trigger an event from a custom item renderer(such as a renderer that contains a button)? is an inline item renderer necessary?

      thanks for reading...
      Craig
        • 1. Re: item renderer
          Craig Grummitt Level 3
          just as an update for anyone with a similar problem, i have made progress. i added the following two lines to the list component:

          labelField="contactName"
          editorDataField="newContact"

          Then inside the itemrenderer component, i set up setters getters for data:

          private var _data:Object;
          [Bindable]
          override public function set data(value:Object):void {
          _data = value;
          newContact=value.contactName;
          }
          override public function get data( ):Object {
          return _data;
          }

          i also set up a change event handler on my textinput field which also updates newContact.
          Doing this ensures the list's dataProvider is updated with this field on every change.

          ...Well, theoretically anyway - i have encountered new problems(of course!) which i thought worthy of a new category( here)
          Basically there appears to be a conflict with the automatic alphanumeric key item selection.

          Oh - and to trigger an event from the custom item renderer - i don't know if this is the best way, but i created a custom component for the list, which included metadata for the event the custom item renderer dispatched, and made sure that the event bubbled. there - the list dispatches an event from the itemrenderer.

          Any comments welcome
          Craig
          • 2. Re: item renderer
            peterent Level 2
            Your approach to having an itemRenderer or editor dispatch custom events is correct - bubble the event and customize the List control with the event metadata - the List doesn't have to do anything but that.

            I see a major problem with your itemRenderer code:
            private var _data:Object; // not needed
            [Bindable] // not needed
            override public function set data(value:Object):void {
            _data = value; // not needed
            newContact=value.contactName;
            }
            override public function get data( ):Object { // not needed
            return _data; // not needed
            } // not needed

            It should simply read:

            override public function set data(value:Object):void {
            super.data = value; // extremely, incredibly important to do this first thing
            if( value ) { // value may be null
            newContact=value.contactName;
            }
            }

            And that's it. You don't need your own data (just use data and the super.data getter will be invoked) but you must set the super.data value as other things (internal things) depend on it. This is most likely the cause of your problems.

            So try that first and see what happens.
            • 3. Re: item renderer
              Craig Grummitt Level 3
              thanks for that peter - appreciate you having a look at this problem. very useful advice and good to hear i was on the right track with itemrenderer event bubbling.

              i've replaced the section of code with your suggestion and i'm afraid i'm still getting the problem which still appears to be occurring only on alphanumeric key item jumping.

              i'd love it if you could have a look - you should be able to replicate the problem at this test site and if you like you can look at the code here

              Cheers
              Craig
              • 4. Re: item renderer
                peterent Level 2
                Did you make further changes? The site works fine for me. I could select your name and type abcdef and it just replaced your name without doing anything else. When I scrolled and came back your name was there. The itemEditor code looks fine now.

                If you are still having the problem, download the Hotfix 2:
                http://www.adobe.com/go/kb401825

                • 5. item renderer
                  Craig Grummitt Level 3
                  hmm... no i haven't made further changes, and i have the hotfix.

                  just to clarify, when you click on the field you must select the characters in my name before releasing the mouse button. is this what you're doing? i'm on another computer using another browser and still getting the issue...

                  here we go - to illustrate, i've just created a captivate demonstration of the problem: captivate demo
                  • 6. Re: item renderer
                    xmritchie Level 1
                    Inside the itemRenderer add a listenter to your Input control:

                    myInput.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);

                    In the onKeyDown function do event.stopImmediatePropagation();

                    This will stop it from bubbling up while you are typing.
                    • 7. item renderer
                      Craig Grummitt Level 3
                      xmritchie brilliant idea. this does the trick in that it removes the default alphanumeric key item jumping. hooray!

                      however... it doesn't fix the original problem of edited items disappearing... grr!!

                      so the pattern is:
                      if i select the text at the same time as selecting the itemrenderer, any edits are ignored.
                      if i click on the itemrenderer and then select the text, edits register.

                      and i don't think its a coincidence that the alphanumeric item jumping was happening only when edits were ignored - i think whatever triggers the alphanumeric item jumping to occur is also causing this problem...

                      i'm not giving up! more ideas welcome...
                      • 8. Re: item renderer
                        xmritchie Level 1
                        Ok, I created an example that I have been developing that allows you to edit the title of images within a TileList. I didn't follow the adobe example, I instead extended the TextInput control. I hope this example helps:

                        http://thanksmister.com/examples/itemrenderereditor/main.html
                        • 9. Re: item renderer
                          Craig Grummitt Level 3
                          xmritchie i'm afraid your tilelist wasn't set up with a labelfield or editorDataField so there is no updating of the dataprovider going on when you add scrolling to the tilelist.

                          give it a go - give the tilelist a width of 300 and height of 200 say, edit some text, scroll down and then scroll back up and notice how the text has returned to what it was originally...
                          • 10. Re: item renderer
                            xmritchie Level 1
                            Yeah, in my Applicatin I set the Value Object in an ArrayCollection through a round trip to the server, so the dataProvider is updated through binding in the Model.

                            Probably why i didn't experience the issue other than through the example I provided (which does not update the dataprovider). Just assume for a moment thta you updated your dataProvider through an event and that the dataProvider was bound to the TileList, that should be fine right?
                            • 11. item renderer
                              Craig Grummitt Level 3
                              well well. very interesting. i remember considering this route at one stage and deciding that it would be too time consuming, and surely i should be able to get flex components to operate as they are meant to right? i refer to specifically the idea that specifying editorDataField should automatically update the dataProvider. And it does in almost all cases... but not all. I basically need to somehow force the dataProvider to update in ALL cases.

                              Your idea of taking a different route of updating the list's dataProvider through an event etc got me thinking - can the itemrenderer itself access and update its dataProvider? and the answer is yes - the property data.

                              which simplifies everything!

                              in my item renderer component, i have removed all references to "newContact" and data setters and in my list component call i've removed a reference to "editorDataField", set "editable" to false and "renderIsEditor" to false (as i'm going to make the itemRenderer handle the dataProvider updating) and onChange to the textInput component, i have:

                              this.data.contactName=event.target.text;

                              this onChange handler is called on ALL changes.

                              i've probably not explained this well, feel free to ask if you need more info, but the long and short is i'm happy with this solution of manually handling change events in the itemrenderer and ensuring the dataProvider changes accordingly.

                              Thanks xmritchie + peterent for your assistance.
                              regards
                              craig
                              • 12. Re: item renderer
                                xmritchie Level 1
                                You can access the dataProvider from the ItemRenderer. I just didn't need to do that in my application. Here is another itemRenderer for a list that has access to the list itself, where you could access the listOwner.labelField to update the data:

                                <?xml version="1.0" encoding="utf-8"?>
                                <mx:Canvas xmlns:mx=" http://www.adobe.com/2006/mxml"
                                implements="mx.controls.listClasses.IDropInListItemRenderer"
                                width="100%" height="40"
                                paddingBottom="10" paddingTop="10"
                                verticalScrollPolicy="off"
                                horizontalScrollPolicy="off">

                                <mx:Script>
                                <![CDATA[
                                import com.xdrive.vo.CollectionVO;
                                import com.xdrive.vo.MediaVO;

                                import com.assets.FileIconFactory;
                                import com.assets.FileIconSize;
                                import com.assets.FileType;

                                // custom selection
                                import mx.controls.listClasses.ListBase;
                                import mx.controls.listClasses.IDropInListItemRenderer;
                                import mx.controls.listClasses.BaseListData;


                                // custom selection
                                [Bindable]
                                private var listOwner:ListBase;
                                private var _listData:BaseListData;


                                [Bindable]
                                public function get listData():BaseListData
                                {
                                return _listData;
                                }

                                public function set listData(value:BaseListData):void
                                {
                                _listData = value;

                                if (_listData){
                                listOwner = ListBase(_listData.owner);
                                }
                                }

                                override protected function updateDisplayList(unscaledWidth : Number, unscaledHeight : Number) : void
                                {
                                super.updateDisplayList(unscaledWidth, unscaledHeight);

                                if (data && parent)
                                {
                                var index:Number = listOwner.itemRendererToIndex(this);
                                if (listOwner.isItemSelected(_listData.uid)){
                                currentState = 'selected';
                                } else if (listOwner.isItemHighlighted(listData.uid)) {
                                currentState = 'rollover';
                                } else {
                                currentState = 'rollout';
                                }
                                }
                                }



                                private function removeItem(event:Event):void
                                {
                                var index:Number = listOwner.itemRendererToIndex(this);
                                listOwner.dataProvider.removeItemAt(index);
                                }

                                ]]>
                                </mx:Script>




                                <mx:Label styleName="listItem" id="textBox" text="{data.label}" textAlign="left" verticalCenter="0" left="44" right="50"/>



                                <mx:states>
                                <mx:State name="rollover">
                                <mx:SetStyle target="{imageBox}" name="styleName" value="listItemRolledOver" />
                                </mx:State>
                                <mx:State name="rollout">
                                <mx:SetStyle target="{imageBox}" name="styleName" value="listItem" />
                                </mx:State>
                                <mx:State name="selected">
                                <mx:SetStyle target="{imageBox}" name="styleName" value="listItemSelected" />
                                </mx:State>
                                </mx:states>


                                </mx:Canvas>
                                • 13. Re: item renderer
                                  Craig Grummitt Level 3
                                  great tips cheers xmritchie