17 Replies Latest reply on Jun 6, 2011 2:21 PM by Robert M

    Spark list filter not working

    flairjax Level 1

      I have a spark list with custom itemRenderers and I have a filter on the list.  I run the filter, but at random times the filter doesn't work. I threw in some trace statements and its passing the filter but the screen doesn't show the filters results. It only shows the results of the last filter. I think it has to do with the spark lists itemRenderer resuse.

       

      Is this a known bug?

        • 1. Re: Spark list filter not working
          Flex harUI Adobe Employee

          Did you forget to call refresh()?

          • 2. Re: Spark list filter not working
            flairjax Level 1

            Yes, calling refresh. If I shutoff virtual it works perfectly.

            • 3. Re: Spark list filter not working
              Flex harUI Adobe Employee

              Sounds like your custom renderer isn't handling recycling correctly.

              • 4. Re: Spark list filter not working
                flairjax Level 1

                Any documentation as I am not seeing any.

                 

                The issue is this. I am looking at the data with the filter set to 'all', so all 10 items are shown.  I then filter the data and it turns out only 4 match so those are shown. I then click to set the filter to 'all'. And it only updates the four shown, resuing the renderer with new data, but doesn't bring back the other 6.

                • 5. Re: Spark list filter not working
                  Flex harUI Adobe Employee

                  Does the problem happen with the default renderer?

                  • 6. Re: Spark list filter not working
                    flairjax Level 1

                    No, it doesn't happen in the default itemRenderer.

                     

                    Here is the renderer ==============================================

                     

                    <?xml version="1.0" encoding="utf-8"?>

                    <s:ItemRenderer name="CustomIconItemRenderer"

                                    xmlns:fx="http://ns.adobe.com/mxml/2009"

                                    xmlns:s="library://ns.adobe.com/flex/spark"

                                    focusEnabled="false" width="100%" height="70"

                                    xmlns:mx="library://ns.adobe.com/flex/mx"

                                    autoDrawBackground="false" right="5" left="5" top="5" bottom="5" >

                        <!-- states -->

                        <s:states>

                            <s:State name="normal" />

                            <s:State name="hovered" />

                            <s:State name="selected" />

                            <s:State name="normalAndShowsCaret" />

                            <s:State name="hoveredAndShowsCaret" />

                            <s:State name="selectedAndShowsCaret" />

                        </s:states>

                     

                        <fx:Script>

                            <![CDATA[

                                import com.me.imgResource;

                                import mx.events.FlexEvent;

                     

                                override public function set data(value:Object) : void {

                                    // Check to see if the data property is null.

                                    if (value== null)

                                        return;

                                    // If the data property is not null, check for the kind then

                                    // set the Label controls appropriately.

                                    if(value && value.hasOwnProperty('config') ){

                                        if(value.config.hasOwnProperty('bb') ){ ID.text =  value.config.bb };

                                        if(value.config.hasOwnProperty('id') ){ Pug.text = value.config.id };

                                        if(value.config.hasOwnProperty('namey') ){ Name.text = value.config.namey};

                                        if(value.commonAttrs.hasOwnProperty('allStatus')){

                                            statusImage.source = imgResource.getIcon(value.allStatus);

                                        }

                                    }else if(value && value.hasOwnProperty('config') ){

                                        if(value.config.hasOwnProperty('bb')){

                                            ID.text = "";

                                            ID.text = value.config.bb;

                                        }

                                        if(value.config.hasOwnProperty('id')){

                                            Name.text = "";

                                            Name.text = value.config.id;

                                        }

                                        if(value.config.hasOwnProperty('namey')){

                                            displayName.text = "";

                                            displayName.text = value.config.namey;

                                        }

                                        if(value.hasOwnProperty('allStatus')){

                                            atatusImage.source = imgResource.getIcon(value.allStatus);

                                        }

                                    }

                     

                                    // Dispatch the dataChange event.

                                    dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));

                                }

                            ]]>

                        </fx:Script>

                     

                     

                        <s:Group width="300" maxWidth="300" left="5" top="5" bottom="5" right="5">

                            <s:Rect left="0" right="0" top="0" bottom="0" radiusX="5" radiusY="5" >

                                <s:fill>

                                    <s:LinearGradient rotation="265">

                                        <s:GradientEntry color="0xF5FBFF" ratio=".33" />

                                        <s:GradientEntry color="0xFFFFFF" ratio=".7" />

                                    </s:LinearGradient>

                                </s:fill>

                                <s:stroke>

                                    <s:SolidColorStroke color.normal="0xCCCCCC" color.normalAndShowsCaret="0xCCCCCC"

                                                        color.hovered="0x7591AC"

                                                        color.selected="0x7591AC" color.selectedAndShowsCaret="0x7591AC"

                                                        weight.normal=".5" weight="1.5" />

                                </s:stroke>

                            </s:Rect>

                            <s:Group left="7" top="5" bottom="5">

                                <mx:Image source="{imgResource.getInstance().blah}" width="32" height="32" />

                            </s:Group>

                            <s:Group right="8" bottom="5">

                                <!--<s:Label text="2460" textAlign="right"

                                         styleName="subPanelLabel" maxWidth="120" maxDisplayedLines="1" showTruncationTip="true" />-->

                                <s:Label id="vlanID" textAlign="center" styleName="subPanelLabel"

                                         maxWidth="120" maxDisplayedLines="1" showTruncationTip="true" />

                            </s:Group>

                            <s:Group left="50" bottom="5">

                                <s:Label id="susPortName" styleName="subPanelLabel" maxWidth="120"

                                         maxDisplayedLines="1" showTruncationTip="true" />

                               <!-- <s:Label text="some shared uplink name"

                                         styleName="subPanelLabel" maxWidth="140" maxDisplayedLines="1" showTruncationTip="true" />-->

                            </s:Group>

                            <s:Group left="50" top="7">

                                <s:Label id="displayName" styleName="subPanelLabel"

                                         maxWidth="170" maxDisplayedLines="1" showTruncationTip="true" />

                            </s:Group>

                            <s:Group right="5" top="5">

                                <mx:Image id="statusImage"  />

                            </s:Group>

                        </s:Group>

                    </s:ItemRenderer>

                    • 7. Re: Spark list filter not working
                      Flex harUI Adobe Employee

                      Hard to say, but I don't like the fact you didn't pass the data property to

                      the superclass:

                          super.data = value;

                       

                      Another possible issue is the mx:Image in the bottom.  It doesn't have a

                      default size, and that can throw off measurements because it doesn't get its

                      size until after it has been measured if its content is asynchronously

                      loaded.

                       

                      If that's not it, start commenting out portions of the renderer until it

                      works.

                      • 8. Re: Spark list filter not working
                        flairjax Level 1

                        Ok, after implementing your suggstions its still there. I performed the test again with FLEX's default spark list itemRenderer and the bug is there as well.

                         

                         

                        Jason

                        • 9. Re: Spark list filter not working
                          Flex harUI Adobe Employee

                          Post a 20-line test case using the default renderer

                          • 10. Re: Spark list filter not working
                            flairjax Level 1

                            Create a project with a Spark list called mainlist, use the custom default list skin, then create another list with the letters from the alphabet a-z and add the first value to 'all' to be used for filter the mainlist.  User should click the letters of the alphabet in the filtering list to filter the mainlist.

                            So the fitlering list should contain the following "all a b c d e f .... z"

                             

                            When user clicks a letter in the filtering list, say letter 'B' it should call this function from the change event of the filtering list.

                             

                            private function setAlphaFilter() : void {

                                            if( compData ) {

                                                compData.filterFunction = alphaFilter;

                            compData.refresh();

                             

                                            }

                                        }

                             

                             

                             

                            private function alphaFilter( item:Object ) : Boolean {

                                            var tempStr:String;

                                            if(item && item.hasOwnProperty('blah') ){ // its a blah

                                                tempStr = item.config[itemToFilterOn] as String;

                                            }else if(item && item.hasOwnProperty('nonblah') ){ //its a nonblah

                                                tempStr = item[itemToFilterOn] as String;

                                            }

                             

                             

                                            if( 0 == navigator.selectedIndex && -1 != alphaList.selectedIndex && String(alphaList.selectedItem.firstName).toLowerCase() == 'all' ) {

                                                return true;

                                            }

                             

                                            if( 0 == navigator.selectedIndex && -1 != alphaList.selectedIndex ) { // if something a letter is selected.

                                                if( tempStr.toLowerCase().charAt(0) == String(alphaList.selectedItem.firstName).toLowerCase() ) {

                                                    return true;

                                                }

                                            }

                                            trace('something failed filter so will not be shown');

                                            return false;

                                        }

                             

                             

                            The issue arises if you click 'N', which has say 10 items that start with 'N' and then click 'J' which has two items that start 'J', then click 'all'.  The list which should return all items ( running through debug with trace statements shows it passes through the true) , but it will only show two renderers that matched 'J'. It won't create the others until you click some other letter 'N' or 'O' then click 'all' again.

                            • 11. Re: Spark list filter not working
                              flairjax Level 1

                              What is odd is that it is happening every 3rd time... so I am thinking some boolean/flag is getting set wrong in the framework code.

                               

                               

                               

                               

                              ISSUE BUG IN LIST:  This is function is only getting called twice (when the renderers don't show up that should... it will only show two; meaning it failed).  Now to walk this back and see why its only being called twice even though my list has 100 items in it.

                               

                              private function dataGroup_rendererAddHandler(event:RendererExistenceEvent):void

                                  {

                                      var index:int = event.index;

                                      var renderer:IVisualElement = event.renderer;

                               

                                      if (!renderer)

                                          return;

                               

                                      renderer.addEventListener(MouseEvent.MOUSE_DOWN, item_mouseDownHandler);

                                  }

                              • 12. Re: Spark list filter not working
                                Flex harUI Adobe Employee

                                I am looking for a complete test case in about 20 lines I can cut/paste and

                                run.

                                • 13. Re: Spark list filter not working
                                  flairjax Level 1

                                  The bug is in TileLayout. 

                                   

                                  If I remove the the TileLayout the list functions as aspected.  Here is a simple example.  Make sure when running the app to follow these instructions.

                                   

                                  1. Run the app (notice the list shows all the items in it)

                                  2. Click "K"

                                  3. Click "All"

                                  4. Look at the Bottom list to see if only two items show even when "ALL" is selected.

                                  5.Repeat steps 2-4 until you see the bug.

                                   

                                   

                                   

                                  <?xml version="1.0" encoding="utf-8"?>

                                  <!-- http://blog.flexexamples.com/2010/05/12/scrolling-to-a-specific-index-in-a-spark-list-cont rol-in-flex-4/ -->

                                  <s:Application name="Spark_List_ensureIndexIsVisible_test"

                                     xmlns:fx="http://ns.adobe.com/mxml/2009"

                                     xmlns:s="library://ns.adobe.com/flex/spark"

                                     xmlns:mx="library://ns.adobe.com/flex/mx">

                                   

                                   

                                  <fx:Script>

                                  <![CDATA[

                                  import mx.collections.ArrayCollection;

                                   

                                  private var array:Array = ['one', 'otwo', 'othree', 'ofour', 'ofive', 'osix', 'oseven', 'oeight', 'nine', 'nten'];

                                  private var myAC:ArrayCollection = new ArrayCollection( array );

                                   

                                  private function setAlphaFilter() : void {

                                  if( myAC ) {

                                  myAC.filterFunction = alphaFilter;

                                  myAC.refresh();

                                   

                                  }

                                  }

                                   

                                  private function alphaFilter( item:Object ) : Boolean {

                                  var tempStr:String;

                                   

                                   

                                  if( String(alphaList.selectedItem.firstName).toLowerCase() == 'all' ) {

                                  return true;

                                  }

                                   

                                  if(  item.toLowerCase().charAt(0) == String(alphaList.selectedItem.firstName).toLowerCase() ) { // if something a letter is selected.

                                  return true;

                                  }

                                  return false;

                                  }

                                   

                                  ]]>

                                  </fx:Script>

                                   

                                   

                                  <s:List id="alphaList" changing="setAlphaFilter()"

                                  width="100%" top="2" bottom="2" left="2" right="2" borderColor="#7F7F7F" >

                                  <s:layout>

                                  <s:HorizontalLayout columnWidth="20" paddingLeft="1" />

                                  </s:layout>

                                  <!-- itemRenderer is inline in this sample -->

                                  <s:itemRenderer>

                                  <fx:Component>

                                  <s:ItemRenderer>

                                  <s:Group top="1">

                                  <s:Label id="blah" text="{data.firstName}" fontSize="13" bottom="1" top="1" right="1" left="1" />

                                  </s:Group>

                                  </s:ItemRenderer>

                                  </fx:Component>

                                  </s:itemRenderer>

                                  <s:dataProvider>

                                  <s:ArrayList>

                                  <fx:Object firstName="All" />

                                  <fx:Object firstName="A"  />

                                  <fx:Object firstName="B"  />

                                  <fx:Object firstName="C" />

                                  <fx:Object firstName="D" />

                                  <fx:Object firstName="E" />

                                  <fx:Object firstName="F"  />

                                  <fx:Object firstName="G"  />

                                  <fx:Object firstName="H" />

                                  <fx:Object firstName="I" />

                                  <fx:Object firstName="J" />

                                  <fx:Object firstName="K"  />

                                  <fx:Object firstName="L"  />

                                  <fx:Object firstName="M" />

                                  <fx:Object firstName="N" />

                                  <fx:Object firstName="O" />

                                  <fx:Object firstName="P"  />

                                  <fx:Object firstName="Q"  />

                                  <fx:Object firstName="R" />

                                  <fx:Object firstName="S" />

                                  <fx:Object firstName="T" />

                                  <fx:Object firstName="U"  />

                                  <fx:Object firstName="V"  />

                                  <fx:Object firstName="W" />

                                  <fx:Object firstName="X" />

                                  <fx:Object firstName="Y" />

                                  <fx:Object firstName="Z" />

                                  <fx:Object firstName="1" />

                                  <fx:Object firstName="2" />

                                  <fx:Object firstName="3" />

                                  <fx:Object firstName="4" />

                                  <fx:Object firstName="5" />

                                  <fx:Object firstName="6" />

                                  <fx:Object firstName="7" />

                                  <fx:Object firstName="8" />

                                  <fx:Object firstName="9" />

                                   

                                  </s:ArrayList>

                                  </s:dataProvider>

                                  </s:List>

                                   

                                  <s:List id="list" width="630" height="100"

                                  horizontalCenter="0" verticalCenter="0" dataProvider="{myAC}" useVirtualLayout="true" allowMultipleSelection="true">

                                  <s:layout>

                                  <s:TileLayout columnWidth="300" rowHeight="50" verticalGap="1" horizontalGap="1" 

                                    requestedColumnCount="2"  />

                                  </s:layout>

                                  </s:List>

                                   

                                  </s:Application>

                                  • 14. Re: Spark list filter not working
                                    flairjax Level 1

                                    bump bump

                                    • 15. Re: Spark list filter not working
                                      Flex harUI Adobe Employee

                                      I'm buried with other stuff right now.  Will try to take a look Friday.

                                      • 16. Re: Spark list filter not working
                                        Flex harUI Adobe Employee

                                        I was not able to reproduce this in 4.5

                                        • 17. Re: Spark list filter not working
                                          Robert M

                                          We ran into the same problem, and believe it to be a bug.  You should be able to reproduce the issue with code below.  If you run the code as is, then you will notice that the bevelFilter is never applied.  If you uncomment out the second label with the width="115", then the bevel gets applied as expected.  It would appear that making the child larger than the parent will perform the sizing calculation needed to allow the bevel to be applied. The bevelFilter gets applied properly in 3.5.  It does not work in 4.1 or 4.5.  NOTE:  I had to place creationComplete="invalidateDisplayList();" on the renderer in order for the filter to be applied automatically, otherwise it will not be applied until roleover.

                                           

                                          <?xml version="1.0" encoding="utf-8"?>
                                          <mx: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">
                                               <fx:Script>
                                                    <![CDATA[
                                                         [Bindable]
                                                         private var dpArray:Array = new Array("a", "b", "c");
                                                    ]]>
                                               </fx:Script>
                                               <mx:List id="manifestListLarge" width="110"     dataProvider="{dpArray}" backgroundColor="#304698"     color="#FFFFFF">
                                                    <mx:itemRenderer> 
                                                         <fx:Component>
                                                              <mx:VBox filters="{[bevelDown]}" backgroundColor="#6788F2" horizontalScrollPolicy="off"     verticalScrollPolicy="off" height="50" creationComplete="invalidateDisplayList();" >
                                                                   <fx:Declarations>
                                                                        <s:BevelFilter id="bevelDown" type="inner" angle="245" shadowAlpha="0.4" highlightAlpha="0.4" distance="8" blurX="10" blurY="10"  quality="4"/>
                                                                   </fx:Declarations>
                                                                   <mx:Label      width="90" text="List Width -20"/>
                                                                   <!--<mx:Label      width="115" text="List Width +5"/>-->
                                                              </mx:VBox>
                                                         </fx:Component>     
                                                    </mx:itemRenderer>
                                               </mx:List>
                                          </mx:Application>