如何为实体类型选择设置默认选择选项?

时间:2018-05-31 11:12:54

标签: forms symfony symfony4

所以我试图在我的表单中设置一个选定的选项,但我似乎无法找到如何执行此操作。我已经用Google搜索过,似乎Symfony2的所有内容都是default,这对于Symfony4来说似乎已经不再适用了。

我已尝试使用dataempty_data,但两者都没有选择正确的值。

# weirdly, setting to ['guru'] gets undefined index error,
# setting to $options doesn't error
->add('guru', EntityType::class, array(
    'class' => User::class,
    'choice_label' => 'username',
    'data' => $options['guru'] 
 ))

以及我如何传递$ options:

$form = $this->createForm(EditCategoryType::class, array('guru' => $guruName));

5 个答案:

答案 0 :(得分:0)

正如我在评论中所说,你做错了什么。我将解释所有过程:

  

在控制器中调用表单

$person = new Person();
$person->setName('My default name');
$form = $this->createForm('AppBundle\Form\PersonType', $person);
$form->handleRequest($request);

然后在这里执行createForm函数是代码

  

的Symfony \捆绑\ FrameworkBundle \控制器\ ControllerTrait

    protected function createForm($type, $data = null, array $options = array())
    {
        return $this->container->get('form.factory')->create($type, $data, $options);
    }

如您所见,数据或选项是在表单中直接设置的,另一个函数被调用,然后创建表单

这是我在PersonType

中进行转储时的结果
PersonType.php on line 20:
array:35 [▼
  "block_name" => null
  "disabled" => false
  "label" => null
  "label_format" => null
  "translation_domain" => null
  "auto_initialize" => true
  "trim" => true
  "required" => true
  "property_path" => null
  "mapped" => true
  "by_reference" => true
  "inherit_data" => false
  "compound" => true
  "method" => "POST"
  "action" => ""
  "post_max_size_message" => "The uploaded file was too large. Please try to upload a smaller file."
  "error_mapping" => []
  "invalid_message" => "This value is not valid."
  "invalid_message_parameters" => []
  "allow_extra_fields" => false
  "extra_fields_message" => "This form should not contain extra fields."
  "csrf_protection" => true
  "csrf_field_name" => "_token"
  "csrf_message" => "The CSRF token is invalid. Please try to resubmit the form."
  "csrf_token_manager" => CsrfTokenManager {#457 ▶}
  "csrf_token_id" => null
  "attr" => []
  "data_class" => "AppBundle\Entity\Person"
  "empty_data" => Closure {#480 ▶}
  "error_bubbling" => true
  "label_attr" => []
  "upload_max_size_message" => Closure {#478 ▶}
  "validation_groups" => null
  "constraints" => []
  "data" => Person {#407 ▼ // Here is the data!!!
    -id: null
    -name: "My default name"
    -salary: null
    -country: null
  }
]

正如您所看到的那样,数据是以数据为索引的,这就是您获得未定义索引错误的原因

因此,正确的方法是从控制器设置实体值或将表单用作服务并调用存储库并使用自版本2以来未更改的数据选项设置值。我的观点是您正在使用形式错了。

请更改您的代码。

希望有所帮助

  

以SYMFONY 4方式编辑(没有名称空间捆绑包)

让我们看一下,我有一个人物实体,其名称仅用于此示例

  

控制器

    $person = new Person(); //or $personsRepository->find('id from request')
    $person->setName('My default name');
    $form = $this->createForm(PersonType::class, $person);
    $form->handleRequest($request);
  

表格

public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder->add('name',TextType::class,[
            //'data' => 'aaaaa' // <= this works too

        ]);

    }
  

options数组值,证明您访问错误

PersonType.php on line 20:
array:35 [▼
  "block_name" => null
  "disabled" => false
  "label" => null
  "label_format" => null
  "translation_domain" => null
  "auto_initialize" => true
  "trim" => true
  "required" => true
  "property_path" => null
  "mapped" => true
  "by_reference" => true
  "inherit_data" => false
  "compound" => true
  "method" => "POST"
  "action" => ""
  "post_max_size_message" => "The uploaded file was too large. Please try to upload a smaller file."
  "error_mapping" => []
  "invalid_message" => "This value is not valid."
  "invalid_message_parameters" => []
  "allow_extra_fields" => false
  "extra_fields_message" => "This form should not contain extra fields."
  "csrf_protection" => true
  "csrf_field_name" => "_token"
  "csrf_message" => "The CSRF token is invalid. Please try to resubmit the form."
  "csrf_token_manager" => CsrfTokenManager {#457 ▶}
  "csrf_token_id" => null
  "attr" => []
  "empty_data" => Closure {#480 ▶}
  "error_bubbling" => true
  "label_attr" => []
  "upload_max_size_message" => Closure {#478 ▶}
  "validation_groups" => null
  "constraints" => []
  "data" => Person {#407 ▼
    -id: null
    -name: "My default name" //Here is the data
    -salary: null
    -country: null
  }
]

AppBundle只是我文件夹结构中的另一个文件夹。很高兴考验你的自我。 formCreate函数的第二个参数是实体或数据,而不是您认为选项是数据的选项。

答案 1 :(得分:0)

$parentCategory = $categoryRepository->repository->find(2);
$category = new Category();
$category->setParentCategory(parentCategory);
$form = $this->createForm(CategoryType::class, $category);

我们选择了预定义的顶级类别,如果您以这种方式使用它,它就会起作用。

答案 2 :(得分:0)

所以在@Juan I. Morales Pestana的帮助下我找到了一个答案,唯一的原因是我将下面的内容添加为答案而不是将其标记为正确是因为似乎在如何它现在有效..:

控制器现在读取(感谢@Juan):

$category = $this->getDoctrine()->getRepository(Category::class)->find($id);
$category->setGuru($category->getGuru());

$form = $this->createForm(EditCategoryType::class, $category);

我的EditCategoryType类:

->add('guru', EntityType::class, array(
    'class' => User::class,
    'choice_label' => 'username',
    'mapped' => false,
    'data' => $options['data']->getGuru()
))

更新了twig模板:

{{ form_widget(form.guru, { 'attr': {'class': 'form-control'} }) }}

答案 3 :(得分:0)

<a href="{{ path('register_new', { idpackage: p.id }) }}" class="btn_packages">

//sends to form type the package id
$fromPackage = '';
if($request->query->get('idpackage')) {
$fromPackage = $request->query->get('idpackage');
}

$form = $this->createForm(RegisterFormType::class, $register, ['fromPackage' => $fromPackage]);

in formType set the param in options: 
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Register::class,
'fromPackage' => null
]);
}

->add('package',EntityType::class, [
'label' => 'Select one item',
'class' => Package::class,
'choice_label' => function($package) {
    return $package->getTitle() . ' | crédits : ' . $package->getAmount();
},
'attr' => ['class' => 'input-text', ],
'placeholder' => '...',
'required' => false,
'choice_attr' => function($package) use ($idFromPackage) {
    $selected = false;
    if($package->getId() == $idFromPackage) {
        $selected = true;
    }
    return ['selected' => $selected];
},
])

答案 4 :(得分:-1)

试试这个: empty_data documentation