Symfony 2.7 ошибка выбора метки элемента формы выбора

1

Устанавливая элемент выбора вверх с массивом опций для выбора, значение "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 дверных меток теперь используют value = 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()
Клавиша "Выбор" показывает массив выше, список выбора показывает это, не хватает всех дублированных помеченных опций.

'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;
    }
}
  • 0
    Пожалуйста, укажите версию Symfony, которую вы используете, поскольку в ChoiceList есть изменения по сравнению с Symfony 2.3 и 2.7
  • 0
    Извините, плохо обновлю вопрос, но 2.7
Показать ещё 3 комментария
Теги:
forms

1 ответ

1

Я выкопал исходный код Symfony 2.7, и я могу дать вам хороший намек.

Во-первых, использование key массива в вариантах выбора, поскольку html option value устарело в symfony 2.7, поэтому, поскольку оно дает вам проблему, я думаю, вы должны перейти непосредственно к "правильному" новому пути. Проблема, с которой вы сталкиваетесь, связана с тем, что какой-либо array_flip используется внутри.

Начиная с Symfony 2.7 вы можете установить choices_as_value в поле (будучи совместимым с версией symfony 3.0) и передать массив вариантов (в смысле вашей модели, иногда это может быть класс) с 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 по умолчанию html option value с вашей собственной стратегией; так как вы используете целые числа, просто используйте этот choice как html value (если у вас был класс, это было бы $currentChoice->getId() например)

  • 0
    Это именно то, что мне было нужно, спасибо. Теперь посмотрим, смогу ли я вместо этого изменить некоторые из своих выборов на типы сущностей, используя эти поля choice_value и choice_label.
  • 0
    Извините, что не смогу ответить на этот вопрос / ответ - я, вероятно, задам другой вопрос, если я не смогу решить это до завтра - Использование choice_value остановило заполнение формы с помощью GET - вы сталкивались с этим?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню