[英]Symfony2: manually submit a form without class via AJAX
We have an old website where I have implemented a form that is sent by AngularJS to a PHP script and after processing an email message get sent.我们有一个旧网站,我在其中实现了一个表单,该表单由 AngularJS 发送到 PHP 脚本,并在处理完电子邮件后发送。 If the form is not valid the PHP script returns a JSON with the validation errors.如果表单无效,PHP 脚本将返回带有验证错误的 JSON。 Since we already use Symfony for some other applications (REST APIs), I thought it would be nice to reimplement my plain PHP script in Symfony.由于我们已经将 Symfony 用于其他一些应用程序(REST API),我认为在 Symfony 中重新实现我的普通 PHP 脚本会很好。
For the sake of simplicity I put only a small but relevant fragment of my code.为简单起见,我只放了一小段但相关的代码片段。 This is what I have:这就是我所拥有的:
HTML (ng-app is bound on body tag, not shown here): HTML(ng-app 绑定在 body 标签上,此处未显示):
<form name="infoscreenForm" class="form-horizontal" enctype="multipart/form-data" ng-controller="FormController">
<div class="form-group">
<div class="col-lg-1 control-label">*</div>
<div class="col-lg-11 input-group">
<input type="text" class="form-control" id="contact_person"
name="contact_person" ng-model="formData.contactPerson"
placeholder="Kontaktperson">
</div>
<span class="text-warning" ng-show="errors.contactPerson">
{{ errors.contactPerson }}
</span>
</div>
<div class="form-group">
<div class="col-lg-1 control-label">*</div>
<div class="col-lg-11 input-group">
<span class="input-group-addon">@</span>
<input type="email" class="form-control" id="email" name="email"
ng-model="formData.email" placeholder="E-Mail">
</div>
<span class="text-warning" ng-show="errors.email">
{{ errors.email }}
</span>
</div>
<div class="form-group">
<div class="col-lg-1 control-label"> </div>
<div class="col-lg-11 input-group">
<input type="file" class="form-control" id="file" name="file"
file-model="formData.file"
accept="application/pdf,image/jpeg,image/png">
</div>
<span class="text-warning" ng-show="errors.file">
{{ errors.file }}
</span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default" id="submit"
name="submit" ng-click="submitForm()">
Formular absenden
</button>
</div>
</form>
JS: JS:
var app = angular.module('InfoscreenApp', []);
app.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function () {
scope.$apply(function () {
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
app.factory('multipartForm', ['$http', function ($http) {
return {
post : function (uploadUrl, data) {
var fd = new FormData();
for (var key in data) {
fd.append(key, data[key]);
}
return $http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers : { 'Content-Type': undefined }
});
}
};
}]);
app.controller('FormController', ['$scope', 'multipartForm', function ($scope, multipartForm) {
$scope.formData = {};
$scope.submitForm = function () {
var uploadUrl = 'http://localhost:8000/infoscreen';
multipartForm.post(uploadUrl, $scope.formData)
.then(function (data) {
console.log(data);
if (data.success) {
$scope.message = data.data.message;
console.log(data.data.message);
} else {
$scope.errors = data.data.errors;
}
});
};
}]);
With the plain PHP script everything works fine.使用普通的 PHP 脚本一切正常。 Here is what I tried to do in Symfony:这是我在 Symfony 中尝试做的:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Email;
class DefaultController extends Controller
{
/**
* @Route("/infoscreen", name="infoscreen")
*/
public function infoscreenAction(Request $request)
{
$defaultData = array('message' => 'infoscreenForm');
$form = $this->createFormBuilder($defaultData)
->add('contactPerson', TextType::class, array(
'constraints' => array(
new NotBlank(),
)
))
->add('email', EmailType::class, array(
'constraints' => array(
new NotBlank(),
new Email(),
)
))
->add('file', FileType::class)
->add('submit', SubmitType::class)
->getForm();
;
$form->submit($request->request->get($form->getName()));
$data = $form->getData();
if ($form->isValid()) {
echo 'Alles ok';
// send an email
}
$errors = array();
$validation = $this->get('validator')->validate($form);
foreach ($validation as $error) {
$errors[$error->getPropertyPath()] = $error->getMessage();
}
$response = new Response();
$response->setContent(json_encode(array(
'form_data' => $data,
'errors' => $errors,
)));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
}
CSRF is disabled in config.yml
. CSRF 在config.yml
被禁用。 The form is not bound to an entity class.表单未绑定到实体类。 After submitting the form I get the following object in the console:提交表单后,我在控制台中得到以下对象:
{
data: Object,
status: 200,
config: Object,
statusText: "OK"
}
The important part is in data: Object
:重要的部分是data: Object
:
{
form_data: {
contactPerson: null,
email: null,
message: "infoscreenForm",
file: null
},
errors : {
children[contactPerson].data = "This value should not be blank",
children[email].data = "This value should not be blank"
}
}
This happens when I submit the form with some values entered in the fields.当我提交表单并在字段中输入一些值时会发生这种情况。 It seems that the submitted data is not bound to the form in the controller.似乎提交的数据没有绑定到控制器中的表单。 I'm probably missing something, but I stuck here and have no idea how to proceed.我可能遗漏了一些东西,但我被困在这里,不知道如何继续。 I tried with $form->bind($request)
, $form->handleRequest($request)
and few other things, but it didn't work.我尝试了$form->bind($request)
, $form->handleRequest($request)
和其他一些东西,但没有用。 Even if I bind the fields individually, I still don't get their values in the form.即使我单独绑定字段,我仍然没有在表单中获取它们的值。
Can somebody please help me.有人能帮帮我吗。
Thanks in advance.提前致谢。
Try尝试
$this->get('form.factory')->createNamedBuilder(null, 'form', $defaultData)
instead of代替
$this->createFormBuilder($defaultData)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.