actionscript – Deleting XML nodes from within a flex repeater doesn’t work? – Education Career Blog

I have the following repeater code:

<mx:Repeater id="chapterRepeater" dataProvider="{Library.Book.Chapter}">
   <mx:FormItem label="Chapter" direction="horizontal">
      <mx:TextInput  width="100" text="{ [email protected]}" 
                     change="event.currentTarget.getRepeaterItem()[email protected] = event.target.text"/>
      <mx:NumericStepper maximum="2000" minimum="0" value="{[email protected]}" 
                    change="event.currentTarget.getRepeaterItem()[email protected] = event.target.value"/>
      <mx:Button label="x" width="20" click="delete event.currentTarget.getRepeaterItem()"/>
  </mx:FormItem>
</mx:Repeater>

Acting on the following XML

<Library Name="TestLibrary1">
   <Book Name="TestBook1">
      <Chapter Name="TestChapter1" Words="530"/>
      <Chapter Name="TestChapter2" Words="490"/>
      <Chapter Name="TestChapter3" Words="1030"/>
   </Book>
</Library>

This allows the user to edit the names and values of the Chapter objects. However, the “delete” operation doesn’t work for some reason?

Can anyone advise me as to how to reference items within a repeater in order to delete them?

,

Hmmm… this one has taken me a while to at least get to some sort of solution for it. In your click event (and subsequently the change events on the text area and numericStepper) you access currentTarget. CurrentTarget will actually return a reference to the button itself. As it is a button and not a repeater getRepeaterItem() would not return anything. I’m actually surprised that calling getRepeatItem() hasn’t caused an error to be thrown. Needless to say that i don’t think they were updating the xml.

My solution externalises the FormItem into it’s own component (as that way, when click is fired i can bubble the event from the FormItem. That way i always know what formItem the event has come from) and then removes the item via an xmlListCollection.

So i have a separate component called ChapterFormItem.mxml which contains

<?xml version="1.0" encoding="utf-8"?>
<mx:FormItem xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
        <!CDATA
            private var _chapterData : XML;

            Bindable
            public function get chapterData() : XML
            {
                return _chapterData;
            }

            public function set chapterData(value : XML) : void
            {
                _chapterData = value;   
            }

            private function clickHandler(event : MouseEvent) : void
            {
                dispatchEvent(new Event("deleteChapter"));
            }

            private function textInputChangeHandler(event : Event) : void
            {
                [email protected] = textInput.text;
            }

            private function numericStepperChangeHandler(event : Event) : void
            {
                [email protected] = numericStepper.value;
            }
        >
    </mx:Script>

    <mx:Metadata>
        Event(name="deleteChapter", type="flash.events.Event")
    </mx:Metadata>

    <mx:TextInput id="textInput" width="100" text="{[email protected]}" change="textInputChangeHandler(event)"/>
    <mx:NumericStepper id="numericStepper" maximum="2000" minimum="0" value="{[email protected]}" change="numericStepperChangeHandler(event)"/>
    <mx:Button label="x" width="20" click="clickHandler(event)"/>
</mx:FormItem>

and in the main application xml (for this example) i have

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" xmlns:local="*">
    <mx:Script>
        <!CDATA
            import mx.collections.XMLListCollection;

        import mx.collections.ArrayCollection;

        Bindable
        private var xml:XML = <Library Name="TestLibrary1">
                                   <Book Name="TestBook1">
                                      <Chapter Name="TestChapter1" Words="530"/>
                                      <Chapter Name="TestChapter2" Words="490"/>
                                      <Chapter Name="TestChapter3" Words="1030"/>
                                   </Book>
                                </Library>;

        private function itemDeleteHandler(event : Event) : void
        {

            var chapterItem : ChapterFormItem = event.currentTarget as ChapterFormItem;
            var chapterData : XML = chapterItem.chapterData;


            var xmlListCollection : XMLListCollection = new XMLListCollection(xml.Book.Chapter);
            var chapterDataIndex : int = xmlListCollection.getItemIndex(chapterData);

            xmlListCollection.removeItemAt(chapterDataIndex);
        }

        >
    </mx:Script>

    <mx:Form width="100%" height="100%">

       <mx:Repeater id="chapterRepeater" dataProvider="{xml.Book.Chapter}">
          <local:ChapterFormItem label="Chapter" 
                                 direction="horizontal" 
                                 chapterData="{chapterRepeater.currentItem}"
                                 deleteChapter="itemDeleteHandler(event)"  />
        </mx:Repeater>

    </mx:Form>

</mx:Application>

Leave a Comment