Ste*_*eve 10 symfony-forms symfony-2.1
我的表单看起来像这样:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$factory = $builder->getFormFactory();
$builder->add('name');
$builder->add('description');
$builder->add('manufacturers', null, array(
'required' => false
));
$builder->add('departments', 'collection', array(
'type' => new Department
));
}
Run Code Online (Sandbox Code Playgroud)
我在表单所代表的实体上有一个类验证器,它调用:
if (!$valid) {
$this->context->addViolationAtSubPath('departments', $constraint->message);
}
Run Code Online (Sandbox Code Playgroud)
这只会在表单中添加"全局"错误,而不会在子路径中添加错误.我假设这是因为departments是嵌入另一个FormType的集合.
如果我改为departments其他字段之一,它可以正常工作.
如何才能将此错误显示在正确的位置?我假设如果我的错误是在集合中的单个实体上,并因此以子表单形式呈现,它将正常工作,但我的标准是如果集合中没有任何实体被标记为活动,则会发生违规,因此它需要在父母一级.
Ber*_*sek 24
默认情况下,表单将"error_bubbling"选项设置为true,这会导致您刚才描述的行为.如果您希望他们保留错误,您可以为单个表单关闭此选项.
$builder->add('departments', 'collection', array(
'type' => new Department,
'error_bubbling' => false,
));
Run Code Online (Sandbox Code Playgroud)
我一直在 Symfony 3.3 中解决这个问题,我希望验证整个集合,但将错误传递给适当的集合元素/字段。该集合被添加到表单中,如下所示:
$form->add('grades', CollectionType::class,
[
'label' => 'student.grades.label',
'allow_add' => true,
'allow_delete' => true,
'entry_type' => StudentGradeType::class,
'attr' => [
'class' => 'gradeList',
'help' => 'student.grades.help',
],
'entry_options' => [
'systemYear' => $form->getConfig()->getOption('systemYear'),
],
'constraints' => [
new Grades(),
],
]
);
Run Code Online (Sandbox Code Playgroud)
学生成绩类型为:
<?php
namespace Busybee\Management\GradeBundle\Form;
use Busybee\Core\CalendarBundle\Entity\Grade;
use Busybee\Core\SecurityBundle\Form\DataTransformer\EntityToStringTransformer;
use Busybee\Core\TemplateBundle\Type\SettingChoiceType;
use Busybee\Management\GradeBundle\Entity\StudentGrade;
use Busybee\People\StudentBundle\Entity\Student;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class StudentGradeType extends AbstractType
{
/**
* @var ObjectManager
*/
private $om;
/**
* StaffType constructor.
*
* @param ObjectManager $om
*/
public function __construct(ObjectManager $om)
{
$this->om = $om;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('status', SettingChoiceType::class,
[
'setting_name' => 'student.enrolment.status',
'label' => 'grades.label.status',
'placeholder' => 'grades.placeholder.status',
'attr' => [
'help' => 'grades.help.status',
],
]
)
->add('student', HiddenType::class)
->add('grade', EntityType::class,
[
'class' => Grade::class,
'choice_label' => 'gradeYear',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('g')
->orderBy('g.year', 'DESC')
->addOrderBy('g.sequence', 'ASC');
},
'placeholder' => 'grades.placeholder.grade',
'label' => 'grades.label.grade',
'attr' => [
'help' => 'grades.help.grade',
],
]
);
$builder->get('student')->addModelTransformer(new EntityToStringTransformer($this->om, Student::class));
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setDefaults(
[
'data_class' => StudentGrade::class,
'translation_domain' => 'BusybeeStudentBundle',
'systemYear' => null,
'error_bubbling' => true,
]
);
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'grade_by_student';
}
}
Run Code Online (Sandbox Code Playgroud)
验证器看起来像:
namespace Busybee\Management\GradeBundle\Validator\Constraints;
use Busybee\Core\CalendarBundle\Entity\Year;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class GradesValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
if (empty($value))
return;
$current = 0;
$year = [];
foreach ($value->toArray() as $q=>$grade)
{
if (empty($grade->getStudent()) || empty($grade->getGrade()))
{
$this->context->buildViolation('student.grades.empty')
->addViolation();
return $value;
}
if ($grade->getStatus() === 'Current')
{
$current++;
if ($current > 1)
{
$this->context->buildViolation('student.grades.current')
->atPath('['.strval($q).']') // could do a single atPath with a value of "[".strval($q)."].status"
->atPath('status') // full path = children['grades'].data[1].status
->addViolation();
return $value;
}
}
$gy = $grade->getGradeYear();
if (! is_null($gy))
{
$year[$gy] = empty($year[$gy]) ? 1 : $year[$gy] + 1 ;
if ($year[$gy] > 1)
{
$this->context->buildViolation('student.grades.year')
->atPath('['.strval($q).']')
->atPath('grade')
->addViolation();
return $value;
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
克雷格
| 归档时间: |
|
| 查看次数: |
7412 次 |
| 最近记录: |