同一实体的多种形式



我正在努力验证包含同一实体的三种不同形式的页面的形式。

我在我的formType中有这个"usuario"字段是我的html上的一个选择,它只返回我用"dpto"过滤的内容。选择:

<?php
namespace AppForm;
use AppEntityResponsavel;
use AppEntityUsuario;
use DoctrineORMEntityRepository;
use SymfonyBridgeDoctrineFormTypeEntityType;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormExtensionCoreTypeHiddenType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolver;
class ResponsavelType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('competenciaInicial')
->add('cliente')
->add('usuario', EntityType::class, [
'required'=> false,
'placeholder'=> '',
'class'=> Usuario::class,
'query_builder' => function(EntityRepository $er) use ($options){
return $er->createQueryBuilder('u')
->where('u.ativo = 1 AND u.acesso < 9 AND u.departamento = :dpto')
->setParameter('dpto',$options['dpto'])
->orderBy('u.nome', 'ASC');}
])
->add('ativo')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Responsavel::class,
'dpto' => '',
]);
}

}

我的控制器(与加载页面时相同),我创建了form1, form2, form3,并传递了不同的"dpto"作为创建视图的选项,然后我做了一个简单的测试,当表单被提交时,它会转储它来自哪个表单。

/**
* @Route("/responsavel", name="responsavel_index")
*/
public function index(Request $request)
{
$responsavel = new Responsavel();
$contabil = $request->request->get('contabil');

$form1 =  $this->createForm(ResponsavelType::class, $responsavel, ['dpto'=>'C']);
$form1->remove('ativo');
$form1->remove('cliente');
$form1->remove('competenciaInicial');
$form1->handleRequest($request);

$form2 =  $this->createForm(ResponsavelType::class, $responsavel, ['dpto'=>'D']);
$form2->remove('ativo');
$form2->remove('cliente');
$form2->remove('competenciaInicial');
$form2->handleRequest($request);
$form3 =  $this->createForm(ResponsavelType::class, $responsavel, ['dpto'=>'F']);
$form3->remove('ativo');
$form3->remove('cliente');
$form3->remove('competenciaInicial');
$form3->handleRequest($request);

if ($form1->isSubmitted()) {
dump('form1');
}
if($form2->isSubmitted()){
dump('form2');
}

if($form3->isSubmitted()){
dump('form3');
}
return $this->render('responsavel/index.html.twig', [
'entity' => [],
'form1' => $form1->createView(),
'form2' => $form2->createView(),
'form3' => $form3->createView()
]);
}

下面是表单的渲染和表单提交的js:


<div class="modal-body px-4">
<div id="clienteId" data-cliente="" class="d-none">
</div>
{% if app.user.acesso in [1,2,3,4,7]%}
{% if app.user.acesso <= 3 or app.user.departamento == 'C' %}
{{ form_start(form1, {'name' : 'responsavelContabil'})}}
<label class="text-monospace"> Contabilidade </label>
<div class="row">
<div class="mb-3 col-10">
{{form_widget(form1.usuario, {'id' : 'usuarioContabil'})}}
</div>
<div class="col-2 mb-3">
<button id="okContabil" type="submit" class="btn btn-success"><i class="mdi mdi-check"></i></button>
</div>
</div>
{{ form_end(form1)}}
{% endif %}
{% if app.user.acesso <= 3 or app.user.departamento == 'D' %}
{{ form_start(form2, {'name' : 'responsavelDp'})}}
<label class="text-monospace"> Dpto. Pessoal </label>
<div class="row">
<div class="mb-3 col-10">
{{form_widget(form2.usuario, {'id' : 'usuarioDp'})}}
</div>
<div class="col-2 mb-3">
<button id="okDp" class="btn btn-success"><i class="mdi mdi-check"></i></button>
</div>
</div>
{{ form_end(form2)}}
{% endif %}
{% if app.user.acesso <= 3 or app.user.departamento == 'F' %}
{{ form_start(form3, {'name' : 'responsavelFiscal'})}}
<label class="text-monospace"> Fiscal </label>
<div class="row">
<div class="mb-3 col-10">
{{form_widget(form3.usuario, {'id' : 'usuarioFiscal'})}}
</div>
<div class="col-2 mb-3">
<button id="okFiscal" class="btn btn-success"><i class="mdi mdi-check"></i></button>
</div>
</div>
{{ form_end(form3)}}
{% endif %}
{% endif %}
</div>
...
$('form').submit(function(e){
e.preventDefault();
console.log($(this));
var dpto = $(this[0]).attr('id').replace('usuario', '').charAt(0);
var responsavel = {dpto:dpto, cliente: $('#clienteId').data('cliente'), responsavel: {usuario: $(this[0]).val()}}
$.ajax({
url: "{{ path('responsavel_index')}}",
type: 'post',
dataType: 'json',
data: responsavel,
success: function(){
console.log('foi');
}
});

很明显,问题是当我提交表单时,它不能区分彼此,然后迭代所有条件,也只检查"常规"。Id根据在form1上创建的表单的选择列表传递请求,然后返回一个"无效"字段;通过的"常规"错误表单验证器上的Id。

我做错了什么,如何修复它或如何调试它的任何想法?

谢谢提前!

我认为你可以试着通过它们的名称,通过请求传递的键来区分表单。

public function __construct() {
$this->prefix = self::$count++;
}
private $prefix;
private static $count = 0;
public function getBlockPrefix() {
return $this->prefix . '_form';
}

这是您的表单类型的代码。这样,呈现的输入将为每个表单具有不同的名称,例如:

<input type="text" id="form_name" name="0_form[name]" class="form-control">

每个表单都有不同的后缀,它们提交的值不会干扰其他表单。请确保在稍后呈现和处理提交的表单时以相同的顺序创建表单,因为后缀依赖于顺序("count++")部分)。试一下,告诉我是否有效。

更新:

在symfony 3+中不起作用。实例只创建一次,但是每次在控制器保证中初始化form时都会调用您的Type中的buildForm方法。所以:

private $formPrefix;
public function __construct()
{
$this->formPrefix = 0;
}
public function getBlockPrefix()
{
return $this->formPrefix . '-' . parent::getBlockPrefix();
}
public function buildForm(FormBuilderInterface $builder, array $options) {
++$this->formPrefix;
...
}

引用

创建2个表单的结果

最新更新