Symfony 2.7选择表单元素重复标签错误

时间:2015-11-03 15:07:31

标签: php forms symfony

使用选项数组设置一个choice元素,值'6 Door'出现3次。在数组中,密钥被保留,在symfony生成的元素中,最后一个密钥将覆盖所有先前的值,其中值匹配。

我忽略了一些简单的事情吗?

表单元素如下:

->add('category', 'choice', array(
    'required' => false,
    'choices' => $this->form_repository->getOptionsForSelect(),
));

    // configure data_class
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
                'data_class' => '\AppBundle\Model\DirectorySearch'
            ));
    }

form_repository :: getOptionsForSelect()

function(){
    $q = ...
    $results = $q->getQuery()->getResult();

    $return = array();
    foreach($results as $form) {
        foreach($form->getElements() as $element){
            $options = array();

            foreach($element->getMultiOptions() as $multi_option) {
                $options[$multi_option->getId()] = $multi_option->getLabel();
            }
            $return[$element->getLabel()] = $options;
        }
    }
    return $return;
}

getOptionsForSelect返回的数组:

array (size=3)
  'Car Brand' => 
    array (size=4)
      221 => string '6 Door' (length=6)
      222 => string 'Toyota' (length=6)
      223 => string 'Jaguar' (length=6)
      224 => string 'Skodai' (length=6)
  'Car Doors Count' => 
    array (size=2)
      226 => string '6 Door' (length=6)
      227 => string 'Green' (length=5)
  'Car Doors' => 
    array (size=5)
      228 => string '1 Door' (length=6)
      229 => string '2 Door' (length=6)
      230 => string '3 Door' (length=6)
      231 => string '4 Door' (length=6)
      232 => string '6 Door' (length=6)

选择生成 - 注意到所有6个门标签现在都使用值= 232:

<select id="category" name="category" class="form-control">
    <option value=""></option>
    <optgroup label="Car Brand">
        <option value="232">6 Door</option>
        <option value="222">Toyota</option>
        <option value="223">Jaguar</option>
        <option value="224">Skodai</option>
    </optgroup>
    <optgroup label="Car Doors Count">
        <option value="232">6 Door</option>
        <option value="227">Green</option>
    </optgroup>
    <optgroup label="Car Doors">
        <option value="228">1 Door</option>
        <option value="229">2 Door</option>
        <option value="230">3 Door</option>
        <option value="231">4 Door</option>
        <option value="232">6 Door</option>
    </optgroup>
</select>

我注意到,如果我转储$builder->get('category')->getOptions()的形式 'choices'键显示上面的数组,选项列表显示了这一点,缺少所有重复的标记选项。

'choice_list' => 
    object(Symfony\Component\Form\ChoiceList\ArrayKeyChoiceList)[1208]
      private 'useChoicesAsValues' => boolean false
      protected 'choices' => 
        array (size=9)
          '6 Door' => int 232
          'Toyota' => int 222
          'Jaguar' => int 223
          'Skodai' => int 224
          'Green' => int 227
          '1 Door' => int 228
          '2 Door' => int 229
          '3 Door' => int 230
          '4 Door' => int 231
      protected 'values' => 
        array (size=9)
          '6 Door' => string '232' (length=3)
          'Toyota' => string '222' (length=3)
          'Jaguar' => string '223' (length=3)
          'Skodai' => string '224' (length=3)
          'Green' => string '227' (length=3)
          '1 Door' => string '228' (length=3)
          '2 Door' => string '229' (length=3)
          '3 Door' => string '230' (length=3)
          '4 Door' => string '231' (length=3)
      protected 'valueCallback' => 
        object(Closure)[1209]

表单的数据类:

class DirectorySearch implements Search
{
    private $keyword = '';
    private $company_name = '';
    private $stand_number = '';
    private $town_region = '';
    private $postcode = '';
    private $country = null;
    private $category = null;
    private $page = 1;

    public function __construct(array $options = array())
    {
        $this->keyword = isset($options['keyword']) ? $options['keyword'] : '';
        $this->company_name = isset($options['company_name']) ? $options['company_name'] : '';
        $this->stand_number = isset($options['stand_number']) ? $options['stand_number'] : '';
        $this->town_region = isset($options['town_region']) ? $options['town_region'] : '';
        $this->postcode = isset($options['postcode']) ? $options['postcode'] : '';
        $this->country = isset($options['country']) ? $options['country'] : null;
        $this->category = isset($options['category']) ? $options['category'] : null;
        $this->page = isset($options['page']) ? $options['page'] : 1;
    }

    public function getKeyword() { return $this->keyword; }
    public function setKeyword($keyword) { $this->keyword = $keyword; }
    public function getCompanyName() { return $this->company_name; }
    public function setCompanyName($company_name) { $this->company_name = $company_name; }
    public function getStandNumber() { return $this->stand_number; }
    public function setStandNumber($stand_number) { $this->stand_number = $stand_number; }
    public function getTownRegion() { return $this->town_region; }
    public function setTownRegion($town_region) { $this->town_region = $town_region; }
    public function getPostcode() { return $this->postcode; }
    public function setPostcode($postcode) { $this->postcode = $postcode; }
    public function getCountry() { return $this->country; }
    public function setCountry($country) { $this->country = $country; }
    public function getCategory() { return $this->category; }
    public function setCategory($category) { $this->category = $category; }
    public function getPage() { return $this->page; }
    public function setPage($page) { $this->page = $page; }

    public function toArray()
    {
        $data = array(
            'keyword' => $this->getKeyword(),
            'company_name' => $this->getCompanyName(),
            'stand_number' => $this->getStandNumber(),
            'town_region' => $this->getTownRegion(),
            'postcode' => $this->getPostcode(),
            'country' => $this->getCountry(),
            'category' => $this->getCategory(),
            'page' => $this->getPage(),
        );

        return $data;
    }
}

1 个答案:

答案 0 :(得分:1)

我已经深入研究了Symfony 2.7源代码,我可以给你一个很好的提示。

首先,在选项中使用数组key因为html option value在symfony 2.7中已弃用,所以因为它给你提问,我认为你应该直接去#34;正确&#34 ;新方法。您面临的问题是由于内部使用了一些array_flip

从Symfony 2.7开始,您可以将choices_as_value设置为字段(与symfony 3.0向前兼容)并传递一系列选项(在模型的含义中,有时可能是一个类){{ 1}}作为关键。

在你的情况下做:

html label

您将获得以下数组:

function(){
    $q = ...
    $results = $q->getQuery()->getResult();

    $return = array();
    foreach($results as $form) {
        foreach($form->getElements() as $element){
            $options = array();

            foreach($element->getMultiOptions() as $multi_option) {
                // note this line
                $options[$multi_option->getLabel()] = (int) $multi_option->getId();
            }
            $return[$element->getLabel()] = $options;
        }
    }
    return $return;
}

组和条目现在感觉更加一致。您可以使用[ 'Car Brand' => [ '6 Door' => 221, 'Toyota' => 222, 'Jaguar' => 223, 'Skodai' => 224, ], 'Car Doors Count' => [ '6 Door' => 226, 'Green' => 227, ], 'Car Doors' => [ '1 Door' => 228, '2 Door' => 229, '3 Door' => 230, '4 Door' => 231, '6 Door' => 232, ] ]

choices_as_value

选项->add('category', 'choice', array( 'required' => false, 'choices' => $this->form_repository->getOptionsForSelect(), 'choices_as_value' => true, 'choice_value' => function ($currentChoice) { return $currentChoice; }, )); 用于根据您自己的策略覆盖默认choice_value生成策略;由于您使用的是整数,因此只需使用html option value作为choice(如果您有一个类,例如html value