Kerri
Kerri

Reputation: 163

Flex 3 scrollToIndex Help

I'm attempting to search a combobox based on text entered via a keyboard event. The search is working and the correct result is being selected but I can't seem to get the scrollToIndex to find the correct item which should be the found result (i). It's scrolling to the last letter entered which I believe is the default behavior of a combobox. I think I'm referring to the event target incorrectly. Newbie tearing my hair out. Can you help? Thank you. Here's the function:

private function textin(event:KeyboardEvent):void 
{

var combo:ComboBox = event.target as ComboBox;

var source:XMLListCollection = combo.dataProvider as XMLListCollection;

str += String.fromCharCode(event.charCode);

if (str=="") {
  combo.selectedIndex = 0;
}

for (var i:int=0; i<source.length; i++) {

    if ( source[i][email protected](new RegExp("^" + str, "i")) ) {
     combo.selectedIndex = i;
     event.target.scrollToIndex(i);
     break;
    }

}
}

Control:

<mx:ComboBox keyDown="textin(event);" id="thislist" change="processForm();" dataProvider="{xmllist}"/>

Upvotes: 1

Views: 1499

Answers (2)

Canella
Canella

Reputation: 454

Here is a solution, based on Kerri's code and Ryan Lynch's suggestions. The credit goes to then.

It's working for me, so I will leave the complete code here for the future generations. :)

import com.utils.StringUtils;

import flash.events.KeyboardEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;

import mx.collections.ArrayCollection;
import mx.controls.ComboBox;

public class ExtendedComboBox extends ComboBox
{
    private var mSearchText : String = "";

    private var mResetStringTimer : Timer;

    public function ExtendedComboBox()
    {
        super();

        mResetStringTimer = new Timer( 1000 );
        mResetStringTimer.addEventListener( TimerEvent.TIMER, function() : void { mResetStringTimer.stop(); mSearchText = ""; } );
    }       

    override protected function keyDownHandler( aEvent : KeyboardEvent ):void
    {
        if( aEvent.charCode < 32 )
        {
            super.keyDownHandler( aEvent );
            return;
        }

        var lComboBox : ComboBox = aEvent.target as ComboBox;

        var lDataProvider : ArrayCollection = lComboBox.dataProvider as ArrayCollection;

        mSearchText += String.fromCharCode( aEvent.charCode );

        if ( StringUtils.IsNullOrEmpty( mSearchText ) ) 
        {
            lComboBox.selectedIndex = 0;
            aEvent.stopImmediatePropagation();
            return;
        }

        if( mResetStringTimer.running )
            mResetStringTimer.reset();

        mResetStringTimer.start();

        for ( var i : int = 0; i < lDataProvider.length; i++ ) 
        {               
            if ( lDataProvider[i].label.match( new RegExp( "^" + mSearchText, "i") ) ) 
            {
                lComboBox.selectedIndex = i;
                aEvent.stopImmediatePropagation();
                break;
            }
        }
    }
}

This solution expects an ArrayCollection as the dataProvider and a field named "label" to do the searching. You can create a variable to store the name of the field, and use it like this:

lDataProvider[i][FIELD_NAME_HERE].match( new RegExp( "^" + mSearchText, "i") )

Have fun!

Upvotes: 0

Ryan Lynch
Ryan Lynch

Reputation: 7786

If event.target is a mx.control.ComboBox then it doesn't have a scrollToIndex method, which is a method defined in mx.controls.ListBase, which the ComboBox doesn't inherit from. Check the api reference for the ComboBox. What exactly is the result you a you are trying to achieve here? If you set the selected index of a ComboBox it should display the item at that index.

EDIT: Try getting replacing event.target.scrollToIndex(i) (which should throw an error anyway) and replace it with event.stopImmediatePropagation(). This should prevent whatever the default key handler is from firing and overriding your event handler.

Upvotes: 1

Related Questions