Zend Form with Subforms causing the submit button to stop working

974 Views Asked by At

I have a form which has 3 subforms inserted into it. If needed I can post the code of how it builds these subforms but since it pretty huge all together I'll just put most relevant parts here.

Firstly the form's init() function:

public function init() {

        $redirect = new Zend_Form_Element_Hidden('redirect');

        $categories = new HPU_Form_Element_TreeView('tree');
        $categories->setMultiOptions($this->categoryList);
        $categories->setLabel('Home')
                    ->setValue($this->selectedCategoryList)
                    ->setRequired(true);

        $id = new Zend_Form_Element_Hidden('id');
        $id->addFilter('Int');

        $title = new Zend_Form_Element_Text('title');
        $title->setLabel('Title')
                ->setRequired(true);

        $subtitle = new Zend_Form_Element_Text('subtitle');
        $subtitle->setLabel('Subtitle')
                    ->setRequired(true);

        $language_id = new Zend_Form_Element_Select("language_id");
        $language_id->setLabel('Language')
                    ->setRequired(true)
                    ->addMultiOption( "" , "Choose a language");

        $table = new Content_Model_DbTable_Language();
        foreach ($table->fetchAll() as $language) {
            $language_id->addMultiOption($language->id, $language->name);
        }

        $start_date = new ZendX_JQuery_Form_Element_DatePicker('start_date');
        $start_date->setLabel('Start date')
                    ->setValue(date('j-m-Y'))
                    ->setRequired(true)
                    ->setAttrib('jQueryParams', array('dateFormat' => 'dd-mm-yy'));

        $expiration_date = new ZendX_JQuery_Form_Element_DatePicker('expiration_date'); 
        $expiration_date->setLabel('Expiration date')
                        ->setAttrib('jQueryParams', array('dateFormat' => 'dd-mm-yy'));

        $status = new Zend_Form_Element_Select("status");
        $status->setLabel('Status')
                ->setRequired(true)
                ->addMultiOptions(array("1" => "Concept", "2" => "Ready to publish", "3" => "Published",
                "4" => "Offline"));

        $meta_description = new Zend_Form_Element_Textarea('meta_description'); 
        $meta_description->setLabel('Meta description')
                            ->setAttrib('rows', '4');

        $meta_keywords = new Zend_Form_Element_Textarea('meta_keywords'); 
        $meta_keywords->setLabel('Meta keywords')
                        ->setAttrib('rows', '4');

        $introductory_text = new HPU_Form_Element_Tinymce('introductory_text'); 
        $introductory_text->setLabel('Introductory text');

        $content_text = new HPU_Form_Element_Tinymce('content_text'); 
        $content_text->setLabel('Follow up text');

        $submit_button = new Zend_Form_Element_Submit('submit_button');

        $this->setDecorators(array('ViewHelper'));
        $this->setElementDecorators(array('ViewHelper'));
        $this->setDecorators(array('FormElements', 'Form'));

        $this->addElements(array($redirect, $categories, $id, $title, $subtitle, $language_id, $start_date, $expiration_date, $status));

        $this->addEnclosedItems();
        $this->addEyecatcher();
        $this->addYoutubeItems();

        $this->addElements(array($meta_description, $meta_keywords, $introductory_text, $content_text, $submit_button));

    }

As you can see I declare a number of elements and then add them to the form using the addElements() function. However I have split this up into two parts since I wanted my 3 subforms (which are created by their respective functions addEnclosedItems(), addYoutubeItems(), addEyecatchers() and then I add the last part of the elements.

As a result I get the following HTML:

<form id="content" enctype="multipart/form-data" action="" method="post">

<dt id="redirect-label">&#160;</dt>

<dd id="redirect-element">

<input type="hidden" name="redirect" value="" id="redirect" /></dd>

<dt id="tree-label"><label for="tree" class="required">Home</label></dt>

<dd id="tree-element">

<ul id="tree"><li><input  value="72" id="tree-72" name="tree[]" type="hidden" /><label for="tree-72" class="parent">Test Categorie 1</label><ul id="tree"><li><input checked="checked" value="75" id="tree-75" name="tree[]" type="checkbox" /><label for="tree-75" class="child">Test Categorie 1.1</label></li><li><input  value="76" id="tree-76" name="tree[]" type="checkbox" /><label for="tree-76" class="child">Test Categorie 1.2</label></li></ul></li><li><input  value="73" id="tree-73" name="tree[]" type="hidden" /><label for="tree-73" class="parent">Test Categorie 2</label><ul id="tree"><li><input  value="77" id="tree-77" name="tree[]" type="hidden" /><label for="tree-77" class="parent">Test Categorie 2.1</label><ul id="tree"><li><input  value="80" id="tree-80" name="tree[]" type="checkbox" /><label for="tree-80" class="child">Test category 2.1.1</label></li></ul></li><li><input checked="checked" value="78" id="tree-78" name="tree[]" type="checkbox" /><label for="tree-78" class="child">Test Categorie 2.2</label></li><li><input  value="79" id="tree-79" name="tree[]" type="checkbox" /><label for="tree-79" class="child">Test Categorie 2.3</label></li></ul></li><li><input  value="74" id="tree-74" name="tree[]" type="checkbox" /><label for="tree-74" class="child">Test Categorie 3</label></li><li><input  value="86" id="tree-86" name="tree[]" type="hidden" /><label for="tree-86" class="parent">Test Category 4</label><ul id="tree"><li><input  value="87" id="tree-87" name="tree[]" type="checkbox" /><label for="tree-87" class="child">Test Category 4.1</label></li></ul></li></ul></dd>

<dt id="id-label">&#160;</dt>

<dd id="id-element">

<input type="hidden" name="id" value="57" id="id" /></dd>

<dt id="title-label"><label for="title" class="required">Title</label></dt>

<dd id="title-element">

<input type="text" name="title" id="title" value="Test Content 2" /></dd>

<dt id="subtitle-label"><label for="subtitle" class="required">Subtitle</label></dt>

<dd id="subtitle-element">

<input type="text" name="subtitle" id="subtitle" value="Test Content 2" /></dd>

<dt id="language_id-label"><label for="language_id" class="required">Language</label></dt>

<dd id="language_id-element">

<select name="language_id" id="language_id">
    <option value="" label="Choose a language">Choose a language</option>
    <option value="1" label="Dutch" selected="selected">Dutch</option>
    <option value="2" label="Russian">Russian</option>
</select></dd>

<dt id="start_date-label"><label for="start_date" class="required">Start date</label></dt>

<dd>

<input type="text" name="start_date" id="start_date" value="0000-00-00 00:00:00" /></dd>

<dt id="expiration_date-label"><label for="expiration_date" class="optional">Expiration date</label></dt>

<dd>

<input type="text" name="expiration_date" id="expiration_date" value="0000-00-00 00:00:00" /></dd>

<dt id="status-label"><label for="status" class="required">Status</label></dt>

<dd id="status-element">

<select name="status" id="status">
    <option value="1" label="Concept" selected="selected">Concept</option>
    <option value="2" label="Ready to publish">Ready to publish</option>
    <option value="3" label="Published">Published</option>
    <option value="4" label="Offline">Offline</option>
</select></dd>

<dt id="enclosedItem-label">&#160;</dt><dd id="enclosedItem-element"><fieldset id="fieldset-enclosedItem"><dl>

<dt id="addEnclosedItem-label">&#160;</dt><dd id="addEnclosedItem-element">

<button name="enclosedItem[addEnclosedItem]" id="enclosedItem-addEnclosedItem" type="button">add enclosed item</button></dd></dl></fieldset></dd>

<div class="eyecatcher_item"><form id="eyecatcher" enctype="application/x-www-form-urlencoded" action="" method="post">

<dt id="eyecatcher-eyecatcher-label">&#160;</dt>

<dd id="eyecatcher-eyecatcher-element">

<img src='/fm/Tulips.jpg'/></dd>

<dt id="deleteEyecatcher59-label">&#160;</dt><dd id="deleteEyecatcher59-element">

<button name="eyecatcher[deleteEyecatcher59]" id="eyecatcher-deleteEyecatcher59" type="button" class="delete" itemid="59">delete</button></dd></form></div>

<dt id="youtube-label">&#160;</dt><dd id="youtube-element"><fieldset id="fieldset-youtube"><dl>

<dt id="addYoutube-label">&#160;</dt><dd id="addYoutube-element">

<button name="youtube[addYoutube]" id="youtube-addYoutube" type="button">add youtube item</button></dd></dl></fieldset></dd>

<dt id="meta_description-label"><label for="meta_description" class="optional">Meta description</label></dt>

<dd id="meta_description-element">

<textarea name="meta_description" id="meta_description" rows="4" cols="80"></textarea></dd>

<dt id="meta_keywords-label"><label for="meta_keywords" class="optional">Meta keywords</label></dt>

<dd id="meta_keywords-element">

<textarea name="meta_keywords" id="meta_keywords" rows="4" cols="80"></textarea></dd>

<dt id="introductory_text-label"><label for="introductory_text" class="optional">Introductory text</label></dt>

<dd id="introductory_text-element">

<textarea name="introductory_text" id="introductory_text" class="tinyMCE" rows="24" cols="80"></textarea></dd>

<dt id="content_text-label"><label for="content_text" class="optional">Follow up text</label></dt>

<dd id="content_text-element">

<textarea name="content_text" id="content_text" class="tinyMCE" rows="24" cols="80"></textarea></dd>

<dt id="submit_button-label">&#160;</dt><dd id="submit_button-element">

<input type="submit" name="submit_button" id="submit_button" value="Save" /></dd></form>

So far it works perfectly with the exception that since I added the subforms it will no longer submit.

Anyone happen to know/ see what the issue is? Any advice will be appreciated :)

UPDATE: I updated the returned HTML code after propperly extending the Zend_Form_Subform. I have also been able to find out that the issue is somewhere in the addEyecatcher function since the form works whenever this function isn't executed.

Here is the addEyecatcher function that creates the subform:

public function addEyecatcher() { $eyecatcher_form = new Zend_Form_SubForm();

if(!$this->eyecatcher_image) {
    $eyecatcher = new Zend_Form_Element_File('eyecatcher');
    $eyecatcher->setLabel('Eyecatcher')
                    ->addValidator('Extension', false, 'jpg')
                    ->setDestination(Zend_Registry::get('config')->content->tempFysicalLocation);
    $eyecatcher_form->addElement($eyecatcher);
} else {
    $this->addPrefixPath('HPU_Form_Element', 'HPU/Form/Element/', 'Element');
    $eyecatcher = new HPU_Form_Element_Note('eyecatcher');
    $source = Zend_Registry::get('config')->content->imageRelativeLocation . $this->eyecatcher_image['image_url'];
    $eyecatcher->setValue("<img src='{$source}'/>");
    $eyecatcher_form->addElement($eyecatcher);
    $eyecatcher_form->addElement('button', "deleteEyecatcher{$this->eyecatcher_image['id']}", array('label' => 'delete', 'class' => 'delete', 'itemid' => $this->eyecatcher_image['id']));
}
$eyecatcher_form->setDecorators(array("ViewHelper"));
$eyecatcher_form->setDecorators(array("FormElements", "Form", array('HtmlTag', array('tag'=>'div' , 'class' => 'eyecatcher_item'))));

$this->addSubForm($eyecatcher_form, 'eyecatcher');

return $eyecatcher_form;

}

Thanks for the help so far, i've already gotten a few steps further into solving this problem :)

1

There are 1 best solutions below

2
On BEST ANSWER

Subforms should not include their own <form> tag. That is what is breaking your submit button. Can you double-check that your sub forms extend Zend_Form_SubForm? If so, please post the code (or the relevant part) for one of your subform methods.

Edit: You still have a second form tag for your eye catcher form because you are manually adding a form decorator to the sub form (which wraps it with <form> .. </form>). Try changing your set decorators line to this:

$eyecatcher_form->setDecorators(array("FormElements", array('HtmlTag', array('tag'=>'div' , 'class' => 'eyecatcher_item'))));