views:

321

answers:

2

I'm using Zend_Form for an application form using this code:

class Form_ApplicationForm extends Zend_Form
{
    public function init()
    {
        $this->setAction('/application/new')
             ->setMethod('post')
             ->setAttrib('id','application');

        $name = new Zend_Form_Element_Text('name');
        $name->setLabel('Your Name')
             ->setRequired(TRUE)
             ->addValidator('alpha', FALSE, array('allowWhiteSpace' => true));

        $email = new Zend_Form_Element_Text('email');
        $email->setLabel('Email Address')
              ->setRequired(TRUE)
              ->addValidator('EmailAddress');

        $this->addElements(array($name,$email));
    }
}

I'm adding a flash file uploader (swfupload) to this form which needs a HTML snippet to be in place to work, the snippet looks like this:

<div id="swfupload-control">
    <p>Upload upto 5 image files(jpg, png, gif), each having maximum size of 1MB(Use Ctrl/Shift to select multiple files)</p>
    <input type="button" id="button" />
    <p id="queuestatus" ></p>
    <ol id="log"></ol>
</div>

What is the best way of inserting this so that it sits somewhere within the <form> which i'm inserting within my controller like this:

public function newAction()
{
    $form = new Form_ApplicationForm();
    if($this->_request->isPost()){
        $data = $_POST;
        if($form->isValid($data)){
            /// handle data here
        }else{
            $form->populate($data);
        }
    }
    $this->view->form = $form;
}

Is there a way of adding a placeholder or similar within Zend_Form, or should this be done using a decorator or something like that?

Thanks.

+2  A: 

The simplest way is to do it in the view:

By echoing each element you can print its html. Here's one way to do it:

<form id="<?= $this->form->getId() ?>" action="<?= $this->form->getAction() ?>">

<? foreach ($this->form as $element): ?>
<?= $element ?>
<? if ($element->getName() == 'email'): ?>
<div id="swfupload-control">
    <p>Upload upto 5 image files(jpg, png, gif), each having maximum size of 1MB(Use Ctrl/Shift to select multiple files)</p>
    <input type="button" id="button" />
    <p id="queuestatus" ></p>
    <ol id="log"></ol>
</div>
<? endif ?>
<? endforeach ?>

</form>

What this does is it prints all the elements, and puts whatever you have to after the email field. If you add or remove a field from the form this code will continue to work (of course it will fail if you remove the email field).

Emil Ivanov
this would definitely work but it just feels a bit hacky
seengee
Agree. It might "feel" hacky, but the other solution, with implementing a decorator, is much, much more time consuming.
Emil Ivanov
haha, i'm certainly finding that :)
seengee
+3  A: 

You'd have to write your own Element for this, e.g. My_Form_Element_SwfUpload along with a renderer. See these tutorials:

Gordon
this looks like a good solution, will have to read more about it
seengee
that does seem to be the solution i'm looking for but the examples provide no context of where new files should be placed. Is there a principle i should be following here, i.e. a new folder within the same directory as ZF itself?
seengee
Well, the classnames follow the PEAR naming convention, so you'd place the above element in My/Form/Element/SwfUpload and a My_Decorator_Something would go in My/Decorator/Something
Gordon
I see, i wasnt aware of that. In your example with My/Form/Element/SwfUpload what would the root be where "My" would be added? would this be parallel to application / public / library etc?
seengee
Either your library folder or in models. But basically, anything relative to an include path you defined.
Gordon
ok, so if i was to instantiate My_Form_Element_SwfUpload with $custom = new My_Form_Element_SwfUpload(); then would it know to automatically look for this class in (for example) /library/my/form/element/swfupload.php ?
seengee
If you have setup your Zend_Autoloader this way. Yes.
Gordon
got it working by adding to autoloader but after all of that but still having issues. might make more sense to create new question but will give you points for this one :)
seengee