我一直在使用Symfony 3构建Web应用程序,使用表单类型并在页面上呈现表单。我正在尝试使用Aurelia自定义元素在页面上呈现Symfony表单,然后将表单提交回Symfony。我已经到达了验证提交表单的阶段,但它从未通过验证。有人可以看一下以下代码并查看是否遗漏了什么吗?
表单类型:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use AppBundle\Service\PayeeService;
class PayeeType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class)
->add('category', ChoiceType::class, [
'choices' => [
'Uncategorized' => PayeeService::CATEGORY_UNCATEGORIZED,
'Installment Loan' => PayeeService::CATEGORY_INSTALLMENT_LOAN,
'Credit Card' => PayeeService::CATEGORY_CREDIT_CARD,
'Utility' => PayeeService::CATEGORY_UTILITY,
'Mortgage' => PayeeService::CATEGORY_MORTGAGE,
'Entertainment' => PayeeService::CATEGORY_ENTERTAINMENT
],
'choices_as_values' => true
])
->add('amount', MoneyType::class, ['currency' => 'USD', 'grouping' => true])
->add('frequency', ChoiceType::class, [
'choices' => [
'Recurring' => PayeeService::FREQUENCY_RECURRING,
'One-time' => PayeeService::FREQUENCY_ONETIME
],
'choices_as_values' => true
])
->add('method', ChoiceType::class, [
'choices' => [
'ACH' => PayeeService::PAY_METHOD_ACH,
'Check' => PayeeService::PAY_METHOD_CHECK
],
'choices_as_values' => true
])
->add('dateLastPaid', DateType::class)
->add('dueDate', DateType::class)
->add('gracePeriod', IntegerType::class)
->add('balance', MoneyType::class, ['currency' => 'USD', 'grouping' => true])
->add('active', CheckboxType::class, ['label' => 'Active', 'data' => true])
->add('save', SubmitType::class, ['label' => 'Save Payee'])
;
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Payee'
));
}
}
控制器:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
class FormController extends Controller
{
/**
* @Route("/_form/entity/{entity}", name="new_entity_form")
* @Method("GET")
*/
public function getFormForNewEntity(Request $request)
{
$rawName = $request->get('entity');
$content = $request->getContent();
$data = json_decode($content, true);
$formName = strtolower($rawName) . "_form";
$submitFunction = $data['submitFunction'];
$entityName = "AppBundle\Entity\\" . $rawName;
$entity = new $entityName();
$form = $this->createForm("\AppBundle\Form\\{$rawName}Type", $entity);
return $this->render('form/form.html.twig', [
'name' => $formName,
'form' => $form->createView(),
'submitFunction' => $submitFunction]);
}
/**
* @Route("/_form/entity/{entity}", name="new_entity_create")
* @Method("POST")
*/
public function saveFormForNewEntity(Request $request)
{
$em = $this->getDoctrine()->getManager();
$rawName = $request->get('entity');
$entityName = "AppBundle\Entity\\" . $rawName;
$entity = new $entityName();
$form = $this->createForm("\AppBundle\Form\\{$rawName}Type", $entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em->persist($entity);
$em->flush();
return new JsonResponse(['result' => true]);
} elseif ($form->isEmpty()) {
return new JsonResponse(['result' => false, 'errors' => 'form empty']);
} else {
return new JsonResponse(['result' => false, 'errors' => iterator_to_array($form->getErrors(true))]);
}
}
}
从twig表单:
{{ form_start(form, {'attr': {'id':name, 'role':'form', 'submit.delegate':submitFunction}}) }}
{{ form_widget(form) }}
{{ form_end(form) }}
Aurelia组件JS:
import {InlineViewStrategy} from 'aurelia-framework';
import {customElement, bindable, inject} from 'aurelia-framework';
import $ from 'jquery';
import {HttpClient} from 'aurelia-http-client';
import 'fetch';
@customElement('symfony-form')
@inject(Element)
export class SymfonyForm {
@bindable entity;
constructor(element) {
this.content = '';
this.http = new HttpClient();
this.http.configure(config => {
config
.withBaseUrl('http://localhost:8000/');
});
this.element = element;
}
bind(binding, override) {
return this.http.get('_form/entity/' + this.entity, {'submitFunction': 'submit()'})
//.then(response => response.html())
.then(response => {
this.content = response.response;
});
}
submit() {
// application/x-www-form-urlencoded
this.http.createRequest('_form/entity/' + this.entity)
.withHeader('Content-Type', 'application/x-www-form-urlencoded')
.asPost()
.withContent($(this.element).find('form').serialize())
.send()
.then(response => {
alert(response.response);
});
//alert('submitted ' + this.entity);
// return this.http.post('_form/entity/' + this.entity, $(this.element).find('form').serialize())
// .then(response => {
// alert(response.response);
// });
}
}
<template>
<form role="form" submit.delegate="submit()">
<div innerHTML.bind="content"></div>
</form>
</template>
<template>
<require from="form"></require>
<section class="au-animate">
<h2>${heading}</h2>
<form role="form" submit.delegate="submit()">
<div class="form-group">
<label for="fn">First Name</label>
<input type="text" value.bind="firstName" class="form-control" id="fn" placeholder="first name">
</div>
<div class="form-group">
<label for="ln">Last Name</label>
<input type="text" value.bind="lastName" class="form-control" id="ln" placeholder="last name">
</div>
<div class="form-group">
<label>Full Name</label>
<p class="help-block">${fullName | upper}</p>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<symfony-form entity="Payee"></symfony-form>
</section>
</template>
{{ form_start(form) }}{{ form_end(form) }}
,其中包括一些隐藏的CSFR字段。你可以使用{{ form_widget(form._token) }}
显式地呈现CSFR字段。我想这就是导致你的表单验证失败的原因。 - tftd