Symfony3 + Select2 AJAX - 禁用选择验证
Symfony3 + Select2 AJAX - disable validation of choices
我有一个带有 ChoiceType 字段的 Symfony3 表单。它使用带有 AJAX 数据源的 Select2。这一点工作正常。然而,当提交表单时,Symfony 验证开始并抱怨:
This value is not valid
我猜这是因为通过 AJAX 选择的选项在表单类型的 'choices' 键中不存在。
我对 Symfony 比较陌生。有人可以指出正确的方向来禁用字段上的验证吗?
您不应该禁用验证。使用 Form Events
- http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
动态添加选项
您必须始终使用字符串值将数据提交到 ChoiceType
。
考虑以下 ChoiceType
配置:
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
$builder->add('some_choice', ChoiceType::class, array(
'choices' => array(
'Choose 1' => 1,
'Choose A' => 'A',
'Choose True' => true,
),
));
默认情况下,您可能希望将选择数组中的每个键用作标签,并且将每个选择值转换为字符串并用作 html 值:
<option value="1">Choose 1</option>
<option value="A">Choose A</option>
<option value="1">Choose True</option>
上面这个例子是错误的。
如您所见,将 true
转换为字符串会得到 "1"
并且它已用于整数 1 选择。
所有选择值必须始终是唯一的,因此默认情况下,在这种情况下,ChoiceType
使用数字递增:
<option value="0">Choose 1</option>
<option value="1">Choose A</option>
<option value="2">Choose True</option>
The same happens when some model choice value in the choice array are not scalar (e.g array
, object
, null
...).
则提交的数据应为"0"
、"1"
或"2"
。每个都将通过 ChoiceType
.
映射回相应的选择
为了完全控制用于每个选择的字符串值,您可以使用选项 choice_value
作为闭包,它将每个选择作为唯一参数传递并且必须 return 它的字符串值。
如果您的选择是对象或数组,您可以将其设置为 属性 路径:
'choice_value' => 'property'
// will be equivalent to
'choice_value' => function ($choice) {
if (is_array($choice)) {
return $choice['property'];
}
if (is_object($choice)) {
return $choice->getProperty();
// or even $choice->isProperty()
}
throw new UnexpectedTypeException();
}
结论:
默认行为与:
$builder->add('some_choice', ChoiceType::class, array(
'choices' => array(
'Choose 1' => 1,
'Choose A' => 'A',
'Choose True' => true,
),
'choice_value' => function ($choice) {
if (!is_scalar($choice) {
return null;
}
return false === $choice ? '0' : (string) $choice;
},
));
如果 null
或两个相同的值被 returned,将使用递增的整数。
您始终必须提交字符串选择值,才能将其映射回 ChoiceType
。
任何未知值或 "extra" 值都将导致您的错误。
我有一个带有 ChoiceType 字段的 Symfony3 表单。它使用带有 AJAX 数据源的 Select2。这一点工作正常。然而,当提交表单时,Symfony 验证开始并抱怨:
This value is not valid
我猜这是因为通过 AJAX 选择的选项在表单类型的 'choices' 键中不存在。
我对 Symfony 比较陌生。有人可以指出正确的方向来禁用字段上的验证吗?
您不应该禁用验证。使用 Form Events
- http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
您必须始终使用字符串值将数据提交到 ChoiceType
。
考虑以下 ChoiceType
配置:
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
$builder->add('some_choice', ChoiceType::class, array(
'choices' => array(
'Choose 1' => 1,
'Choose A' => 'A',
'Choose True' => true,
),
));
默认情况下,您可能希望将选择数组中的每个键用作标签,并且将每个选择值转换为字符串并用作 html 值:
<option value="1">Choose 1</option>
<option value="A">Choose A</option>
<option value="1">Choose True</option>
上面这个例子是错误的。
如您所见,将 true
转换为字符串会得到 "1"
并且它已用于整数 1 选择。
所有选择值必须始终是唯一的,因此默认情况下,在这种情况下,ChoiceType
使用数字递增:
<option value="0">Choose 1</option>
<option value="1">Choose A</option>
<option value="2">Choose True</option>
The same happens when some model choice value in the choice array are not scalar (e.g array
, object
, null
...).
则提交的数据应为"0"
、"1"
或"2"
。每个都将通过 ChoiceType
.
为了完全控制用于每个选择的字符串值,您可以使用选项 choice_value
作为闭包,它将每个选择作为唯一参数传递并且必须 return 它的字符串值。
如果您的选择是对象或数组,您可以将其设置为 属性 路径:
'choice_value' => 'property'
// will be equivalent to
'choice_value' => function ($choice) {
if (is_array($choice)) {
return $choice['property'];
}
if (is_object($choice)) {
return $choice->getProperty();
// or even $choice->isProperty()
}
throw new UnexpectedTypeException();
}
结论:
默认行为与:
$builder->add('some_choice', ChoiceType::class, array(
'choices' => array(
'Choose 1' => 1,
'Choose A' => 'A',
'Choose True' => true,
),
'choice_value' => function ($choice) {
if (!is_scalar($choice) {
return null;
}
return false === $choice ? '0' : (string) $choice;
},
));
如果 null
或两个相同的值被 returned,将使用递增的整数。
您始终必须提交字符串选择值,才能将其映射回 ChoiceType
。
任何未知值或 "extra" 值都将导致您的错误。