42

マニュアルを何度も読み、Google が提供するこの件に関する記事を精査し、ZF に関する本を何冊か購入しました。さて、なぜ私はまだ混乱しているのですか?

Zend_Form を使用して、検証して正常に機能するフォームを作成できます。私ができないことは、私が望むエラーメッセージを表示したいのとまったく同じように見えるフォームを作成することです。カスタム ボタンが欲しい、ファンキーなレイアウトが欲しい、フォームの途中にテキストを挿入したい、など。

この種のことを達成する簡単な方法はありますか?このフレームワークによってコストがかかるのではなく、時間が節約されているように感じることはありますか? Zend Form を放棄することもできます...独自のフォームを作成し、そのアクションをページにヒットさせて、投稿されたデータを検証および処理します。入力できるのとほぼ同じ速さで実行できますが、これを「取得」してできるようにしたいです明らかに意図したとおりに使用すること。

何かアドバイス?カスタムボタン、ファンキーなレイアウト、および基本的な(または難しい問題をスキップする基本的なチュートリアルがたくさんあるので高度な)ための簡単な「ハウツー」はありますか?

4

14 に答える 14

26

Barrett Conrad のアドバイスは、私が提案したものです。また、フォーム オブジェクトを使用してフォームをレンダリングする必要はないことにも注意してください。

できることの 1 つは、ビュー スクリプトで、フォーム クラスと同じ名前の要素を持つフォームを作成することです。

あなたの HTML フォーム:

<form action="/login/" method="post">
<fieldset>
    <label for="username">Username:</label>
    <input type="text" size="10" name="username" />
    <label for="password">Password:</label>
    <input type="password" size="10" name="password" />
    <input type="submit" />
</fieldset>
</form>

あなたのクラス:

class LoginForm extends Zend_Form
{
    public function init()
    {
        $username = $this->createElement('text','username');
        $username->setRequired(true);
        $this->addElement($username);

        $password = $this->createElement('password','password');
        $password->setRequired(true);
        $this->addElement($password);        
    }
}

フォーム クラスは HTML フォームを反映し、クラスの各要素には独自のバリデータと要件があります。アクションに戻って、フォーム クラスのインスタンスを作成し、そのフォームに対して post/get 変数を検証できます。

$form = new LoginForm();
if ($this->_request->isPost()) {
    if ($form->isValid($this->_request->getParams())) {
        // do whatever you need to do
    } else {
        $this->view->errors = $form->getMessages();
    }
}

この方法を使用して、エラー メッセージをフォームの上部に 1 つのグループで表示できます。

これは基本的な例ですが、デコレータの使い方を学ぶ時間を費やすことなく、フォームの表示を完全に制御できます。私の意見では、Zend_Form の強みの多くは検証とフィルタリングのプロパティにあります。これはあなたにその強さを与えます。このようなソリューションの主な欠点は、ビュー スクリプトの HTML フォームがフォーム クラスと同期しなくなる可能性があることです。

于 2009-03-08T00:07:08.690 に答える
11

ビューで各要素を個別にレンダリングします-たとえば

<!-- view script here -->
<form method="POST">
Name: <?php echo $this->myForm->getElement('name')->render(); ?>
some other text between the fields
Birthdate: <?php echo $this->myForm->getElement('birthdate')->render(); ?>
<input type="submit" />
</form>

これにより、Zend_Form ビュー ヘルパーを使用する機能 (つまり、エラー メッセージを表示し、検証が失敗したときにフォーム フィールドの値を維持する機能) が維持されますが、完全なカスタマイズ機能が提供されます。

さらに進めたい場合は、個々のフォーム要素のデフォルトのデコレーターをオフにしてから、独自のデコレーターを追加して、使用されるタグ (エラー メッセージやラベルなど) を正確にカスタマイズするか、デコレーターをまったく使用しない (その他のフォーム要素自体をレンダリングするより)、周囲のすべての HTML を手動で記述します。フォーム レベルとビュー レベルの両方で、Zend_Form の利点を失うことなく、完全なカスタマイズ機能を提供します。

于 2011-03-20T20:12:59.130 に答える
9

Matthew Weier O'Phinney が、Zend_Form デコレータに関する一連のブログ投稿を開始しました。

  1. 最も単純な Zend_Form デコレーター
  2. 裏返しに: デコレータを重ねる方法
  3. Zend_Form デコレータを個別にレンダリングする
  4. 複合要素の作成
于 2009-05-08T15:35:56.987 に答える
5

Zend\Form現在、古いコンポーネントよりもさらに複雑でありながら、より制御しやすく、カプセル化され、強力な新しい光沢のあるコンポーネントがあります。したがって、私が以下に述べたことは当てはまりません。新しいコンポーネントは、それが...

  • ...フォームをレンダリングする方法を完全に制御できます。もう少しビューコードを書く必要がありますが、それだけの価値があります
  • ...データ、ロジック、およびビューを可能な限り分離します
  • ...HTML5 フォーム要素を利用する
  • ...ハイドレーション、注釈など、フォームをどのようにまとめるかについて多くのオプションを提供します。

Zend_Form に関する古い回答

おそらく私はまったく同じ問題を抱えているため、本当に助けることはできません。Zend_Form デコレータは強力だと思いますが、これまでに見た ZF の最もプログラマーフレンドリーで直感的でない部分であり、さまざまなプロジェクトで ZF の大部分を使用してきました。

とはいえ、私の経験からいくつかのヒントしか提供できません。

  • フィルターはフォームを使わずに簡単に使用できます
  • 達成したいことのすべてではないにしても、ほとんどはデコレーターの助けを借りて行われます
  • 私は小さなフォームから始めて、少しずつ追加しましたが、結果が試行錯誤に基づいているため (主にデコレータで)、一部のフォームで行っていることの一部が得られません。
  • Zendメーリングリストから情報を入手しましたが、これはウェブ上のどこにもありませんでした

右側のこれに関連する質問から、Zend_Form の包括的なドキュメントが不足していることは明らかです。特に、Zend_Form の直感的でない性質を考えるとそうです。私が Zend Framework を気に入っているのと同じくらい、ZF の人たちがこれについて何かしてくれるのを見たいと思っています。

したがって、この回答はおそらく、この問題を抱えているのはあなただけではないことを知らせるためのものです.


または、もちろん、ジェダイの心のトリックを使用することもできます!

于 2009-02-11T00:19:39.800 に答える
4

言われたことに追加するには:

デコレータを恐れないでください。Zend_Form を使い続けることに決めた場合、デコレータをたくさん使用することになります。「理解」すればかなり簡単ですが、残念ながらドキュメントは弱く、それをいじるしかそこにたどり着くことがほとんどできません。

ViewScript および ViewHelper デコレーターは、多くの機能を提供します。

存在するさまざまなデコレーターのソースを掘り下げて、それらがどのように機能しているかを確認することを恐れないでください (元のデコレーターと dojo のデコレーターを比較して、かなりの洞察を得ました)。

Sean が提案していたのは、form->render を呼び出す必要はなく、viewscript でこのようなものを使用できるということだと思います。

 <someHtmlThingy name="blah" value="<?php echo $this->formInstance->getElement('whatever')->getValue(); ?>" />

私は 1 つのプロジェクト (Zend_Form 以前) に取り組み、バリデーターのセットを構築し、標準のビュースクリプトをずっと使用していました。少し手間がかかりました (エラー メッセージの配管など) が、Zend_Form を使用して要素を作成する場合に比べて過剰ではありません。

于 2009-02-11T00:44:58.507 に答える
2

whycantitbemorethan25c は上記で説明しましたが、ViewScriptを使用すると、フォームのレンダリングを非常にきめ細かく制御できます。Zend_Form は高速であることを意図しているため、標準のデコレーターのような多くのデフォルトを想定し、フォーム オブジェクトに追加された方法で要素を並べ替えます。ViewScript を使用すると、その多くをスキップして、すべての要素を通常の HTML 内に好きなように配置できます。

ただし、デコレータの概念を完全にスキップしないでください。後で ViewScript で使用される場合でも、個々の要素のスタイルを設定します。たとえば、他の人が提案したように、エラー メッセージに使用できます。

同様のアクションを持つ複数のデータ ポイントを持つ非常に複雑なフォーム (アクティブ/非アクティブ ボタンとそれぞれの削除ボタンを持つユーザーのリストを考えてください) がある場合は、Zend_Form_SubFormを検討する必要があります。サブフォームは、通常のフォームと同じように ViewScript を利用できます。独自の ViewScript を持つサブフォームを持つ ViewScript を使用してフォームをカスケードすると、単純なフォームよりもはるかに強力な適切に含まれたロジックとプレゼンテーションになります。

于 2009-02-11T14:47:28.780 に答える
2

残念ながら、具体的な目的や目標を念頭に置いていないと、例やハウツーを書くのは非常に難しいため、より複雑な問題はスキップされます。SO で非表示の要素の表示方法を変更したいと考えていた別の開発者を支援するのに時間を費やしましたが、彼のケースは非常に具体的だったので、詳細にドリルダウンする方が簡単でした。

より複雑なタスクの大部分は、特定のフィールド タイプのデフォルト ヘルパーを拡張することになります。たとえば、フォームが送信された後、検証エラー テキストを書き出す代わりに、検証に合格しなかったすべてのフィールドにクラス「エラー」を適用するプロジェクトがありました。

<label for="field">Label:</label>
<input type="text" name="field" id="field" class="error">

実際のフォーム要素はデフォルトではビュー ヘルパーで使用できないため、ヘルパーは要素に検証エラーがあるかどうかを確認できないため、かなり複雑なプロセスでした。そこで、次のプロセスに進みました。

  1. 「エラー」クラスを適用するフィールド タイプごとに顧客ビュー ヘルパーを作成する必要がありました。その中で、メソッドをオーバーライドしformXXX()、要素にエラーがあるかどうかを確認するチェックを追加しました。setElement()さらに、ヘルパーがエラーをチェックできるように、要素のインスタンスを設定するためにデコレーターが呼び出すことができるメソッドを追加しました。
  2. 次に、デフォルトをオーバーライドする必要がありましたZend_Form_Decorator_ViewHelper。その中で、ビューにアクセスし、フォーム要素タイプのヘルパーをインスタンス化setElement()し、ビュー ヘルパーで作成したメソッドの存在を確認し、存在する場合は設定しました。こうすることで、スクリプト全体を破壊することなく、一部のフォーム要素タイプを拡張でき、他のタイプは拡張できませんでした。
  3. addElementPrefixPath('My_Form_Decorator'), 'path/to/decorator')各フォームの init() 関数で、新しいフォーム デコレータを指す新しい要素プレフィックス パス ( ) を追加する必要がありました。
  4. 最後に、最初の箇条書きで作成したヘルパーを Zend Framework が見つけられるように、アプリケーションにヘルパー パスを追加する必要がありました。addHelperPath('/path/to/helpers', 'My_View_Helper');

複雑なチュートリアルを作成するには実際に現実の問題が必要な理由がわかります。これらの種類のヘルパーや複雑なデコレータ スキームをセットアップすることの優れた点は、前もって煩わしくても、同じデザイン スキームに準拠する多くのフォームを非常に簡単に作成し、変更があった場合にそれらの出力を一様に非常に迅速に変更できることです。する必要があります。しかし、一方で、1 つのフォームの利益のために簡単なタスクであるべきことをどのように行うかを考え出すのに多くの時間を費やしていると感じる場合は、それを飛ばしてください!

ただし、より具体的なサポートが必要な場合は、喜んでお手伝いさせていただきます。別の質問をする (またはこれを更新する) だけで、最善を尽くしてお手伝いします。

于 2009-02-11T05:19:58.597 に答える
2

フォーム全体のデコレーター (IE - すべてを処理するためにフォームの標準のビュー ヘルパーに頼るのではなく、フォームの個々の要素を印刷する) をスキップすることは、一連の制御を取り戻す 1 つの方法です。

もう 1 つのオプションは、フォームを単純にハンドコーディングし、ZF のみを使用して検証とフィルタリングを処理することです。

于 2009-02-11T00:30:29.383 に答える
1

おそらくこれで解決したと思いますが、私はいくつかの作業を行っており、同様の解決策が必要でした.

form->getSubform('サブフォーム');
foreach ($subform as $key => $value) {
//マークアップとカスタムコードをここに
    $値を印刷します。
//マークアップとカスタムコードをここに

}
?>

foreach ループ内で、テーブル マークアップを追加できます。テーブル行のキーに適切な名前を付けていれば、それらはフォーム キーと一致するはずです。キーによって適切なサブフォームを取得するループ、またはキーによって要素を取得するループを使用することもできます。キーがわかっている場合は foreach ループをスキップして、単に print $subform['somekey']; と言うことができます。$form->setIsArray(true); と言ってメイン フォームを設定するとします。(最後の部分が厳密に必要かどうかはわかりませんが、複雑なフォームの場合は、とにかくそのように設定する必要があります.

各要素内の印刷を完全に制御できるように、デフォルトのデコレータを削除しました。Zend_Form には、個々の要素をもう少し簡単に取得するためのメソッドが組み込まれているべきですが、これはかなりうまく機能すると思います。

それが誰かに役立つことを願っています!

于 2009-11-17T23:42:49.377 に答える
1

ここに答えてください。それがあなたを助けることを願っています。私はそれを見つけるまで、非常に多くの情報を調べました。

<table>
    <tr>
        <td>Page name: *</td>
        <td><?php echo $this->pageForm->header_title;?></td>
    </tr>

    <tr>
        <td>H1 tag: *</td>
        <td><?php echo $this->pageForm->h1_tag;?></td>
    </tr>

    <tr>
        <td>Page URL: *</td>
        <td><?php echo $this->pageForm->url;?></td>
    </tr>

    <tr>
        <td>Meta Description: </td>
        <td><?php echo $this->pageForm->meta_description;?></td>
    </tr>

    <tr>
        <td>Meta Keywords: </td>
        <td><?php echo $this->pageForm->meta_keywords;?></td>
    </tr>

    <tr>
        <td>Short Description: *</td>
        <td><?php echo $this->pageForm->short_description;?></td>
    </tr>

    <tr>
        <td colspan="2"><a href="<?php echo $this->websiteUrl;?>backend_template/list?placeValuesBeforeTB_=savedValues&TB_iframe=true&height=200&width=300&modal=true"
                           title="add a caption to title attribute / or leave blank" class="thickbox">Open iFrame Modal</a></td>
         <td>
            <a href="<?php echo $this->websiteUrl;?>backend_template/list?placeValuesBeforeTB_=savedValues&TB_iframe=true&height=200&width=300&modal=true" onclick="javascript:getDataFromAddPage()" title="Select Template For Page" class="thickbox" > TEST FORM  </a>
         </td>
    </tr>

    <tr>
        <td>Featured: </td>
        <td><?php echo $this->pageForm->featured;?></td>
    </tr>

    <tr>
        <td>Mark as 404: </td>
        <td><?php echo $this->pageForm->is_404page;?></td>
    </tr>

    <tr>
        <td>Show in Navigation Menu: </td>
        <td><?php echo $this->pageForm->in_navmain;?></td>
    </tr>

    <tr>
        <td>Show in Static Menu:</td>
        <td><?php echo $this->pageForm->in_navstatic;?></td>
    </tr>

    <tr>
        <td><?php echo $this->pageForm->submit;?></td>
        <td><?php echo $this->pageForm->button_close;?></td>
    </tr>

</table>
于 2009-07-21T16:44:34.110 に答える
0

Sean McSomethingの最初のアドバイスは、私のために行く方法です。<?php echo $this->form ?>フォームをレンダリングするのは魔法すぎるといつも思っていました。$element->renderDecorator()さらに一歩進んで、魔法の方法で個々の要素ではなく、個々のデコレータをレンダリングします。このように、デコレータを定義した順序について心配する必要はありません。それらがそこにある必要があるだけで、それらの厄介で直感的でないHtmlTagデコレータを追加する必要はありません。これについてブログに投稿しました

于 2009-02-23T10:58:25.487 に答える
-1

Zend に既にその機能があるかどうかはわかりませんが、簡単な解決策はクラスを拡張して、html テンプレートを受け入れるようにすることです。

例えば:

<?php
$form = new zend_form_whatever($field_list + $validators + $template);
echo $form;
?>

テンプレート:

<form id="my_custom_form">
    <label>{label.email}</label>
    {input.email}
    <span class="red">{error.email}</span>

    <div>
        {label.password}
        {error.password}
        {input.password}
    </div>

    <div class="purple">{input.submit}<div>
</form>
于 2009-02-11T10:41:37.793 に答える