« Return to Thread: Handling unspecified number of sub-forms with Zend_Form

Re: Handling unspecified number of sub-forms with Zend_Form

by Julian Davchev :: Rate this Message:

Reply to Author | View in Thread

Hi, little code I'd like to share...hopefully you find it useful.
I had similer issue lately. Basically you build your forms like
[stuff1][field] .....[stuff2][field]    etc etc......     with
javascript (I used ajax).

I just assign on rendering the view..  variable with current number of
subforms... then on each ajax call
I just increment this javascript variable (it doesn't need to be
sequential at all)...just increment each time.
So I know that it returns nonconficting [stuffN][field] - For the ajax
returning I use ::assignSubForm() method mentioned
below and just echo $main_form->$subFormName


Then on post you have stuff like  [stuff1][field]
..[stuff132][field]...[stuff2][field]    etc...

//I got some specifics on decorators..you can ignore them... I am using
view script decorator for rending....thats why
//have to use assignBelongsTo()  probably can ignore this too in your
scenario

So you have two cases:
1.  When you have to build form based on request data... (because stuff
dynamiccally piles in there)
2.  When you have to build form based on db data... (regular scenario)

$foo =
Form_Abstract::buildSubFormFromRequest($request,'Form_Subform_Something','something');
$formContainingSubForms = $foo['form_container'];
$subFormNames = $foo['subFormNames']; //in case we want to address one
by one e.g $formContaintingSubForms->something1

Not really sure what you mean by second level of subforms..... I was
thinking of doing
stuff[1][field] stuff[2][field]    etc...    so you take directly stuff
later...but found issues with rendering just one element
$mainForm->stuff->"1"  would not render stuff[1][field] as it doesn't
see whole decorator level and renders not as expected.

Form_Abstract{

public static function
buildSubFormFromRequest($request,$subFormClass,$subFormName)
    {
        $form_container = new Zend_Form();
        $form_container->setDecorators(array('FormElements'));
        $names = array();
        $params = $request->getParams();
        foreach ($params as $index => $param) {
            if (preg_match("#^{$subFormName}\d+$#",$index)) {
               
Form_Abstract::assignSubForm($form_container,$subFormClass,null,array($index=>$param));
                $names[] = $index;
            }
        }
        return array ('form_container' => $form_container,'subFormNames'
=> $names);
    }

    public static function
assignSubForm($mainForm,$subFormClass,$subformName,$assignData = null)
    {
        if (!$assignData) {
            $subForm = new $subFormClass();
            $subForm->assignBelongsTo($subformName);
            $subForm->removeDecorator('form');
            $mainForm->addSubForm($subForm, $subformName);
        } else {
            foreach ($assignData as $subName => $subFormData) {
                $subForm = new $subFormClass();
                $subForm->assignBelongsTo($subName);
                $subForm->removeDecorator('form');
                $subForm->setDefaults($subFormData);
                $mainForm->addSubForm($subForm, $subName);
            }
        }
    }
}

Matthew Weier O'Phinney wrote:

> -- Sagi Bashari <sagi@...> wrote
> (on Tuesday, 01 July 2008, 02:31 PM +0300):
>  
>> I can add a counter, but I can't see a good use for it - its value should be
>> identical to count($_POST['features']).
>>
>> And I will have to iterate over the features anyway to add the second level of
>> sub-forms (ItemForm).
>>    
>
> This sounds like a reasonable solution to me, actually.
>
>
>  
>> On Tue, Jul 1, 2008 at 2:10 PM, Bart McLeod <mcleod@...> wrote:
>>
>>     I would do like you do, inspect the post data. However, it would be nice if
>>     you would just have to know the number of subforms you are processing.
>>     Javascript can easily update a counter in a hidden field on your mainform.
>>     It increments the count each time you add a subform dynamically. This
>>     counter is the only post element you will have to evaluate in order to know
>>     how many subforms to process.
>>
>>     Bart McLeod
>>
>>     Sagi Bashari schreef:
>>
>>
>>         Hello,
>>
>>         I have a form that can generate any number of input fields dynamically
>>         (the fields are generated using javascript).
>>
>>         The fields have some nested sub-form structure:
>>         1. There can be many "feature" forms, and each has a name: features
>>         [feature0,..,featureN][name]
>>         2. Each of these feature forms has many items, and each item has a
>>         name: features[feature0][items][item0,..,itemN][name]
>>
>>         (Actually they have many other fields except the name but this is
>>         enough for the example).
>>
>>         I managed to handle a static number of such sub-forms with Zend_Form,
>>         by attaching multiple instances of a FeatureForm to my main form, and
>>         attaching multiple instances of ItemForm to the FeatureForm (inside a
>>         container sub-form).
>>
>>         However, I wonder how can I add these sub-forms dynamically.
>>
>>         I thought about creating some pre-processing method that will get the
>>         $_POST data, inspect it and add fields accordingly before calling
>>         isValid().
>>
>>         Can anyone think of a better (more Zend_Form-like) way of handling such
>>         situation?
>>
>>         Thanks,
>>         Sagi
>>
>>
>>    
>
>  

 « Return to Thread: Handling unspecified number of sub-forms with Zend_Form