我一直在尝试提交一个将 Question 对象添加到数据库中的表单。
但每次我这样做时,都会出现错误“CSRF 令牌无效。请尝试重新提交表单”。
在我的表单内容字段中,我附加了这个插件,它是一个与 Stack Overflow 相同的编辑器。
在我的表单标签字段中,我附上了这个标签自动完成。
这是我的控制器代码:
/**
* Creates a new Question entity.
*
* @Route("/ask", name="question_create")
* @Method("POST")
* @Template("VerySoftAskMeBundle:Question:ask.html.twig")
*/
public function createAction(Request $request) {
$entity = new Question();
$form = $this->createCreateForm($entity);
$tags = $this->getDoctrine()->getRepository('VerySoftAskMeBundle:Tag')->findAll();
date_default_timezone_set('Asia/Manila');
$entity->setDateOfPost(new \DateTime());
$entity->setOwner($this->getUser());
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('question_show', array('id' => $entity->getId())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
'tags' => $tags
);
}
/**
* Creates a form to create a Question entity.
*
* @param Question $entity The entity
*
* @return Form The form
*/
private function createCreateForm(Question $entity) {
$form = $this->createForm(new QuestionType(), $entity, array(
'action' => $this->generateUrl('question_create'),
'method' => 'POST',
'em' => $this->getDoctrine()->getEntityManager()
));
$form->add('submit', 'submit', array('label' => 'Ask'));
return $form;
}
/**
*
* @Route("/ask", name="ask")
* @Security( "has_role( 'ROLE_USER' )" )
* @Method("GET")
* @Template
*/
public function askAction() {
$tags = $this->getDoctrine()->getRepository('VerySoftAskMeBundle:Tag')->findAll();
$entity = new Question();
$form = $this->createCreateForm($entity);
return array(
'entity' => $entity,
'form' => $form->createView(),
'tags' => $tags
);
}
我为我的标签字段制作了一个数据转换器,它将输入标签转换为标签对象。
class TagTransFormer implements DataTransformerInterface {
/**
* @var ObjectManager
*/
private $om;
/**
* @param ObjectManager $om
*/
public function __construct(ObjectManager $om) {
$this->om = $om;
}
/**
* Transforms an object (issue) to a string (number).
*
* @return ArrayCollection
*/
public function transform($tags) {
return $tags;
}
/**
* Transforms a string (number) to an object (issue).
*
* @param string $number
*
* @return ArrayCollection
*
* @throws TransformationFailedException if object (issue) is not found.
*/
public function reverseTransform($ids) {
$tags = array();
if (!$ids) {
return null;
}
$repo = $this->om
->getRepository('VerySoftAskMeBundle:Tag');
$idsArray = explode(",", $ids);
foreach ($idsArray as $id) {
$tags[] = $repo->findOneByName($id);
}
return $tags;
}
}
这是我的表单类:
class QuestionType extends AbstractType {
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
$entityManager = $options['em'];
$transformer = new TagTransFormer($entityManager);
$builder
->add('title', 'text')
->add('content', 'textarea')
->add($builder->create('tags', 'text')
->addModelTransformer($transformer)
);
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'VerySoft\AskMeBundle\Entity\Question'
))
->setRequired(array(
'em',
))
->setAllowedTypes(array(
'em' => 'Doctrine\Common\Persistence\ObjectManager',
));
}
/**
* @return string
*/
public function getName() {
return 'verysoft_askmebundle_question';
}
}
我的树枝模板:
<div id="askDiv" style="padding-bottom: 90px;">
{{ form_start(form, { 'attr' : { 'novalidate' : 'novalidate', 'class' : 'col-md-offset-3 form-control-static col-md-7' } }) }}
<div class="col-lg-12" style="padding: 0px; margin-bottom: 30px;">
<span class="askLabels col-lg-1 text-left">{{ form_label(form.title) }}</span>
{{form_widget(form.title, { 'attr' : { 'class' : 'form-control col-lg-11' } })}}
</div>
{{ form_widget(form.content, { 'attr' : { 'class' : 'col-lg-12' } }) }}
<div class="col-lg-12" style="padding: 0px; margin-top: 20px;">
<label class="col-lg-1 text-left askLabels" for="tagField">Tags</label>
<div class="col-lg-8">
{{ form_widget(form.tags) }}
</div>
{% if app.user.reputation >= 100 %}
<a id="addTag" title="Add New Tag" data-toggle="tooltip modal" data-placement="left" class="col-lg-3" href="#"><i class="fa fa-plus-circle"></i></a>
<div id="mymodal" class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Add New Tag</h4>
</div>
<div class="modal-body">
<label for="tagName">Tag Name: </label>
<input id="tagName" class="form-control" type="text"/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Add Tag</button>
</div>
</div>
</div>
</div>
{% endif %}
</div>
<div style="margin-top: 20px; ">
{{ form_widget(form.submit, { 'attr' : { 'class' : 'col-md-offset-4 col-md-4 btn btn-primary' } }) }}
</div>
<p>
title error{{ form_errors(form.title) }}
</p>
<p>
content error{{ form_errors(form.content) }}
</p>
<p>
tag error{{ form_errors(form.tags) }}
</p>
<p>
form error{{ form_errors(form) }}
</p>
脚本:
$(document).ready(function(){
$("textarea").pagedownBootstrap();
var zeTags = ["{{ tags|join('", "')|raw }}"];
$('#verysoft_askmebundle_question_tags').tagit({
availableTags: zeTags,
tagLimit: 5,
beforeTagAdded: function(event, ui) {
if ($.inArray(ui.tagLabel, zeTags) == -1)
return false;
}
});
});