我正在构建一个复杂的symfony表单,它有点长并包含其他嵌入表单。因此,表单在UI中显示在单独的选项卡中,以使其对用户更具可读性和方便性。
因为表格很长并且在UI中分开,所以有可能在填充它时错过了某些内容,或者您只是插入了不正确的内容。那时验证会启动并停止保存表单。验证本身已配置完好并且运行良好。
我的问题是我有一个巨大的表单,在标签中分开,在某处有错误,我需要浏览每个标签以确切地看到什么是错误。我正在考虑使用另一种颜色制作包含错误字段的特定选项卡,这样它就可以脱颖而出,为您节省时间,想知道错误是什么以及它位于何处。
从我所看到的,我有两个选择:
{% if not form.children.FIELD_NAME.vars.valid %}
这将需要永远完成,我只会做它唯一可行的方式。validation_groups => array('Default', 'my_tab_name')
并对每个标签进行逻辑分组。 我真的希望使用第二种方法,但我似乎无法弄清楚如何检查验证组,my_tab_1
是否包含任何错误。我知道我可以这样做:
$validator = $this->get('validator');
$my_tab_1 = $validator->validate($entity, null, array('my_tab_1'));
$my_tab_2 = $validator->validate($entity, null, array('my_tab_2'));
$my_tab_3 = $validator->validate($entity, null, array('my_tab_3'));
// so on
但表单已经使用$form->validate()
验证,并且使用此方法会触发N次更多不必要的验证。
所以这里的问题是如何从树枝模板中检查特定验证组是否有效?如果那是不可能的,可以从Controller
获取它并将其作为变量传递而不进行另一次验证吗?
我认为我不需要发布FormType
因为它们很长,嵌套并且可能只会让你感到困惑。但是,这是父表单的过度简化版本:
class CompanyType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('address')
->add('representedBy')
->add('category')
->add('phone')
->add('member', new MemberType())
->add('contacts', new ContactType())
->add('notes', new NoteType())
// and a couple more embedded form types.
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\FooBundle\Entity\Company',
'cascade_validation' => true
));
}
/**
* @return string
*/
public function getName()
{
return 'app_company';
}
}
如果有人有更好的想法或解决方案,我会非常感激。
答案 0 :(得分:1)
首先,您可以通过两种不同的方式使用标签:
a)使用javascript。选项卡的所有内容都加载一次,可以在页面源中找到。除了一个之外,所有标签内容都是隐藏的。
b)使用链接和PHP。在这种情况下,每个标签都是另一个带有其他网址的网页。
(希望你能理解其中的差异)
我总是将第二种方法用于高级表单。因此,对于每个页面,我只添加formtype中所有表单域的一部分。对于每个页面,我也使用一个验证组。这已经足以编辑现有实体。
但问题是新的实体。您可能希望避免数据库中部分填充的实体,因此您需要验证并存储每个步骤'在会话中以及用户完成最后一步(并且验证正常)之后,您可能希望将所有表单字段一次性存储到数据库中。
此方法由craueformflowbundle使用。
要获取表单域的一部分,只需在formType中使用开关或为每个步骤创建一个formType。
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class CompanyType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
switch ($options['flow_step']) {
case 1:
$builder
->add('company')
->add('origin')
;
break;
case 2:
$builder
->add('contactPerson', NULL, array('label' => 'Volledige naam'))
->add('email', 'email', array('label' => 'Email'))
->add('telephone', NULL, array('label' => 'Telefoonnummer'))
;
break;
}
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Company',
'flow_step' => 1
));
}
/**
* @return string
*/
public function getName()
{
return 'appbundle_company';
}
}