2

わかりました。私はZendFrameworkを初めて使用するので、これがちょっと無知な場合は失礼します。

現在、フォームがテーブルに組み込まれています。テーブルは次のようになります。

<table>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
</table>

誰が最初にそれを作ったのかは、私が働いている人々が望むものを最初に残しました。これらの同じ人々は、基本的に次のようなレイアウトを持ちたいと考えています。

<table>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
</table>
<table>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
  <tr>
    <td><label><input>[Text]</td>
  </tr>
</table>

フィールドは動的でロールベースであるため、テーブルは現在foreachステートメントを介してロールアウトされています。基本的に、コードはそのフォーム要素の完全な配列を吐き出し、foreachがそれを構築します。私はそれについてそれだけ理解しています。しかし、私の主な質問は、いわばテーブルから抜け出し、別のテーブルを展開する方法はありますか?

</tr></table><br><table>全体として、 2つの異なるテーブルを持つことができるように、本質的に何らかの方法で注入したいと思います。

ループで更新 私は進行中のpropietray作業の一部としていくつかの変数とそのようなものを除外する必要があるので、ImはWebにコードを投稿することを許可されていないので、ここに最小限のバージョンがあり、目立つ

$form = new form_TableForm(self::CHANGEPREFS);
        $form->setAction($this->_helper->url('saveprefs'));
    foreach ($defaults as $name => $value)
            {
               if ($name == 'xxx1' && (!xxx::eval('xxx','view') || $zzz)) continue;
               if ($name == 'xxx2' && !xxx::eval('xxx','view')) continue;
               if ($name == 'xxx3' && !xxx::eval('xxx','alerts')) continue;
               if ($name == 'xxx4' && !xxx::eval('xxx','alerts')) continue;

               $element = new Zend_Form_Element_Checkbox($name);
               $element->setLabel($this->_helper->Literal->xxx($name));
               if ($value) $element->setValue($value);
               $element->setOptions(array(
                   'required' => false,
                   'fullrow' => true
                   ));
               $form->addElement($element);
               //if($name == 'xxx5'){$form .= "</table><table>";}
               //bad attempt at injection above
            }
        $form->addDisplayGroup(array('savebutton'), 'buttonsgroup', array('fullrow' => true));
        return $form;
4

1 に答える 1

1

Zend_Form_Decoratorsを使用してから長い時間が経ちましたが、解決策はそれらを使用することになると思います。

Zend_Formとデコレータの簡単な概要が役立つ場合があります。

Zend_Formは、Zend_Form_Elementアイテムのマスターコンテナの一種です。これらのクラスにはデフォルトの「デコレータ」があり、Zend_Formオブジェクト全体を印刷すると、クラスはすべてのオブジェクトをループし、クラスに設定されているHTMLフォーマットを吐き出します。

Zend_Form_Elementオブジェクトを作成するときに、デコレータHTMLを設定できます。foreachループでは、要素を作成しているので、条件付きで、新しいテーブルを閉じる/開く必要がある特定の要素を変更できます。ただし、Zend_FormがHTMLを生成する方法が原因で、正しく機能させるのは難しい場合があります。標準のデコレータではかなり簡単なことを行うことができなかったため、カスタムデコレータを作成する必要があったことを思い出します。

上記の場合、$ formオブジェクトは複雑なクラスであるため、$formオブジェクトにHTMLコードを追加することはできません。

とにかく、十分な話。次のようなものを試してください。

// create the form element
$element = new Zend_Form_Element_Checkbox($name);
... // same code as above

// do something different for 'special' items
if($name == 'xxx5'){

    $element->setDecorators(array(
        array('ViewHelper'),
        // you might need to do this instead of the above
        // array('ViewHelper', array('helper' => 'formCheckbox')),
        array('HtmlTag', array(
            'tag' => 'table', 
            'placement'=>'APPEND', 
            'closeOnly' => true)),
        array(
            'decorator' => array('My_Alias_HtmlTag' => 'HtmlTag'),
            'options' => array(
                'tag' => 'table', 
                'placement'=>'APPEND', 
                'openOnly' => true)
        ),
    ));
}

// now add the element to the form object
$form->addElement($element);

私はあなたのためにこれを分解しようとします。

$element->setDecorators( array($d1, $d2, [...]) );

これにより、この要素のデコレータが設定されます。各デコレータ($ d1、$ d2など)は、前のデコレータから構築されています。$ d1がHTML文字列を吐き出し、$d2がそのHTML文字列を$d1に追加/追加すると考えてください。

array('ViewHelper'),

これは、表示する要素に到達するためのデフォルトのデコレータです。これがない場合は、何も表示されません。各要素には標準のデコレータがあります。これにはそれが含まれる可能性があると思いますが、デフォルトを強制する必要があるかもしれません:

array('ViewHelper', array('helper' => 'formCheckbox')),

両方で遊んでください。この時点で、生成されるHTMLは次のようになります。

<input type="checkbox" />

または、テーブルの行/セルタグが含まれる場合もあります。この部分は少し錆びています。

<tr><td><input type="checkbox" /></td></tr>

そうでない場合は、それらを定義することで追加できます。しかし、先に進みましょう...

array('HtmlTag', array(
        'tag' => 'table', 
        'placement'=>'APPEND', 
        'closeOnly' => true)),

「HtmlTag」は、Zend_Frameworkに付属する標準のデコレータです。基本的に、必要なHTMLタグを追加できます。私が設定したオプションは、「table」タグを使用し、それを前のデコレータHTML文字列に追加し、closeタグ(</ table>)のみを使用するように指示します。

この時点で、簡潔にするための入力タグがあると仮定します。私たちは今持っています:

<input type="checkbox" /></table>

次に、オープニングテーブルデコレータも追加します。

array(
        'decorator' => array('My_Alias_HtmlTag' => 'HtmlTag'),
        'options' => array(
            'tag' => 'table', 
            'placement'=>'APPEND', 
            'openOnly' => true)
    ),

この部分は少し混乱するかもしれません。Zend_Formでは、特定の要素で同じデコレータを複数回使用することはできません。その理由は、コードがどのように生成されるかです。基本的に、デコレータ名は名前空間のように使用されます。同じデコレータを2つ追加すると、後のデコレータが前のデコレータを上書きします。

これを回避するために、エイリアス名を付けることができます。これは、このコードのビットが実行していることです。

'decorator' => array('My_Alias_HtmlTag' => 'HtmlTag'),

「My_Alias_HtmlTag」は任意の名前にすることができますが、同じルールに従って、エイリアス名を2回使用しないでください。毎回新しいエイリアス名が必要になります。

コードの残りの部分は自明である必要があります。現在のHTML文字列に開始テーブルタグを追加したいと思います。最終結果は次のようになります。

<input type="checkbox" /></table><table>

したがって、$ formオブジェクトを印刷するときに、「特別に装飾された」要素にヒットすると、上記のHTMLコードが生成されます。

もちろん、これには多少の遊びが必要です。私が言ったように、私はZend_Form全体とそれがデコレータで少し錆びています。

カスタムZend_Formクラスが、これを正しく機能させない可能性のある予期しないことを行っている可能性があるという懸念もあります。

しかし、それを試してみてください。

Matthew Weier O'Phinneyによるこのブログ投稿は大いに役立ったと思います:http://devzone.zend.com/1240/decorators-with-zend_form/

お役に立てば幸いです。

乾杯!

アップデート

タイプミスがありました。"'tag'=>'true'"は"'tag'=>'table'"である必要があります。以前のコードを更新しました。

于 2012-06-06T23:40:44.623 に答える