#php #forms #symfony #symfony4 #symfony-forms
#php #формы #symfony #symfony4 #symfony-forms
Вопрос:
Я изо всех сил пытаюсь проверить форму страницы, которая содержит три разные формы одной и той же сущности.
У меня есть это в моем 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');
}
});
По-видимому, проблема в том, что когда я отправляю форму, она не отличает одну от другой, а затем повторяет все условия, также проверяет только идентификатор «usuario», переданный в запросе, на соответствие списку вариантов формы, созданной в form1, а затем возвращает ошибку «поле недопустимо» переданногоидентификатор «usuario» в средстве проверки формы.
Есть идеи о том, что я делаю неправильно и как это исправить или как отладить?
Заранее спасибо!
Ответ №1:
Я думаю, вы можете попытаться различить формы по их именам, ключам, которые проходят через запрос.
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 . Экземпляр создается только один раз, но метод buildForm в yout Type вызывается каждый раз, когда вы запускаете форму в Controller guaranteedy. Итак:
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;
...
}
Цитата из блока
Комментарии:
1. Кроме того, часть getBlockPrefix ‘_form’ похожа на ‘foo’, замените ее на то, что вы хотите. Переменная $count также может использоваться как sufix ofc.
2. Спасибо за помощь! И как будет выглядеть мой контроллер? Я вставил _construct и getBlocPrefix в свой FormType, он изменил имена отображаемых элементов формы, но для всех трех префикс равен «0_form»
3. О, я понимаю, почему это не работает в Symfony 3 , экземпляр создается только один раз. Я обновлю свой ответ. Попробовал этот метод, и он работает
4. Это не сработало, по-прежнему повторяет 0 в качестве префикса
5. Sry я не упомянул в buildForm @LucasMarques . В ответ добавляется функция buildForm