我的表单中有一个名为* sub_choice *的选择字段类型,其选择将通过AJAX动态加载,具体取决于父选择字段的选定值,名为* parent_choice *。加载选项非常有效,但在提交时验证sub_choice的值时遇到问题。它给出了“此值无效”验证错误,因为提交的值在构建时不在sub_choice字段的选项中。那么有没有办法可以正确验证sub_choice字段的提交值?下面是构建表单的代码。我正在使用Symfony 2.1。
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('parent_choice', 'entity', array(
'label' => 'Parent Choice',
'class' => 'Acme\TestBundle\Entity\ParentChoice'
));
$builder->add('sub_choice', 'choice', array(
'label' => 'Sub Choice',
'choices' => array(),
'virtual' => true
));
}
答案 0 :(得分:21)
要提交表格,您需要在提交表单之前覆盖sub_choice
字段:
public function buildForm(FormBuilderInterface $builder, array $options)
{
...
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$parentChoice = $event->getData();
$subChoices = $this->getValidChoicesFor($parentChoice);
$event->getForm()->add('sub_choice', 'choice', [
'label' => 'Sub Choice',
'choices' => $subChoices,
]);
});
}
答案 1 :(得分:2)
这接受任何价值
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$data = $event->getData();
if(is_array($data['tags']))$data=array_flip($data['tags']);
else $data = array();
$event->getForm()->add('tags', 'tag', [
'label' => 'Sub Choice',
'choices' => $data,
'mapped'=>false,
'required'=>false,
'multiple'=>true,
]);
});
答案 2 :(得分:0)
为将来的读者添加了另一种方法,因为我必须进行大量调查才能使我的表格正常工作。这是细分:
树枝的jquery代码:
$(function(){
$(document).ready(function() {
$("[name*='[custom_option]']").parent().parent().hide(); // hide on load
$("[name*='[options]']").append('<option value="new">New</option>'); // add "New" option
$("[name*='[options]']").trigger("chosen:updated");
});
$("[name*='[options]']").change(function() {
var companyGroup = $("[name*='[options]']").val();
if (companyGroup == 'new') { // when new option is selected display text box to enter custom option
$("[name*='[custom_option]']").parent().parent().show();
} else {
$("[name*='[custom_option]']").parent().parent().hide();
}
});
});
// Here's my Symfony 2.6 form code:
->add('options', 'entity', [
'class' => 'Acme\TestBundle\Entity\Options',
'property' => 'display',
'empty_value' => 'Select an Option',
'mapped' => true,
'property_path' => 'options.optionGroup',
'required' => true,
])
->add('custom_option', 'text', [
'required' => false,
'mapped' => false,
])
要处理表单数据,我们需要使用PRE_SUBMIT表单事件。
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
if (isset($data['options']) && $data['options'] === 'new') {
$customOption = $data['custom_option'];
// todo: handle this better on your own
if (empty($customOption)) {
$form->addError(new FormError('Please provide a custom option'));
return;
}
// Check for a duplicate option
$matches = $this->doctrine->getRepository('Acme\TestBundle\Entity\Options')->matchByName([$customOption]);
if (count($matches) > 0) {
$form->addError(new FormError('Duplicate option found'));
return;
}
// More validation can be added here
// Creates new option in DB
$newOption = $this->optionsService->createOption($customOption); // return object after persist and flush in service
$data['options'] = $newOption->getOptionId();
$event->setData($data);
}
});
让我知道您是否有任何疑问或疑虑。我知道这可能不是最好的解决方案,但它可行。谢谢!
答案 3 :(得分:-3)
你不能建立sub_choice验证,因为在你配置它的验证器时你不知道哪些值是有效的(值取决于parent_choice的值)。
您可以做的是在控制器中创建新的YourFormType()之前将parent_choice解析为实体。 然后你可以获得sub_choice的所有可能值,并通过表单构造函数提供它们 - new YourFormType($ subChoice)。
在YourFormType中,你必须像这样添加__construct方法:
/**
* @var array
*/
protected $subChoice = array();
public function __construct(array $subChoice)
{
$this->subChoice = $subChoice;
}
并使用格式add:
中提供的值$builder->add('sub_choice', 'choice', array(
'label' => 'Sub Choice',
'choices' => $this->subChoice,
'virtual' => true
));
答案 4 :(得分:-6)
假设子选择你的id是对的吗? 创建并清空具有一定数量值的数组并将其作为选择
$indexedArray = [];
for ($i=0; $i<999; $i++){
$indexedArray[$i]= '';
}
然后'choices' => $indexedArray,
:)