2

これは今週 (そして全体) で 3 番目の質問です。ここで禁止されないことを願っています :D とにかく、あちこち検索しましたが、私の問題を解決するための正確な説明が見つかりませんでした。

A. 検索して、フォームをレンダリングするためのカスタム ViewHelper を見つけました。すべてのフィールドセットを再帰的に取得し、要素レベルに到達すると、次のようになります。

    public function renderElement($element) {
        $html = '
            <div class="row">' . 
            '<label class="col-md-12" for="' . $element->getAttribute('id') . '">' . $element->getLabel() . '</label>' . 
            $this->view->formElement($element) . 
            $this->view->FormElementErrors($element) .
            '<div class="clearfix" style="height: 15px;"></div>';

        return $html . PHP_EOL;
    }

フォームは正常にレンダリングされますが、例外は次のとおりです。1) フォーム要素にエラー クラスを追加するにはどうすればよいですか? (ビューで formRow ヘルパーを使用する場合と同様に、要素を作成するときにフィールドセットで指定された初期クラスを維持しながら、「入力エラー」クラスを自動的にアドバタイズします - 'attributes' => array('class' => ' some-class')) であるため、無効な場合、要素の class 属性は「some-class input-error」になります。2) エラー メッセージを含む「ul」($this->view->FormElementErrors($element) によってレンダリングされる「ul」) のクラスを設定するにはどうすればよいですか? これがワンライナーであることを願っており、メッセージごとに移動してエラーメッセージリストのhtmlを作成する必要はありませんが、そうでない場合はそうです(方法もわかりません)。

B. このカスタム ViewHelper を使用してフォームをレンダリングしないことがあるとしましょう。Zend の formRow ビュー ヘルパーが便利な場合があります。これにより、私の見解では次のコードが表示されます。

    echo $this->formRow($this->form->get('user_fieldset')->get('user_name'));

これにより、要素に「input-error」クラスが自動的に追加されることに気づきました(無効な場合)。これは完璧ですが、エラーメッセージを表示している「ul」にクラスを与えるようにformRowに指示するにはどうすればよいですか?

さらに進んで、これをどのように変えることができるかを尋ねます。

    echo $this->formLabel($this->form->get('user_fieldset')->get('user_name'));
    echo $this->formInput($this->form->get('user_fieldset')->get('user_name'));
    echo $this->formElementErrors($this->form->get('user_fieldset')->get('user_name'), array('class' => 'form-validation-error'));

エラーメッセージリストだけでなく、エラークラスを要素にも広告するものにしますが、ポイントAIに誰かが答えた場合、それは同じ問題だと思います。

4

2 に答える 2

4

私はこのようにそれを行うことができました:

public function renderElement($element) {
    // FORM ROW
    $html = '<div class="form-group">';

    // LABEL
    $html .= '<label class="form-label" for="' . $element->getAttribute('id') . '">' . $element->getLabel() . '</label>';

    // ELEMENT
    /*
     - Check if element has error messages
     - If it does, add my error-class to the element's existing one(s),
       to style the element differently on error
    */
    if (count($element->getMessages()) > 0) {
        $classAttribute = ($element->hasAttribute('class') ? $element->getAttribute('class') . ' ' : '');
        $classAttribute .= 'input-error';
        /* 
         * Normally, here I would have added a space in my string (' input-error')
         * Logically, I would figure that if the element already has a class "cls"
         * and I would do $element->getAttribute('class') . 'another-class'
         * then the class attribute would become "clsanother-class"
         * BUT it seems that, even if I don't intentionally add a space in my string,
         * I still get "cls another-class" as the resulted concatenated string
         * I assume that when building the form, ZF2 automatically
         * adds spaces after attributes values? so you/it won't have to
         * consider that later, when you'd eventually need to add another
         * value to an attribute?
         */
        $element->setAttribute('class', $classAttribute);
    }
    $html .= $this->view->formElement($element);
    /*
     * Of course, you could decide/need to do things differently,
     * depending on the element's type

       switch ($element->getAttribute('type')) {
           case 'text':
           case 'email': {

               break;
           }
           default: {

           }
       }
     */
    // ERROR MESSAGES
    // Custom class (.form-validation-error) for the default html wrapper - <ul>
    $html .= $this->view->FormElementErrors($element, array('class' => 'form-validation-error'));

    $html .= '</div>'; # /.form-group
    $html .= '<div class="clearfix" style="height: 15px;"></div>';

    return $html . PHP_EOL;
}

私はこれが好きではありませんが、もっと短い方法はないと思います。ZF2には次のようなものがあるべきだと思いました:

if ($element->hasErrors()) { $element->addClass('some-class'); }

すぐに使用できます。それは私が期待していた答えです。それは単に私が見逃した/見つけられなかった方法であるということです。しかし、ZF2 には、箱から出してすぐに必要となる可能性のあるものが全世界にまったくないことが判明しました。

とにかく、誰かがそれを必要とする場合は、RenderForm ビュー ヘルパー全体を次に示します。

namespace User\View\Helper;

use Zend\View\Helper\AbstractHelper;

class RenderForm extends AbstractHelper {

    public function __invoke($form) {
        $form->prepare();
        $html = $this->view->form()->openTag($form) . PHP_EOL;
        $html .= $this->renderFieldsets($form->getFieldsets());
        $html .= $this->renderElements($form->getElements());
        $html .= $this->view->form()->closeTag($form) . PHP_EOL;
        return $html;
    }

    public function renderFieldsets($fieldsets) {

        foreach ($fieldsets as $fieldset) {
            if (count($fieldset->getFieldsets()) > 0) {
                $html = $this->renderFieldsets($fieldset->getFieldsets());
            } else {
                $html = '<fieldset>';
                    // You can use fieldset's name for the legend (if that's not inappropriate)
                    $html .= '<legend>' . ucfirst($fieldset->getName()) . '</legend>';
                    // or it's label (if you had set one)
                    // $html .= '<legend>' . ucfirst($fieldset->getLabel()) . '</legend>';
                    $html .= $this->renderElements($fieldset->getElements());
                $html .= '</fieldset>';
                // I actually never use the <fieldset> html tag.
                // Feel free to use anything you like, if you do have to
                // make grouping certain elements stand out to the user
            }
        }

        return $html;
    }

    public function renderElements($elements) {
        $html = '';
        foreach ($elements as $element) {
            $html .= $this->renderElement($element);
        }
        return $html;
    }

    public function renderElement($element) {
        // FORM ROW
        $html = '<div class="form-group">';

        // LABEL
        $html .= '<label class="form-label" for="' . $element->getAttribute('id') . '">' . $element->getLabel() . '</label>'; # add translation here

        // ELEMENT
        /*
         - Check if element has error messages
         - If it does, add my error-class to the element's existing one(s),
           to style the element differently on error
        */
        if (count($element->getMessages()) > 0) {
            $classAttribute = ($element->hasAttribute('class') ? $element->getAttribute('class') . ' ' : '');
            $classAttribute .= 'input-error';

            $element->setAttribute('class', $classAttribute);
        }
        $html .= $this->view->formElement($element);

        // ERROR MESSAGES
        $html .= $this->view->FormElementErrors($element, array('class' => 'form-validation-error'));


        $html .= '</div>'; # /.row
        $html .= '<div class="clearfix" style="height: 15px;"></div>';

        return $html . PHP_EOL;
    }

}

ユーザーは私のモジュールです。config フォルダーに「viewhelper.config.php」を作成しました。

return array(
    'invokables' => array(
        'renderForm' => 'User\View\Helper\RenderForm',
    ),
);

そしてModule.phpで:

public function getViewHelperConfig() {
    return include __DIR__ . '/config/viewhelper.config.php';
}

次に、ビューで次のように呼び出します。

$this->renderForm($form);

もちろん、多くのビュー ヘルパーがない場合は、そのためだけに別の構成ファイルを作成することはできません。Module.php をそのままにして、次のように追加するだけです。

'view_helpers' => array(
    'invokables' => array(
        'renderForm' => 'User\View\Helper\RenderForm',
    ),
),

任意の構成ファイルに。

于 2013-12-31T14:03:15.683 に答える
2

getMessages() メソッドを使用して、要素に検証メッセージがあるかどうかを確認します。たとえば。

<div class="form-group <?=($this->form->get('user_fieldset')->get('user_name')->getMessages())?'has-error':'';?>">
    ...
</div>

この質問は非常に古いようで、自分で解決したに違いありません。:)

于 2015-01-04T17:49:35.270 に答える