我正在学习http://symfony.com/doc/current/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms上的教程
这个想法是我得到了3类动物=>种族在创造一个新的动物,我想要动态地改变种族的选择取决于种族。
这是我的类: Race
class Race
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="nom", type="string", length=255, unique=true)
*/
private $nom;
/**
* @ORM\ManyToOne(targetEntity="Rendy\AppBundle\Entity\Espece", inversedBy="race")
* @ORM\JoinColumn(name="espece_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
*/
private $espece;类动物
class Animal
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="Nom", type="string", length=30)
*/
private $nom;
/**
* @var Espece
*
*
* @ORM\ManyToOne(targetEntity="Espece")
* @ORM\JoinColumn(name="espece_id", referencedColumnName="id", onDelete="CASCADE")
*/
private $espece;
/**
* @var string
*
* @ORM\ManyToOne(targetEntity="Race")
* @ORM\JoinColumn(name="race_id", referencedColumnName="id", onDelete="CASCADE")
*/
private $race;和类别说明:
class Espece
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="nom", type="string", length=255, unique=true)
*/
private $nom;
/**
* @ORM\OneToMany(targetEntity="Race", mappedBy="espece")
* @ORM\JoinColumn(name="race_id", referencedColumnName="id")
*/
private $race;
/**
* Get race
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getRace()
{
return $this->race;
}这是我的控制器
public function newAction(Request $request)
{
$animal = new Animal();
$form = $this->createForm(AnimalType::class, $animal);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// do something after
}
return $this->render('RendyAppBundle:animal:new.html.twig', array(
'form' => $form->createView(),
));
}这是我的AnimalType表单
class AnimalType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('nom');
$builder->add('espece', EntityType::class, array(
'class' => 'RendyAppBundle:Espece',
'choice_label' => 'nom',
'placeholder' => '',
));
$formModifier = function (FormInterface $form, Espece $espece = null) {
$race = null === $espece ? array() : $espece->getRace();
$form->add('race', EntityType::class, array(
'class' => 'RendyAppBundle:Race',
'choice_label' => 'nom',
'placeholder' => '',
'choices' => $race,
));
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier) {
$data = $event->getData();
$formModifier($event->getForm(), $data->getEspece());
}
);
$builder->get('espece')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
$espece = $event->getForm()->getData();
$formModifier($event->getForm()->getParent(), $espece);
}
);结束视图!
{% block body%}
{{ form_start(form) }}
{# render the task's only field: description #}
{{ form_row(form.nom) }}
{{ form_row(form.espece, {'id': 'test','attr': {'onChange': 'changed()'}}) }}
{{ form_row(form.race, {'id': 'animal_race', 'attr': { 'class': 'form-control'}}) }}
{{ form_row(form.sexe) }}
{{ form_row(form.age) }}
{{ form_row(form.puce) }}
{{ form_row(form.poids) }}
<h3>Comportement</h3>
<ul class="comportement">
{# iterate over each existing tag and render its only field: name #}
{% for comportement in form.comportement %}
<li>{{ form_row(comportement.name) }}</li>
{% endfor %}
</ul>
{{ form_end(form) }}
{% endblock %}
{% block ajax %}
<script>
function changed() {
var espece = $('#test');
// ... retrieve the corresponding form.
var $form = $('#form');
console.log($form);
// Simulate form data, but only include the selected sport value.
var data = {};
data[espece.attr('nom')] = espece.val();
// Submit data via AJAX to the form's action path.
jQuery.ajax({
url : $form.attr('action'),
type: "POST",
data: data,
success: function (html) {
console.log(html)
$("#animal_race").replaceWith(
// ... with the returned one from the AJAX response.
$(html).find("#animal_race")
);
// Position field now displays the appropriate positions.
}
});
}
</script>
{% endblock %}当我更改"Especes“的值时,Ajax函数会被调用,但我的字段Race仍然为空...(我的block ajax在block javascripts之后)
Ajax请求: POST参数键值未定义"2“
对于信息,当我做一个简单的Animal->getEspece()->getRace()时,我得到了一个包含好信息的数组。
我搜索了,尝试,搜索了尝试,我想我错过了一些东西。
谢谢你的帮助
发布于 2017-07-11 22:55:53
这是我正在工作的代码
控制器:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\Animal;
use AppBundle\Form\Type\AnimalType;
// ...
class MeetupController extends Controller
{
/**
* @Route("/animal")
*/
public function animalAction(Request $request)
{
$meetup = new Animal();
$form = $this->createForm(AnimalType::class, $meetup);
$form->handleRequest($request);
if ($form->isValid()) {
// ... save the meetup, redirect etc.
}
return $this->render(
':Meetup:animal.html.twig',
array('form' => $form->createView())
);
}
// ...
}animal.html.twig
{% block body %}
{{ form_start(form) }}
{{ form_row(form.espece) }}
{{ form_row(form.race) }}
{# ... #}
{{ form_end(form) }}
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script>
var $espece = $('#animal_espece');
// When especegets selected ...
$espece.change(function() {
console.log("Dans la fonction Change");
// ... retrieve the corresponding form.
var $form = $(this).closest('form');
// Simulate form data, but only include the selected espece value.
var data = {};
data[$espece.attr('name')] = $espece.val();
// Submit data via AJAX to the form's action path.
$.ajax({
url : $form.attr('action'),
type: $form.attr('method'),
data : data,
success: function(html) {
// Replace current race field ...
$('#animal_race').replaceWith(
// ... with the returned one from the AJAX response.
$(html).find('#animal_race')
);
// race field now displays the appropriate positions.
}
});
});
</script>
{% endblock %}AnimalType
<?php
namespace AppBundle\Form\Type;
use AppBundle\Entity\Espece;
use AppBundle\Entity\Animal;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormInterface;
// ...
class AnimalType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('espece', EntityType::class, array(
'class' => 'AppBundle:Espece',
'placeholder' => '',
))
;
$formModifier = function (FormInterface $form, Espece $sport = null) {
$positions = null === $sport ? array() : $sport->getAvailablePositions();
$form->add('race', EntityType::class, array(
'class' => 'AppBundle:Race',
'placeholder' => '',
'choices' => $positions,
));
};
$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->getEspece());
}
);
$builder->get('espece')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
$sport = $event->getForm()->getData();
$formModifier($event->getForm()->getParent(), $sport);
}
);
}
}观察实体
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* Espece
*
* @ORM\Table(name="espece")
* @ORM\Entity(repositoryClass="AppBundle\Repository\EspeceRepository")
*/
class Espece
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="nom", type="string", length=255, unique=true)
*/
private $nom;
/**
* @var Collection|Race[]
*
* @ORM\OneToMany(targetEntity="Race", mappedBy="espece")
*/
protected $racesdisponibles;
public function __constructor()
{
$this->racesdisponibles = new ArrayCollection();
}
public function __toString()
{
return $this->nom;
}和Race实体
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Race
*
* @ORM\Table(name="race")
* @ORM\Entity(repositoryClass="AppBundle\Repository\RaceRepository")
*/
class Race
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="nom", type="string", length=255, unique=true)
*/
private $nom;
/**
* @var Espece
* @ORM\ManyToOne(targetEntity="Espece", inversedBy="racesdisponibles")
* @ORM\JoinColumn(name="espece_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
*/
private $espece;
public function __toString()
{
return $this->nom;
}如果需要,给我发一条消息,我会给你发送捆绑包:)我的错误在这里
data[espece.attr('nom')] = espece.val();关于DOM,好的回答是
data[espece.attr('name')] = espece.val();我认为“名字”是体育实体的属性,而不是<div name="beeeeer">的属性
希望这能帮助到一些人
发布于 2017-06-25 21:59:19
您将post请求(在AJAX调用中)发送到与加载页面(newAction的请求)相同的URL (表单操作url)。如果您的newAction方法实际上是向传入的POST/GET请求发送数据,那么这可能会起作用,但这里的情况并非如此。
我建议始终为POST请求创建单独的路由(并因此创建单独的控制器方法)。您也不能按“原样”发送数据(即从数据库检索数据时在对象中)。例如,您必须将其转换为JSON。您可以直接将整个对象转换为JSON (https://symfony.com/doc/current/components/serializer.html),但只获取所需的信息可能会更好。为此,您可以创建一个保存此信息的数组
总而言之,你的控制器方法看起来像这样:
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
public function getRacesJsonAction(Request $request)
{
//Get the race data here that you want to send (edit to your own needs)
$race = $Animal->getEspece()->getRace();
//Convert the entity directly to a JSON
$jsonContent = $serializer->serialize($race, 'json');
//create a response
$response = new Response($jsonContent);
$response->headers->set('Content-Type', 'application/json');
return $response;
}在你的前端,你必须将json解码成一个javascript数组,如下所示:
$.ajax({
type: 'POST',
url: url,
data: {
data: dataObj
},
dataType: 'json',
success: function(data) {
console.log('success');
//Obj is the array with information now
obj = JSON.parse(json);
},
error: function(data) {
console.log('fail');
}
});但是,您不能直接填充obj-array中的信息。您必须对其进行解析,因为HTML-dropdown中的每个条目都是这样包装的:
<ul>
</li>race1</li>
</li>race2</li>
</li>race3</li>
</ul>它是一个广泛的实现。我可能在语法上犯了错误,所以要小心。我也推荐你使用'FOSJsRoutingBundle',它可以让你从javascript中的路由创建url。您可能会使用它将路由的路径转换为保存url的javascript变量。
祝好运!
https://stackoverflow.com/questions/44741993
复制相似问题