CRUD を扱うときにフォーム オブジェクトからビューを生成する簡単な方法があるかどうか疑問に思っていました。
つまり、次のオプションがある場合です。編集 | DELETE EDIT オプションのような VIEW オプションが必要ですが、フォーム要素がなく、値だけが必要です。
これにより、これらのビューの作成にかかる時間を最小限に抑えることができます。
誰かがそのようなことを知っていますか?
CRUD を扱うときにフォーム オブジェクトからビューを生成する簡単な方法があるかどうか疑問に思っていました。
つまり、次のオプションがある場合です。編集 | DELETE EDIT オプションのような VIEW オプションが必要ですが、フォーム要素がなく、値だけが必要です。
これにより、これらのビューの作成にかかる時間を最小限に抑えることができます。
誰かがそのようなことを知っていますか?
私の最後のプロジェクトでも、このジレンマがありました。私のソリューションは最もエレガントではないかもしれませんが、うまくいきました。完全なデコレータで生成された要素の代わりに、フォーム ビュースクリプト デコレータを使用します。しかし、この例を調整して、私が推測するデコレーターを使用することができます。ここで示しているのは、一般的な考え方を示すための非常に基本的な例です。これが私がしたことです:
class Cms_Form_Page extends Zend_Form
{
const FOR_CREATE = 'forCreate';
const FOR_READ = 'forRead';
const FOR_UPDATE = 'forUpdate';
const FOR_DELETE = 'forDelete';
protected $_name = 'page';
private $_for;
private $_viewScripts = array(
self::FOR_CREATE => 'page-manager/partials/form-page-create.phtml',
self::FOR_READ => 'page-manager/partials/form-page-read.phtml',
self::FOR_UPDATE => 'page-manager/partials/form-page-update.phtml',
self::FOR_DELETE => 'page-manager/partials/form-page-delete.phtml'
);
public function __construct( $for = self::FOR_CREATE, $options = null )
{
$this->_for = $for;
parent::__construct( $options );
}
public function init()
{
$this->setName( $this->_name )
->setAttribs( array( 'accept-charset' => 'utf-8' ) )
->setDecorators( array(
'PrepareElements',
array( 'ViewScript', array( 'viewScript' => $this->_viewScripts[ $this->_for ] ) ),
'Form'
) );
$elements = array();
swith( $this->_for )
{
case self::FOR_CREATE:
$title = new Zend_Form_Element_Text( 'title' );
$elements[] = $title;
break
case self::FOR_READ:
$id = new Zend_Form_Element_Hidden( 'id' );
$elements[] = $id;
break;
case self::FOR_UPDATE:
$id = new Zend_Form_Element_Hidden( 'id' );
$elements[] = $id;
$title = new Zend_Form_Element_Text( 'title' );
$elements[] = $title;
break;
case self::FOR_DELETE:
$id = new Zend_Form_Element_Hidden( 'id' );
$elements[] = $id;
break;
default:
throw new Exception( 'invalid Form type' );
}
$submit = new Zend_Form_Element_Button( 'submit' );
$elements[] = $submit;
$this->addElements( $elements );
}
}
したがって、基本的に、クラス定数の 1 つをそのコンストラクターに渡します。そして、その値に基づいて、フォームに必要な要素と、要素のレンダリング方法を決定します。
たとえば、作成の場合、ロケールを選択する選択ドロップダウン フォーム フィールドを作成できます。削除の場合、これは非表示のフィールドになります (私の例では示されていません)。
これがあなたにいくつかのアイデアを与えたことを願っています。
PS:
選択したビュースクリプトの 1 つで、次のような要素の値を (非表示の要素もレンダリングして) 単純に表示できます。
<?
$form = $this->element;
?>
... some html
// let's presume id and locale are hidden form fields for current form type
// (Cms_Form_Page::FOR_UPDATE for instance)
<?= $form->id->renderViewHelper(); ?>
<?= $form->locale->renderViewHelper(); ?>
// and here we simply output the current locale value
// of course, you should have populated the values in the form somewhere first
<dt>Current locale:</dt>
<dd><?= $form->locale->getValue(); ?></dd>
...etc
したがって、フォームにviewscriptデコレーターを使用するのが最善だと思います。または、非表示フィールドをレンダリングし(必要な場合)、htmlタグに値を表示する独自のフォーム要素デコレーターをロールバックすることもできます。
NabbleのHector、これを見せてください。これが最善の方法のようです。
class Default_View_Helper_FormView extends Zend_View_Helper_Abstract
{
public function formView(Zend_Form $form)
{
$html = "<dl>";
foreach ($form->getElements as $element) {
$html .= "<dt>{$element->getLabel()}</dt>";
$html .= "<dd>{$element->getValue()}</dd>";
}
$html .= "</dl>";
return $html;
}
}
特殊なケースである可能性がある一般的な要素をカバーするために、受け入れられた回答にいくつかのマイナーな追加を行いました。
class Default_View_Helper_FormView extends Zend_View_Helper_Abstract
{
public function formView( Zend_Form $form )
{
$html = '<dl>';
foreach ( $form->getElements() as $element ) {
if( $element instanceof Zend_Form_Element_Submit ) {
continue;
}
$html .= '<dt>' . $element->getLabel() . '</dt>';
$value = $element->getValue();
if( $element instanceof Zend_Form_Element_Checkbox ) {
$value = ($value) ? 'Yes' : 'No';
}
else if( $element instanceof Zend_Form_Element_Select ) {
$value = $element->getMultiOption($value);
}
$html .= '<dd>' . $value . '</dd>';
}
$html .= '</dl>';
return $html;
}
}
受け入れられた答えの唯一の問題は、すべての要素を作成してから無視していることです。
fireeyedboy の回答の制御ロジックを使用すると、代わりにすべての要素を切り替えZend_View_Helper_FormNote
て同じことを行うことができます。
最適化が重要かどうかに依存します。
理解できるかどうかはわかりませんが、表示オプションについては、モデルからデータを取得するだけでよいと思います。Zend_Form からアクセスする必要はありません。
ただし、フォームを読み取り専用にしたい場合は、要素に readonly (setAttrib('readonly', 'readonly')) 属性を追加できます。