views:

114

answers:

2

i created a form dynamically by adding each component in action script, now i want to get back the text/data entered in to that each component dynamically?

private function loadAllComponents():void
        {   
            var formItemArray:Array = new Array();   

            for(var i:int=0; i< Application.application.designList.length; i++)//which had the colonName, colComponet to be dispalyed,
            {
                var fm:FormItem = new FormItem();

                fm.label = Application.application.designList.getItemAt(i).colName;

                var comp:String = Application.application.designList.getItemAt(i).component;

                switch(comp)
                {
                    case "TextBox":
                        var ti:TextInput = new TextInput();
                        ti.id = Application.application.designList.getItemAt(i).component;
                        fm.addChild(ti);
                    break;

                    case "TextArea":
                        var ta:TextArea = new TextArea();
                        ta.id = Application.application.designList.getItemAt(i).colName;
                        fm.addChild(ta);                        
                    break;

                    case "ComboBox":

                        var mycb:myComboBox = new myComboBox();                                                     
                        mycb.getAllMasterCBData(Application.application.selectedgridItem, Application.application.designList.getItemAt(i).colName);                                                     
                        fm.addChild(mycb);

                    break;

                    case "DateField":
                        var df:DateField = new DateField();
                        df.id = Application.application.designList.getItemAt(i).component;
                        fm.addChild(df);
                    break;
                }
                myform.addChild(fm);                
            }

        }

    private function saveToDb():void // Here i wan to read all the formdata
    {               
        var formItems:Array = myform.getChildren();

        for each (var item:UIComponent in formItems)
        {   
            if (item is TextInput)
            {         
                var text:String = Object(item).text;    

                Alert.show("came here");      
            }
            else if (item is DateField)
            {
                var date:Date = DateField(item).selectedDate;                                   
            }
        }
    }

    ]]>
</mx:Script>

<mx:Form id="myform" cornerRadius="5" borderColor="#B7BABC" borderStyle="solid" width="100%" height="100%" />

<mx:HBox width="100%" height="100%" >
    <mx:Spacer width="120"/>
    <mx:Button label=" Save " id="saveBtn"  click="saveToDb()" />       
</mx:HBox>  
A: 

You're creating the input components in ActionScript, but based on this code you are not creating them dynamically; you're just hard coding them. With your given sample, you'll know the components you are creating at compile time.

You'll need to store a reference to the form items you create; make them public variables instead of 'var' local variables. Kind of like this:

protected var ti:TextInput ;       
protected var ta:TextArea ;        
protected var df:DateField;

Then in your creation method, do something like this:

ti = new TextInput();       
ti.id = Application.application.designList.getItemAt(i).component;
fm.addChild(ti);

ta  = new TextArea();        
ta.id = Application.application.designList.getItemAt(i).colName;
fm.addChild(ta);    

df = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
fm.addChild(df);

myform.addChild(fm); 

Then when you need to access them, just do something like this:

private function getMyformData()
{
       ti.text;
       ta.text;
}

If you're generating the form components at run time based on data, then store then form elements in an array of some sort.

You could also work something out by looping over all children of your container, although that wouldn't be my first approach.


Since poster posted more complete code; here are some additions. I added the protected array of all form items and in each 'switch' block; the new input element is pushed onto the array.

<mx:Script>
protected var itemsArray : Array = new Array();
private function loadAllComponents():void
    {   
        var formItemArray:Array = new Array();   

        for(var i:int=0; i< Application.application.designList.length; i++)//which had the colonName, colComponet to be dispalyed,
        {
            var fm:FormItem = new FormItem();

            fm.label = Application.application.designList.getItemAt(i).colName;

            var comp:String = Application.application.designList.getItemAt(i).component;

            switch(comp)
            {
                case "TextBox":
                    var ti:TextInput = new TextInput();
                    ti.id = Application.application.designList.getItemAt(i).component;
                    fm.addChild(ti);
                    itemsArray.push(ti)
                break;

                case "TextArea":
                    var ta:TextArea = new TextArea();
                    ta.id = Application.application.designList.getItemAt(i).colName;
                    fm.addChild(ta);                        
                    itemsArray.push(ta)
                break;

                case "ComboBox":

                    var mycb:myComboBox = new myComboBox();                                                     
                    mycb.getAllMasterCBData(Application.application.selectedgridItem, Application.application.designList.getItemAt(i).colName);                                                     
                    fm.addChild(mycb);
                    itemsArray.push(mycb)

                break;

                case "DateField":
                    var df:DateField = new DateField();
                    df.id = Application.application.designList.getItemAt(i).component;
                    fm.addChild(df);
                    itemsArray.push(df)
                break;
            }
            myform.addChild(fm);                
        }

    }

The sateToDb method will change to be something like this:

private function saveToDb():void // Here i wan to read all the formdata
{               
    var formItems:Array = myform.getChildren();

    for each (var item:UIComponent in itemsArray )
    {   
        if (item is TextInput)
        {         
            var text:String = Object(item).text;    

            Alert.show("came here");      
        }
        else if (item is DateField)
        {
            var date:Date = DateField(item).selectedDate;                                   
        }
    }
}

    ]]>
</mx:Script>
www.Flextras.com
please can u tell me clearly ?first i dont have reference to get those components except form name ?then how can i get all the data from all components which i added in run time ?
Thirst for Excellence
As I did in the code in my answer; make those form elements protected [or public or private] variables and the getMyFormData() method can access them by variable name. All components are, essentially, added at runtime and you can access them all the same way [by their variable identifier]
www.Flextras.com
@www.Flextras.com : Yah Just i posted all my exact code, can u review Once ?
Thirst for Excellence
Using Application.application is usually considered a bad practice because it adds dependencies to your component making it less reusable. Aside from that; as you create new items in loadAllComponents(); just store them in an array so you can access in saveToDb().
www.Flextras.com
I updated my answer as per your updated code.
www.Flextras.com
A: 

Edited Response:

OK, I think I see the issue.

You're adding your data controls to FormItems and adding those to the Form. But then you're iterating over the Form's children and as if they were the data controls and not FormItems.

Without commenting on the rest of the code, have a look at what this updated function is doing to retrieve the data controls:

      private function saveToDb():void
      {
           var formItems:Array = myform.getChildren();

           for each (var item:FormItem in formItems)
           {
                var itemChildren:Array = item.getChildren();
                for each (var control:UIComponent in itemChildren)
                {
                     if (control is TextInput)
                     {
                          var text:String = Object(item).text;
                          Alert.show("TextInput");
                     }
                     else if (control is DateField)
                     {
                          var date:Date = DateField(item).selectedDate;
                          Alert.show("Date");
                     }
                }
           }

You can delete the formItemArray variable too, it's not needed since we're getting the list of children from the Form and FormItems.


Original response:

If you keep a reference to each of the dynamic form items in an Array you can iterate over each of them in your getMyFormData() function.

e.g.

protected var formItems:Array = new Array();

// Other class stuff here...

var ti:TextInput = new TextInput();       
ti.id = Application.application.designList.getItemAt(i).component;
formItems.push(ti); // Add item to array.
fm.addChild(ti);

var ta:TextArea = new TextArea();        
ta.id = Application.application.designList.getItemAt(i).colName;
formItems.push(ta); // Add item to array.
fm.addChild(ta);    

var df:DateField = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
formItems.push(df); // Add item to array.
fm.addChild(df);

myform.addChild(fm); 


<mx:button click="getMyformData()"/>

private function getMyformData()
{
    //How to get the myform Data dynamically here after validations... ? & 
    for each (var item:UIComponent in formItems)
    {
        if (item is TextInput || item is TextArea)
        {
            // Cast to Object to access the 'text' property without the compiler complaining.
            var text:String = Object(item).text;
            // Do something with the text...
        }
        else if (item is DateField)
        {
            var date:Date = DateField(item).selectedDate;
            // Do something with the date...
        }
        // Insert additional type checks as needed.
    }
}

You'll have to work out what to do with the data on your own though :)

If you are using a separate list make sure you clear out the formItems array when you're done with it so you don't have references to the items keeping them in memory unnecessarily.

Instead of keeping a separate array of form items you could also iterate over the children in the fm container. You might have to make some assumptions about the children you'd be accessing but it looks like you have control over all of the children being added so that's no problem.

I hope that helps...

:)

Sly_cardinal
Thirst for Excellence
You need to make sure the `formItems` array remains in scope. Can you post a more specific example? The example above requires too many assumptions about the strucutre of the project to be able to determine the issue properly.
Sly_cardinal
@Sly_Cardinal : Yah Just i posted all my exact code, can u review Once ?
Thirst for Excellence