2013-05-16 1 views
4

Я хотел бы создать набор полей под каждым элементом радио/checkbox.Вложенные поля в поле «Радио» или «Ячейки»: Zend Framework 2

например

Which animals do you like: 

[x] Cats 

    [Fieldset of cat related questions] 

[ ] Dogs 

    [Fieldset of dog related questions] 

...

Я могу создать Fieldsets и формы с легкостью, но гнездование их по каждому пункту, вызывает у меня некоторые головные боли.

В конце концов, я имел в виду что-то вроде этого:

$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' 
     ) 
    )); 
+0

Вы с визуализации проблем, связанных или вы спрашиваете о передовом опыте, чтобы настроить саму форму на кодовой базе? – Sam

+0

Привет Сэм, лучшая практика для настройки самой формы. – Aborgrove

ответ

-1

Хорошо мне удалось обойти этот вопрос, используя немного рубить, но это работает.

TestForm.php (обратите внимание на дополнительные атрибуты элементов ('родитель' и '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 'родителя'), это в основном создает тег, например, {# кошки #} после родительского элемента:

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); 
} 

Extended и переписал Zend \ Form \ View \ Helper \ FormRow метод визуализации это то же самое, г возвращение метода:

..... 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 и изменил цикл Еогеасп элемент, в основном перезапись теги, если элемент является массивом, и поэтому имеет тег 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); 

Это (хотя некрасиво) дают желаемые результаты, а также потому, что мы просто играем с рендерингом, проверкой и созданием формы нетронуты.

Все самое лучшее, Aborgrove