Zend Framework forms, decorators and validation: s

2019-01-16 05:37发布

I am currently working on a pretty large application which contains a lot of forms.

Up to this moment, I have always been writing my forms by hand and writing my own validation logic, but I have decided it was about time I started using Zend_Form and it's built-in validation routines.

However, I keep stumbling upon more and more problems concerning the (lack of) flexibility caused Zend_Form_Decorator. Simple tasks like adding an extra button to a single input-element become incredibly difficult tasks.

I have now reached a point where I am seriously considering dropping the Zend_Form_Element + Zend_Form_Decorator approach entirely, but I do not want to lose the excellent validation options.

Basically, I want the best of both worlds:

  • Write forms the way the end-user sees them: in plain HTML
  • Easily add server-side validations to form fields without breaking too much of the ZF standard behaviour

A possible solution I am considering is writing the forms both on the server side as in the views. This would allow me to easily validate my own forms, but the (in my eyes quite big) downside is that each form should be defined twice, which just feels plain wrong.

Are there any guidelines to do this? Have any of you experienced the same, and if so, how have you solved these issues?

I'd very much like to hear your points of view.

10条回答
叼着烟拽天下
2楼-- · 2019-01-16 06:01

Here are a few decorators that I use in my projects using Zend Form. These , I believe, are simple enough to understand.

$stdRowDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td', 'width' => '200')), array('Label', array('escape' => false, 'class' => 'zfFormLabel', 'tag' => 'td')), array(array('row'=>'HtmlTag'), array('tag'=>'tr')));
$startRowDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td')), array('Label', array('escape' => false, 'tag' => 'td', 'class' => 'zfFormLabel')), array(array('row'=>'HtmlTag'), array('tag'=>'tr', 'openOnly'=>true)));
$startRowOpenOnlyDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td', 'openOnly'=>true)), array('Label', array('escape' => false, 'class' => 'zfFormLabel', 'tag' => 'td')), array(array('row'=>'HtmlTag'), array('tag'=>'tr', 'openOnly'=>true)));
$midRowDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td')),array('Label', array('escape' => false, 'class' => 'zfFormLabel', 'tag' => 'td')));
$midRowCloseOnlyDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td', 'closeOnly'=>'true')),array('Label', array('escape' => false, 'class' => 'zfFormLabel', 'tag' => 'td')));
$midRowCloseOnlyNoLabelDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td', 'closeOnly'=>'true')));
$endRowDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td')), array('Label', array('escape' => false, 'class' => 'zfFormLabel', 'tag' => 'td')), array(array('row'=>'HtmlTag'), array('tag'=>'tr', 'closeOnly'=>'true')));
$endRowCloseOnlyNoLabelDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td', 'closeOnly'=>'true')), array(array('row'=>'HtmlTag'), array('tag'=>'tr', 'closeOnly' => 'true')));
$buttonEndRowDec = array('ViewHelper', 'Description', 'Errors', array(array('data'=>'HtmlTag'), array('tag' => 'td', 'colspan'=>'2', 'align'=>'center')), array(array('row'=>'HtmlTag'), array('tag'=>'tr', 'closeOnly'=>'true')));
$buttonDecorators = array('ViewHelper', array(array('data' => 'HtmlTag'), array('tag' => 'td', 'class' => 'element')), array(array('label' => 'HtmlTag'), array('tag' => 'td', 'placement' => 'prepend')), array(array('row' => 'HtmlTag'), array('tag' => 'tr')), );
查看更多
放我归山
3楼-- · 2019-01-16 06:01

You can use Zend Form and generate the HTML yourself :) You just have to track changes and heep the form elements same in HTML and ZF :)

查看更多
Evening l夕情丶
4楼-- · 2019-01-16 06:02

I second what lo_fye mentioned. In my experience Zend Forms are clunky and not well thought out.

The solution I found easiest and most flexible is to create two form files, 1. the form class, which initializes the form elements, then a view script to display the form elements. In my form class I turn off all decorators, minus the actual form element. e.g.: ->removeDecorator('HtmlTag') ->removeDecorator('DtDdWrapper') ->removeDecorator('Label') ->removeDecorator('Errors');

Then at the end of the constructor that initializes the form elements, pass the view script: $this->setDecorators(array(array('ViewScript', array('viewScript' => 'path/to/script_form.phtml'))));

In the view script I format the form exactly how I like, then where the input field (e.g.) would be just display that element: $this->element->form_element_id. And notice I remove error decorations and just grab the error stack and display it how I think it should.

The downside is you would create a view script for every form or build some sort of reusable system yourself, so extra work. But in the end its much easier to design forms to fit within your layout, imo.

查看更多
相关推荐>>
5楼-- · 2019-01-16 06:02

Edit/Comment on top answer by @Cal Jacobson.

Cannot edit because the change is insufficient characters, cannot comment because of insufficient rep but...

$this-element->getAction()

should be

$this->element->getAction()

I'm sure the OP knows this but a correction would avoid an error when attempting to use the code in the answer directly.

查看更多
Bombasti
6楼-- · 2019-01-16 06:14

I have been using Zend Framework for about a year and I have only used Zend_Form for one of my projects (the first one). I gave up on Zend_Form after I spent all of 15 mins trying to position my 'or Cancel' link. I do love the integration though.

I now use plain HTML forms and use Zend_Filter_Input in the model (Zend_Db_Table in most cases but I had to add a Service Layer in my last project).

An example snippet of controller code using ZFI in the model. Error handling and common validation methods are in a subclass of Zend_Db_Table and my classes extend it.

A view helper formats the error messages array.

if ($this->_request->isPost()) {
    $data = $this->_request->getPost();
    $event = new Default_Model_DbTable_Event();         
    $event->createRow($data)->save();

    if ($event->hasErrors()) {
        $this->view->errors = $event->getErrorMessages();
        $this->view->event = $data;
    } else {
        $this->_redirect('events');
    }
}
查看更多
走好不送
7楼-- · 2019-01-16 06:19

Short Answer: Use Zend_Form only for validation and filtering, and use your plain old view scripts to render the form the way you want.

Long Answer: I came to the conclusion that not worth it to use Zend_Form to generate the HTML of the form. At least in the company I work. But why?

It's simple, I do not want to create a class (or use a hack) just to "tranquilly" add a link within a div inside of my form. I do not want to have to create multiple decorators just to add functionality that could easily be added with simple HTML, and most importantly, designers who work with us do not want to edit one (or two or more) class[es] only to make their work.

We continue using Zend_Form, but only to validate and filter our forms. And not to generate them.

I know many will not agree with my arguments, but that's just the opinion from someone who has had sleepless nights taken thanks to Zend_Fom.

查看更多
登录 后发表回答