0
votes

I have a Custom Spark ComboBox which contains a list of items. I want to Add a new Item to the ComboBox stating the text "Add new Item", which on selecting popup a window to do some operations.

I have achieved this by creating a new object of the same type of the entities in the data provider, with the LabelField of the new object having the text "Add new Item". I have override the set dataProvider method and in the custom combobox.

But this adds the values to the Actual List which is binded to the DataProvider. The list is used in the business logics. So i do not want this to happen. I have lot of Entity Classes. i could not change all the objects.

All i want is to achieve the same functionality in my custom component without changing the other code. I have also tried to create a new instance of dataProvier but i noticed that the binding of the List and dataprovider is lost when i created a new instance.

Kindly help.!!

Edited:

ExtendedComboBox.as

package components

{ import flash.utils.getDefinitionByName;

import mx.collections.ArrayCollection;
import mx.collections.IList;

import spark.components.ComboBox;
import spark.events.DropDownEvent;

public class ExtendedComboBox extends ComboBox
{

    private var _addItem:Boolean = false;
    private var _addItemLabel:String = "Create New Item" ;
    private var _dropDownClass:String = null ;
    private var originalDP:IList ;
    private var dpEdited:Boolean = false;

    public function ExtendedComboBox()
    {
        super();
        this.addItem = true;
        this.addEventListener(DropDownEvent.CLOSE, dropDownCloseEventListner );
        this.addEventListener(DropDownEvent.OPEN, openDropDownEvent );
    }

    public function get dropDownClass():String
    {
        return _dropDownClass;
    }

    public function set dropDownClass(value:String):void
    {
        _dropDownClass = value;
    }

    public function get addItemLabel():String
    {
        return _addItemLabel;
    }

    public function set addItemLabel(value:String):void
    {
        _addItemLabel = value;
    }

    public function get addItem():Boolean
    {
        return _addItem;
    }

    public function set addItem(value:Boolean):void
    {
        _addItem = value;
    }

    private function dropDownCloseEventListner(event:DropDownEvent):void{

    }

    protected function openDropDownEvent(event:DropDownEvent):void{
        if(addItem)
        {
            //  if(value) value = new ArrayCollection();
            var value:IList  ; 
            if(originalDP == null)  value = new ArrayCollection ;
            else value = new ArrayCollection( originalDP.toArray() ) ;
            var tempObj:Object;
            var createItemPresent:Boolean =false ;
            if(dropDownClass != null)           
            {
                var TempClass = flash.utils.getDefinitionByName(dropDownClass) as Class;
                tempObj = new TempClass();
                if(value.length >0)
                {
                //  trace(value.getChildAt(0)[this.labelField]) ;
                    if(value.getItemAt(0)[this.labelField] == addItemLabel)
                        createItemPresent = true ;
                }
                if(!createItemPresent)
                {
                    tempObj[this.labelField] = addItemLabel ;
                    var sort = (value as ArrayCollection).sort ;
                    value.addItemAt(tempObj, 0);
                    (value as ArrayCollection).sort = sort ;
                    dpEdited = true;
                }
            }
        }
        super.dataProvider = value;
    }

    override public function set dataProvider(value:IList):void{
        if(!dpEdited)
        {
            originalDP = value;
            dpEdited = true;
        }

        /*if(addItem)
        {
        //  if(value) value = new ArrayCollection();
            var tempObj:Object;
            var createItemPresent:Boolean =false ;
            if(dropDownClass != null)           
            {
                var TempClass = flash.utils.getDefinitionByName(dropDownClass) as Class;
                tempObj = new TempClass();
                if(value.length >0)
                {
                    if(value.getItemIndex(0)[this.labelField] == addItemLabel)
                        createItemPresent = true ;
                }
                if(!createItemPresent)
                {
                tempObj[this.labelField] = addItemLabel ;
                var sort = (value as ArrayCollection).sort ;
                value.addItemAt(tempObj, 0);
                (value as ArrayCollection).sort = sort ;
                }
            }
        }*/
        super.dataProvider = value;
    }
}

}

MyEntityObj.as

package entity

{ public class MyEntityObj { private var _name:String ; private var _age:int ; private var _company:String;

    public function MyEntityObj()
    {
    }

    public function get company():String
    {
        return _company;
    }

    public function set company(value:String):void
    {
        _company = value;
    }

    public function get age():int
    {
        return _age;
    }

    public function set age(value:int):void
    {
        _age = value;
    }

    public function get name():String
    {
        return _name;
    }

    public function set name(value:String):void
    {
        _name = value;
    }

}

}

And Implementation Sample - ComboImpl.mxml

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

        import mx.collections.ArrayCollection;
        import mx.events.CollectionEvent;
        import mx.events.FlexEvent;

        [Bindable]
        private var samplDP:ArrayCollection;

        protected function application1_initializeHandler(event:FlexEvent):void
        {
            samplDP = new ArrayCollection ;
            samplDP.addEventListener(CollectionEvent.COLLECTION_CHANGE, changeHandlerFunc );
            var sampVO:MyEntityObj;
            for(var i:int = 0; i<5;i++)
            {
                sampVO = new MyEntityObj;
                sampVO.name = "Name " + i;
                sampVO.age = i;
                sampVO.company = "Company " + i;
                samplDP.addItem(sampVO);
            }
        }

        protected function changeHandlerFunc(event:CollectionEvent):void{
            var nameList:String = "" ;
            for each(var myObj:* in samplDP)
            {
                nameList += myObj.name + ", " ;
            }
            changeHandler.text = nameList ;
        }

    ]]>
</fx:Script>
<fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:VGroup>
    <s:Label id="changeHandler" />  
    <components:ExtendedComboBox dataProvider="{samplDP}" labelField="name" addItem="true" dropDownClass="entity.MyEntityObj" addItemLabel="Create Sample" />
</s:VGroup>

As commented in the set DataProvider Overridden method and the in the DropDownClose events addition of the new item directly affects the original List. i do not want this to happen.

Note that its just a sample implementation. The component creation in my project actually happens in the action script class dynamically.

Kindly help.!!

1
You can do this with extending the component, but I need to see what you're doing so far. You simply need to override the getters and setters to omit that value and make a custom method that will return the data with it when you need it (which is probably only in a couple places).Nate
I've first override the set dataprovider method, but doing so add the element to the original ArrayCollection, also when the dataprovider is set using binding utils from .as the overridden method is not called if there is no data in it.Prakashm88
Hi Nate, kindly check the code and comment it.Prakashm88

1 Answers

0
votes

It sounds to me like:

You're going to have to extend the ComboBox (If you drill down into how it's implemented, possibly the DataGroup) to include your extra "Add New Item" item w/o it being in the dataProvider.

I expect this to be very difficult, but have not reviewed the code for this purpose.