4

各ラジオ/チェックボックス項目の下にフィールドセットを作成したいと思います。

例えば

Which animals do you like:

[x] Cats

    [Fieldset of cat related questions]

[ ] Dogs

    [Fieldset of dog related questions]

...

Fieldsets と Forms は簡単に作成できますが、それらを各アイテムの下にネストすると頭が痛くなります。

最終的には、次のようなことを念頭に置いていました。

 $this->add(array(
        'type' => 'Zend\Form\Element\Radio',
        'name' => 'profile_type',
        'options' => array(
            'label' => 'Which animals do you like:',
            'label_attributes' => array('class'=>'radio inline'),
            'value_options' => array(
                '1' =>'cats',

                'fieldsets' => array(
                 array(
                    'name' => 'sender',
                    'elements' => array(
                        array(
                            'name' => 'name',
                            'options' => array(
                                'label' => 'Your name',
                                ),
                            'type'  => 'Text'
                        ),
                        array(
                            'type' => 'Zend\Form\Element\Email',
                            'name' => 'email',
                            'options' => array(
                                'label' => 'Your email address',
                                ),
                        ),
                    ),
                )),
                '2'=>'dogs',

                'fieldsets' => array(
                    array(
                        'name' => 'sender',
                        'elements' => array(
                            array(
                                'name' => 'name',
                                'options' => array(
                                    'label' => 'Your name',
                                ),
                                'type'  => 'Text'
                            ),
                            array(
                                'type' => 'Zend\Form\Element\Email',
                                'name' => 'email',
                                'options' => array(
                                    'label' => 'Your email address',
                                ),
                            ),
                        ),
                    ))
            ),
        ),
        'attributes' => array(
            'value' => '1' //set checked to '1'
        )
    ));
4

1 に答える 1

-1

ちょっとしたハックを使ってこの問題を回避することができましたが、うまくいきます。

TestForm.php (要素の追加属性に注意してください (「parent」および「childOf」)

class TestForm extends Form
{

public $user_agent;
public $user_ip;


public function __construct($name = null)
{
    // we want to ignore the name passed
    parent::__construct('profile');
    $this->setAttributes(array(
        'method'=>'post',
        'class'=>'form-horizontal',
    ));

    $this->add(array(
        'type' => 'Zend\Form\Element\Radio',
        'name' => 'profile_type',
        'options' => array(
            'label' => 'Which animals do you like:',
            'label_attributes' => array('class'=>'radio inline'),
            'value_options' => array(
                array('label' =>'cats', 'value'=>1, 'parent'=>'cat'),
                array('label'=>'dogs', 'value'=>2, 'parent'=>'dog'),
            ),
        ),
        'attributes' => array(
            'value' => '1' //set checked to '1'
        )
    ));

    $this->add(array(
        'type'  => 'Text',
        'name' => 'name',
        'attributes' => array(
            'childOf' => 'cat',
        ),
        'options' => array(
            'label' => 'Your name',
            ),
    ));

    $this->add(array(
        'type' => 'Zend\Form\Element\Email',
        'name' => 'email',
        'attributes' => array(
            'childOf' => 'dog',
        ),
        'options' => array(
            'label' => 'Your email address',
        ),
    ));
}
}

次に、Zend\Form\View\Helper\FormMultiCheckbox を拡張し、RenderOptions メソッドを上書きします (新しい optionSpec 'parent' に注意してください)。これは基本的に、親要素の後に{# cat #} などのタグを作成します。

protected function renderOptions(MultiCheckboxElement $element, array $options, array $selectedOptions,
                                 array $attributes)
{
    $escapeHtmlHelper = $this->getEscapeHtmlHelper();
    $labelHelper      = $this->getLabelHelper();
    $labelClose       = $labelHelper->closeTag();
    $labelPosition    = $this->getLabelPosition();
    $globalLabelAttributes = $element->getLabelAttributes();
    $closingBracket   = $this->getInlineClosingBracket();

    if (empty($globalLabelAttributes)) {
        $globalLabelAttributes = $this->labelAttributes;
    }

    $combinedMarkup = array();
    $count          = 0;

    foreach ($options as $key => $optionSpec) {
        $count++;
        if ($count > 1 && array_key_exists('id', $attributes)) {
            unset($attributes['id']);
        }

        $value           = '';
        $parent          = '';
        $label           = '';
        $inputAttributes = $attributes;
        $labelAttributes = $globalLabelAttributes;
        $selected        = isset($inputAttributes['selected']) && $inputAttributes['type'] != 'radio' && $inputAttributes['selected'] != false ? true : false;
        $disabled        = isset($inputAttributes['disabled']) && $inputAttributes['disabled'] != false ? true : false;

        if (is_scalar($optionSpec)) {
            $optionSpec = array(
                'label' => $optionSpec,
                'value' => $key
            );
        }

        if (isset($optionSpec['value'])) {
            $value = $optionSpec['value'];
        }
        if (isset($optionSpec['parent'])) {
            $parent = $optionSpec['parent'];
        }
        if (isset($optionSpec['label'])) {
            $label = $optionSpec['label'];
        }
        if (isset($optionSpec['selected'])) {
            $selected = $optionSpec['selected'];
        }
        if (isset($optionSpec['disabled'])) {
            $disabled = $optionSpec['disabled'];
        }
        if (isset($optionSpec['label_attributes'])) {
            $labelAttributes = (isset($labelAttributes))
                ? array_merge($labelAttributes, $optionSpec['label_attributes'])
                : $optionSpec['label_attributes'];
        }
        if (isset($optionSpec['attributes'])) {
            $inputAttributes = array_merge($inputAttributes, $optionSpec['attributes']);
        }

        if (in_array($value, $selectedOptions)) {
            $selected = true;
        }

        $inputAttributes['value']    = $value;
        $inputAttributes['checked']  = $selected;
        $inputAttributes['disabled'] = $disabled;

        $input = sprintf(
            '<input %s%s',
            $this->createAttributesString($inputAttributes),
            $closingBracket
        );

        if (null !== ($translator = $this->getTranslator())) {
            $label = $translator->translate(
                $label, $this->getTranslatorTextDomain()
            );
        }

        $tag = ($parent != '')? "{#*".$parent."*#}": "";

        $label     = $escapeHtmlHelper($label);
        $labelOpen = $labelHelper->openTag($labelAttributes);
        $template  = $labelOpen . '%s%s%s' . $labelClose;
        switch ($labelPosition) {
            case self::LABEL_PREPEND:
                $markup = sprintf($template, $label, $input, $tag);
                break;
            case self::LABEL_APPEND:
            default:
                $markup = sprintf($template, $input, $label, $tag);
                break;
        }
        $combinedMarkup[] = $markup;
    }

    return implode($this->getSeparator(), $combinedMarkup);
}

Zend\Form\View\Helper\FormRow render メソッドを拡張して上書きしました。これは、メソッドの戻り値を除いて同じです。

    ..... more code .....
    $child_of = $element->getAttribute('childOf');
    if($child_of != '')
    {
        return array($child_of => sprintf('<div class="control-group%s">%s</div>', $status_type, $markup));
    }
    return sprintf('<div class="control-group%s">%s</div>', $status_type, $markup);

最後に、Zend\Form\View\Helper\FormCollection の render メソッドを拡張して上書きし、要素の foreach ループを変更して、基本的に要素が配列の場合はタグを上書きして、ChildOf タグを付けました。次に、タグのクリーンアップ:

foreach ($element->getIterator() as $elementOrFieldset) {
        if ($elementOrFieldset instanceof FieldsetInterface) {
            $markup .= $fieldsetHelper($elementOrFieldset);
        } elseif ($elementOrFieldset instanceof ElementInterface) {
            $elementString =  $elementHelper($elementOrFieldset);
            if(!is_array($elementString))
            {
                $markup .= $elementString;
            }
            // is child of another element
            else
            {

                foreach($elementString as $key => $value)
                {
                    $match = "{#*".$key."*#}";
                    $replacement = $value.$match;
                    $markup = str_replace($match, $replacement, $markup);
                }
            }
        }
    }
    $pattern = '/[{#\*]+[a-z0-0A-Z]*[\*#}]+/';
    $markup = preg_replace($pattern, '', $markup);

これは (醜いですが) 望ましい結果をもたらします。また、レンダリング、検証、およびフォームの作成をいじっているだけなので、そのままです。

万歳、アボグローブ

于 2013-05-31T13:12:33.190 に答える