user346077
user346077

Reputation:

in combobox editable text how to control Cursor position using actionscript3?

I have a class which inherit from ComboBox .i want to implement a function to control the position of the cursor.Any builtin function? thanks in advance

////////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2003-2006 Adobe Macromedia Software LLC and its licensors.
//  All Rights Reserved. The following is Source Code and is subject to all
//  restrictions on such code as contained in the End User License Agreement
//  accompanying this product.
//
////////////////////////////////////////////////////////////////////////////////

package ac
{
    import flash.events.KeyboardEvent;
    import flash.events.Event;
    import flash.events.FocusEvent;
    import flash.net.SharedObject;
    import flash.ui.Keyboard;
    import mx.core.UIComponent;
    import mx.controls.ComboBox;
    import mx.collections.ArrayCollection;
    import mx.collections.ListCollectionView;


    //--------------------------------------
    //  Events
    //--------------------------------------

    /**
     *  Dispatched when the <code>filterFunction</code> property changes.
     *
     *  You can listen for this event and update the component
     *  when the <code>filterFunction</code> property changes.</p>
     * 
     *  @eventType flash.events.Event
     */
    [Event(name="filterFunctionChange", type="flash.events.Event")]

    /**
     *  Dispatched when the <code>typedText</code> property changes.
     *
     *  You can listen for this event and update the component
     *  when the <code>typedText</code> property changes.</p>
     * 
     *  @eventType flash.events.Event
     */
    [Event(name="typedTextChange", type="flash.events.Event")]

    //--------------------------------------
    //  Excluded APIs
    //--------------------------------------

    [Exclude(name="editable", kind="property")]

    /**
     *  The AutoComplete control is an enhanced 
     *  TextInput control which pops up a list of suggestions 
     *  based on characters entered by the user. These suggestions
     *  are to be provided by setting the <code>dataProvider
     *  </code> property of the control.
     *  @mxml
     *
     *  <p>The <code>&lt;fc:AutoComplete&gt;</code> tag inherits all the tag attributes
     *  of its superclass, and adds the following tag attributes:</p>
     *
     *  <pre>
     *  &lt;fc:AutoComplete
     *    <b>Properties</b>
     *    keepLocalHistory="false"
     *    lookAhead="false"
     *    typedText=""
     *    filterFunction="<i>Internal filter function</i>"
     *
     *    <b>Events</b>
     *    filterFunctionChange="<i>No default</i>"
     *    typedTextChange="<i>No default</i>"
     *  /&gt;
     *  </pre>
     *
     *  @includeExample ../../../../../../docs/com/adobe/flex/extras/controls/example/AutoCompleteCountriesData/AutoCompleteCountriesData.mxml
     *
     *  @see mx.controls.ComboBox
     *
     */
    public class AutoComplete extends ComboBox 
    {

        //--------------------------------------------------------------------------
        //
        //  Constructor
        //
        //--------------------------------------------------------------------------

        /**
         *  Constructor.
         */
        public function AutoComplete()
        {
            super();

            //Make ComboBox look like a normal text field
            editable = true;
            if(keepLocalHistory)
                addEventListener("focusOut",focusOutHandler);

            setStyle("arrowButtonWidth",0);
            setStyle("fontWeight","normal");
            setStyle("cornerRadius",0);
            setStyle("paddingLeft",0);
            setStyle("paddingRight",0);
            rowCount = 7;
        }

        //--------------------------------------------------------------------------
        //
        //  Variables
        //
        //--------------------------------------------------------------------------

        /**
         *  @private
         */
        private var cursorPosition:Number=0;

        /**
         *  @private
         */
        private var prevIndex:Number = -1;

        /**
         *  @private
         */
        private var removeHighlight:Boolean = false;    

        /**
         *  @private
         */
        private var showDropdown:Boolean=false;

        /**
         *  @private
         */
        private var showingDropdown:Boolean=false;

        /**
         *  @private
         */
        private var tempCollection:Object;

        /**
         *  @private
         */
        private var usingLocalHistory:Boolean=false;

        /**
         *  @private
         */
        private var dropdownClosed:Boolean=true;

        //--------------------------------------------------------------------------
        //
        //  Overridden Properties
        //
        //--------------------------------------------------------------------------

        //----------------------------------
        //  editable
        //----------------------------------
        /**
         *  @private
         */
        override public function set editable(value:Boolean):void
        {
            //This is done to prevent user from resetting the value to false
            super.editable = true;
        }
        /**
         *  @private
         */
        override public function set dataProvider(value:Object):void
        {
            super.dataProvider = value;
            if(!usingLocalHistory)
                tempCollection = value;
        }

        //----------------------------------
        //  labelField
        //----------------------------------
        /**
         *  @private
         */
        override public function set labelField(value:String):void
        {
            super.labelField = value;

            invalidateProperties();
            invalidateDisplayList();
        }


        //--------------------------------------------------------------------------
        //
        //  Properties
        //
        //--------------------------------------------------------------------------


        //----------------------------------
        //  filterFunction
        //----------------------------------

        /**
         *  @private
         *  Storage for the filterFunction property.
         */
        private var _filterFunction:Function = defaultFilterFunction;

        /**
         *  @private
         */
        private var filterFunctionChanged:Boolean = true;

        [Bindable("filterFunctionChange")]
        [Inspectable(category="General")]

        /**
         *  A function that is used to select items that match the
         *  function's criteria. 
         *  A filterFunction is expected to have the following signature:
         *
         *  <pre>f(item:~~, text:String):Boolean</pre>
         *
         *  where the return value is <code>true</code> if the specified item
         *  should displayed as a suggestion. 
         *  Whenever there is a change in text in the AutoComplete control, this 
         *  filterFunction is run on each item in the <code>dataProvider</code>.
         *  
         *  <p>The default implementation for filterFunction works as follows:<br>
         *  If "AB" has been typed, it will display all the items matching 
         *  "AB~~" (ABaa, ABcc, abAc etc.).</p>
         *
         *  <p>An example usage of a customized filterFunction is when text typed
         *  is a regular expression and we want to display all the
         *  items which come in the set.</p>
         *
         *  @example
         *  <pre>
         *  public function myFilterFunction(item:~~, text:String):Boolean
         *  {
         *     public var regExp:RegExp = new RegExp(text,"");
         *     return regExp.test(item);
         *  }
         *  </pre>
         *
         */
        public function get filterFunction():Function
        {
            return _filterFunction;
        }

        /**
         *  @private
         */
        public function set filterFunction(value:Function):void
        {
            //An empty filterFunction is allowed but not a null filterFunction
            if(value!=null)
            {
                _filterFunction = value;
                filterFunctionChanged = true;

                invalidateProperties();
                invalidateDisplayList();

                dispatchEvent(new Event("filterFunctionChange"));
            }
            else
                _filterFunction = defaultFilterFunction;
        }

        //----------------------------------
        //  filterFunction
        //----------------------------------

        /**
         *  @private
         *  Storage for the keepLocalHistory property.
         */
        private var _keepLocalHistory:Boolean = false;

        /**
         *  @private
         */
        private var keepLocalHistoryChanged:Boolean = true;

        [Bindable("keepLocalHistoryChange")]
        [Inspectable(category="General")]

        /**
         *  When true, this causes the control to keep track of the
         *  entries that are typed into the control, and saves the
         *  history as a local shared object. When true, the
         *  completionFunction and dataProvider are ignored.
         *
         *  @default "false"
         */
        public function get keepLocalHistory():Boolean
        {
            return _keepLocalHistory;
        }

        /**
         *  @private
         */
        public function set keepLocalHistory(value:Boolean):void
        {
            _keepLocalHistory = value;
        }

        //----------------------------------
        //  lookAhead
        //----------------------------------

        /**
         *  @private
         *  Storage for the lookAhead property.
         */
        private var _lookAhead:Boolean=false;

        /**
         *  @private
         */
        private var lookAheadChanged:Boolean;

        [Bindable("lookAheadChange")]
        [Inspectable(category="Data")]

        /**
         *  lookAhead decides whether to auto complete the text in the text field
         *  with the first item in the drop down list or not. 
         *
         *  @default "false"
         */
        public function get lookAhead():Boolean
        {
            return _lookAhead;
        }

        /**
         *  @private
         */
        public function set lookAhead(value:Boolean):void
        {
            _lookAhead = value;
            lookAheadChanged = true;
        }

        //----------------------------------
        //  typedText
        //----------------------------------

        /**
         *  @private
         *  Storage for the typedText property.
         */
        private var _typedText:String="";
        /**
         *  @private
         */
        private var typedTextChanged:Boolean;

        [Bindable("typedTextChange")]
        [Inspectable(category="Data")]

        /**
         *  A String to keep track of the text changed as 
         *  a result of user interaction.
         */
        public function get typedText():String
        {
            return _typedText;
        }

        /**
         *  @private
         */
        public function set typedText(input:String):void
        {
            _typedText = input;
            typedTextChanged = true;

            invalidateProperties();
            invalidateDisplayList();
            dispatchEvent(new Event("typedTextChange"));
        }

        //--------------------------------------------------------------------------
        //
        //  Overridden methods
        //
        //--------------------------------------------------------------------------

        /**
         *  @private
         */
        override protected function commitProperties():void
        {
            super.commitProperties();

            if(!dropdown)
                selectedIndex=-1;

            if(dropdown)
            {
                if(typedTextChanged)
                {
                    cursorPosition = textInput.selectionActivePosition;//mansoor change: selectionBeginIndex;

                    updateDataProvider();

                    //In case there are no suggestions there is no need to show the dropdown
                    if(collection.length==0 || typedText==""|| typedText==null)
                    {
                        dropdownClosed=true;
                        showDropdown=false;
                    }
                    else
                    {
                        showDropdown = true;
                        selectedIndex = 0;
                    }
                }
            }
        }

        /**
         *  @private
         */
        override protected function focusOutHandler(event:FocusEvent):void
        {
            super.focusOutHandler(event)
            if(keepLocalHistory && dataProvider.length==0)
                addToLocalHistory();
        }
        /**
         *  @private
         */
        override public function getStyle(styleProp:String):*
        {
            if(styleProp != "openDuration")
                return super.getStyle(styleProp);
            else
            {
                if(dropdownClosed)
                    return super.getStyle(styleProp);
                else
                    return 0;
            }
        }
        /**
         *  @private
         */
        override protected function keyDownHandler(event:KeyboardEvent):void
        {
            super.keyDownHandler(event);

            if(!event.ctrlKey)
            {
                //An UP "keydown" event on the top-most item in the drop-down
                //or an ESCAPE "keydown" event should change the text in text
                // field to original text
                if(event.keyCode == Keyboard.UP && prevIndex==0)
                {
                    textInput.text = _typedText;
                    textInput.selectRange(textInput.text.length, textInput.text.length);//mansoor: setSelection(textInput.text.length, textInput.text.length);
                    selectedIndex = -1; 
                }
                else if(event.keyCode==Keyboard.ESCAPE && showingDropdown)
                {
                    textInput.text = _typedText;
                    textInput.selectRange(textInput.text.length, textInput.text.length);// mansoor: setSelection(textInput.text.length, textInput.text.length);
                    showingDropdown = false;
                    dropdownClosed=true;
                }
                else if(event.keyCode == Keyboard.ENTER)
                {
                    if(keepLocalHistory && dataProvider.length==0)
                        addToLocalHistory();
                }
                else if(lookAhead && event.keyCode ==  Keyboard.BACKSPACE 
                    || event.keyCode == Keyboard.DELETE)
                    removeHighlight = true;
            }
            else
                if(event.ctrlKey && event.keyCode == Keyboard.UP)
                    dropdownClosed=true;

            prevIndex = selectedIndex;
        }

        /**
         *  @private
         */
        override protected function measure():void
        {
            super.measure();
            measuredWidth = mx.core.UIComponent.DEFAULT_MEASURED_WIDTH;
        }

        /**
         *  @private
         */
        override protected function updateDisplayList(unscaledWidth:Number, 
                                                      unscaledHeight:Number):void
        {

            super.updateDisplayList(unscaledWidth, unscaledHeight);

            //An UP "keydown" event on the top-most item in the drop 
            //down list otherwise changes the text in the text field to ""
            if(selectedIndex == -1)
                textInput.text = typedText;

            if(dropdown)
            {
                if(typedTextChanged)
                {
                    //This is needed because a call to super.updateDisplayList() set the text
                    // in the textInput to "" and thus the value 
                    //typed by the user losts
                    if(lookAhead && showDropdown && typedText!="" && !removeHighlight)
                    {
                        var label:String = itemToLabel(collection[0]);
                        var index:Number =  label.toLowerCase().indexOf(_typedText.toLowerCase());
                        if(index==0)
                        {
                            textInput.text = _typedText+label.substr(_typedText.length);
                            textInput.selectRange(textInput.text.length,_typedText.length);//setSelection(textInput.text.length,_typedText.length);
                        }
                        else
                        {
                            textInput.text = _typedText;
                            textInput.selectRange(cursorPosition, cursorPosition);
                            removeHighlight = false;
                        }

                    }
                    else
                    {
                        textInput.text = _typedText;
                        textInput.selectRange(cursorPosition, cursorPosition);
                        removeHighlight = false;
                    }

                    typedTextChanged= false;
                }
                else if(typedText)
                    //Sets the selection when user navigates the suggestion list through
                    //arrows keys.
                    textInput.selectRange(_typedText.length,textInput.text.length);
            }
            if(showDropdown && !dropdown.visible)
            {
                //This is needed to control the open duration of the dropdown
                super.open();
                showDropdown = false;
                showingDropdown = true;

                if(dropdownClosed)
                    dropdownClosed=false;
            }
        }


        /**
         *  @private
         */
        override protected function textInput_changeHandler(event:Event):void
        {
            super.textInput_changeHandler(event);
            //Stores the text typed by the user in a variable
            typedText=text;
        }

        //--------------------------------------------------------------------------
        //
        //  Methods
        //
        //--------------------------------------------------------------------------

        /**
         *  @private
         *  If keepLocalHistory is enabled, stores the text typed 
         *     by the user in the local history on the client machine
         */
        private function addToLocalHistory():void
        {
            if (id != null && id != "" && text != null && text != "")
            {
                var so:SharedObject = SharedObject.getLocal("AutoCompleteData");

                var savedData : Array = so.data.suggestions;
                //No shared object has been created so far
                if (savedData == null)
                    savedData = new Array();

                var i:Number=0;
                var flag:Boolean=false;
                //Check if this entry is there in the previously saved shared object data
                for(i=0;i<savedData.length;i++)
                    if(savedData[i]==text)
                    {
                        flag=true;
                        break;
                    }
                if(!flag)
                {
                    //Also ensure it is not there in the dataProvider
                    for(i=0;i<collection.length;i++)
                        if(defaultFilterFunction(itemToLabel(ListCollectionView(collection).getItemAt(i)),text))
                        {
                            flag=true;
                            break;
                        }
                }
                if(!flag)
                    savedData.push(text);

                so.data.suggestions = savedData;
                //write the shared object in the .sol file
                so.flush();
            }
        }    
        /**
         *  @private
         */
        private function defaultFilterFunction(element:*, text:String):Boolean 
        {
            var label:String = itemToLabel(element);

            return (label.toLowerCase().substring(0,text.length) == text.toLowerCase());
        }
        /**
         *  @private
         */

        private function templateFilterFunction(element:*):Boolean 
        {
            var flag:Boolean=false;
            if(filterFunction!=null)
                flag=filterFunction(element,typedText);
            return flag;
        }

        /**
         *  @private
         *  Updates the dataProvider used for showing suggestions
         */
        private function updateDataProvider():void
        {
            dataProvider = tempCollection;
            collection.filterFunction = templateFilterFunction;
            collection.refresh();

            //In case there are no suggestions, check there is something in the localHistory
            if(collection.length==0 && keepLocalHistory)
            {
                var so:SharedObject = SharedObject.getLocal("AutoCompleteData");
                usingLocalHistory = true;
                dataProvider = so.data.suggestions;
                usingLocalHistory = false;
                collection.filterFunction = templateFilterFunction;
                collection.refresh();
            }
        }
    }    
}

Upvotes: 0

Views: 2143

Answers (2)

user346077
user346077

Reputation:

Ever one can check a complete example.A component demo http://flashcommander.org/blog/flex-4-autocomplete

Upvotes: 0

poke
poke

Reputation: 388273

That's not possible with Flash. All you could do would be to listen for key events and instead of allowing the user to normally write, intercept it and add the character for the pressed key at your desired location.

Upvotes: 1

Related Questions