我想在文档中应用提交表单的动态生成示例,以使用Ajax创建与另一个相关的ans选择框。 http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-data
我创建了所有实体 SportMeetup ,体育和职位。我也创造了所有的关系。 现在我可以显示表格,所有运动都在选择框中正确显示,但代码ajax还没有工作。
实体运动与Postion相关
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Position", mappedBy="sport", cascade={"persist"})
*/
private $positions;
实体位置与Sport
相关 /**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Sport", inversedBy="positions", cascade={"persist"})
*/
private $sport;
实体SportMeetup 与体育和位置有关
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Sport")
*/
private $sport;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Position")
*/
private $position;
SportMeetupType
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
//........
use Symfony\Component\Form\FormInterface;
use AppBundle\Entity\Sport;
class SportMeetupType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name','text')
->add('sport', 'entity', array(
'class' => 'AppBundle:Sport',
'placeholder' => '',
'property' => 'name',
'attr' => array('id'=>'meetup_sport')
));
$formModifier = function (FormInterface $form, Sport $sport = null) {
$positions = null === $sport ? array() : $sport->getPostions();
$form->add('position', 'entity', array(
'class' => 'AppBundle:Position',
'placeholder' => '',
'choices' => $positions,
'property' => 'name',
'attr' => array('id'=>'meetup_position')
));
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier) {
// this would be your entity, i.e. SportMeetup
$data = $event->getData();
$formModifier($event->getForm(), $data->getSport());
}
);
$builder->get('sport')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
// It's important here to fetch $event->getForm()->getData(), as
// $event->getData() will get you the client data (that is, the ID)
$sport = $event->getForm()->getData();
// since we've added the listener to the child, we'll have to pass on
// the parent to the callback functions!
$formModifier($event->getForm()->getParent(), $sport);
}
);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\SportMeetup'
));
}
public function getName()
{
return 'sportmeetup';
}
}
控制器
public function createAction(Request $request)
{
$meetup = new SportMeetup();
$form = $this->createForm(new SportMeetupType(), $meetup);
$form->handleRequest($request);
if ($form->isValid()) {
// ... save the meetup, redirect etc.
}
if ($request->isXmlHttpRequest()){
$id = $request->request->get('id');
$em = $this->getDoctrine()->getManager();
$positions = $em->getRepository('AppBundle:Position')->findBySport($id);
$response = new Response();
$response->setContent(json_encode($positions));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
return $this->render(
'AppBundle:Dashboard/Sport-meetup:create.html.twig',
array('form' => $form->createView())
);
}
这是 form.twig
<form method="post" action="" class="form-horizontal" role="form" {{ form_enctype(form) }}>
<label for="form-field-mask-2">Name</label>
{{ form_widget(form.name) }}
{{ form_errors(form.name) }}
<br/>
<label for="form-field-mask-2">Sport</label>
{{ form_row(form.sport) }}
<br/>
<label>Position</label>
{{ form_row(form.position) }}
{{ form_rest(form) }}
<br><br>
<a href="javascript:history.back()" class="btn btn-default btn-sm radius-4"> <i
class='icon-remove bigger-110'></i> Cancel</a>
<button type="submit" class="btn btn-sm btn-success">Send <i
class="icon-arrow-right icon-on-right bigger-110"></i></button>
</form>
<script type="text/javascript">
var $sport = $('#meetup_sport');
// When sport gets selected ...
$sport.change(function () {
// ... retrieve the corresponding form.
var $form = $(this).closest('form');
// Simulate form data, but only include the selected sport value.
var data = {};
data[$sport.attr('name')] = $sport.val();
// Submit data via AJAX to the form's action path.
$.ajax({
url: '{{ path('dashboard_sport_meetup_new') }}',
type: 'POST',
data: data,
success: function (html) {
// Replace current position field ...
$('#meetup_position').replaceWith(
// ... with the returned one from the AJAX response.
$(html).find('#meetup_position')
);
// Position field now displays the appropriate positions.
}
});
});