如何解决如何使用带有 craue/CraueFormFlowBundle 步进器的 Symfony4 FormEvent onChange 字段来更新或验证表单?
- 上下文:
我在 Symfony4 应用程序中使用 craue/CraueFormFlowBundle 包从基本的 SYmfony4 表单生成步进器,它工作正常,直到我尝试引入表单事件以根据表单更改修改我的表单:
How to Dynamically Modify Forms Using Form Events
- 代码:
控制器:
Error information: "SignerTimeStampEx2() failed." (-2145844844/0x80190194)
SignTool Error: An unexpected internal error has occurred.
AddUserFlow.php
**
* @Route("/user/add",name="add_user")
* @param Request $request
*/
public function add(Request $request){
$employe = new Employe();
$flow = $this->addUserFlow;
$flow->bind($employe);
// form of the current step
$form = $flow->createForm();
if ($flow->isValid($form)) {
$flow->saveCurrentStepData($form);
if ($flow->nextStep()) {
// form for the next step
$form = $flow->createForm();
} else {
//Persist user
$this->manager->persist($employe);
$this->manager->flush();
//Reset flow to create new user
$flow->reset();
//Redirect to new user detail page
return $this->redirect($this->generateUrl('user_edit',array('id' => $employe->getId())));
}
}
return $this->render('app/users/users/add.html.twig',[
'form' => $form->createView(),'flow' => $flow,'employe' => $employe
]);
}
这是我的第 3 步表单,其中包含 FormEvent :
class AddUserFlow extends FormFlow
{
protected $allowDynamicStepNavigation = true;
protected function loadStepsConfig()
{
return [
[
'label' => 'Informations générales','form_type' => UserGeneralType::class,],[
'label' => 'Contact','form_type' => EmployeContactType::class,[
'label' => 'Contrat','form_type' => EmployeContractType::class,[
'label' => "Accès a l'application",'form_type' => EmployeAccessType::class,]
];
}
}
这是我的 /**
* Class ContractType
* @package App\Form\User\Stepper
*/
class ContractType extends AbstractType
{
/**
* @var EntityManagerInterface
*/
private $manager;
/**
* ContractType constructor.
*/
public function __construct(EntityManagerInterface $manager)
{
$this->manager = $manager;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder,array $options)
{
$builder
->add('type',EntityType::class,[
"class" => TypeContract::class,'label' => 'Type de contrat',"required" => true
])
->add('startDate',DateType::class,[
'label' => 'Date de début','widget' => 'single_text',"required" => false,])
->add('endDate',[
'label' => 'Date de fin',])
->add('isInsertion',CheckboxType::class,[
'label' => 'Insertion professionnelle',])
->add('hourlyRate',MoneyType::class,[
'label' => 'Taux horaire',])
;
$formContractTypeModifier = function (FormInterface $form,$contractType = null) {
if($contractType != null && !$contractType instanceof TypeContract){
$contractType = $this->manager->getRepository(TypeContract::class)->find($contractType);
}
if($contractType != null && $contractType instanceof TypeContract && $contractType->getSlug() === ContractTypeEnum::INTERIM){
$form->add('company',[
"class" => Company::class,"label" => "Entreprise","required" => true,]);
}
};
// Events listener to modify the form regarding PRE_SET_DATA datas
$builder->addEventListener(FormEvents::PRE_SET_DATA,function (FormEvent $event) use ($formContractTypeModifier){
/** @var array $data */
$data = $event->getData();
/** TypeContract $contractType */
$contractType = isset($data['type']) ? $data['type'] : null;
//Add elements to form
$formContractTypeModifier($event->getForm(),$contractType);
});
// Events listener to modify the form regarding PRE_SUBMIT
$builder->addEventListener(FormEvents::PRE_SUBMIT,$contractType);
});
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => null,]);
}
}
视图:
add_user.html.twig
step_3.html.twig 视图是这样的:
{% if flow.getCurrentStepNumber() == 3 %}
{% include 'app/users/users/stepper/_step_3.html.twig' %}
{% else %}
{{ form_errors(form) }}
{{ form_rest(form) }}
{% endif %}
- 问题/问题:
我的问题是,我不确定 CraueFlow 是否按照我将它用于 FormEvent 的方式工作,而且我没有找到任何文档。
当我尝试我刚刚在这个问题中提出的方式时,我从我的 Ajax 调用中得到了一个结果,其中包含我的 Flow 的第一步。结果是 {{ form_row(form.contracts.type) }}
{% if form.contracts.company is defined %}
{{ form_row(form.contracts.company) }}
{% endif %}
{{ form_row(form.contracts.startDate) }}
{{ form_row(form.contracts.endDate) }}
{{ form_row(form.contracts.hourlyRate) }}
{{ form_row(form.contracts.isInsertion) }}
<script>
$( document ).ready(function() {
$('#employe_contract_contracts_type').on('change',function() {
$.ajax({
url : $form.attr('action'),type: $form.attr('method'),data : data,success: function(html) {
console.log(html);
console.log($(html));
$('#add_employe_step_3_container').replaceWith($(html).find('#add_employe_step_3_container'));
}
});
});
});
</script>
没有在我的容器中加载任何东西,因为它没有被找到。
当我进入下一步然后回到第三步时,新的 $('#add_employe_step_3_container').replaceWith($(html).find('#add_employe_step_3_container'));
字段出现在我的第 3 步中,因为全局表单似乎已更新并且 formEvent 已正常工作。
有什么想法或例子吗?
解决方法
为了刷新表单并重新加载错误和控件,我只需要渲染表单而不调用 $flow->nextStep()
/**
* @Route("/user/add",name="user_add")
*/
public function add(Request $request,UserPasswordEncoderInterface $encoder,UniquePasswordResetToken $uniqueToken){
$employe = new Employe();
$flow = $this->addUserFlow;
$flow->bind($employe);
// form of the current step
$form = $flow->createForm();
if ($flow->isValid($form)) {
$flow->saveCurrentStepData($form);
if ($request->isXmlHttpRequest()) {
$form = $flow->createForm();
} else {
if ($flow->nextStep()) {
// form for the next step
$form = $flow->createForm();
} else {
//Persist user
$this->manager->persist($employe);
$this->manager->flush();
//Persist change password user token
$this->manager->persist($uniqueToken->getToken($employe));
$this->manager->flush();
//Reset flow to create new user
$flow->reset();
//Redirect to new user detail page
return $this->redirect($this->generateUrl('user_edit_personnal_info',array('id' => $employe->getId())));
}
}
}
return $this->render('app/users/users/add.html.twig',[
'form' => $form->createView(),'flow' => $flow,'employe' => $employe
]);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。