首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Symfony动态表单提交表单

Symfony动态表单提交表单
EN

Stack Overflow用户
提问于 2017-06-25 08:02:26
回答 2查看 1.9K关注 0票数 0

我正在学习http://symfony.com/doc/current/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms上的教程

这个想法是我得到了3类动物=>种族在创造一个新的动物,我想要动态地改变种族的选择取决于种族。

这是我的类: Race

代码语言:javascript
复制
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;

类动物

代码语言:javascript
复制
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;

和类别说明:

代码语言:javascript
复制
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;
    }

这是我的控制器

代码语言:javascript
复制
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表单

代码语言:javascript
复制
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);
            }
        );

结束视图!

代码语言:javascript
复制
{% 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()时,我得到了一个包含好信息的数组。

我搜索了,尝试,搜索了尝试,我想我错过了一些东西。

谢谢你的帮助

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-11 22:55:53

这是我正在工作的代码

控制器:

代码语言:javascript
复制
<?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

代码语言:javascript
复制
{% 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

代码语言:javascript
复制
<?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);
            }
        );
    }

}

观察实体

代码语言:javascript
复制
<?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实体

代码语言:javascript
复制
<?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;
    }

如果需要,给我发一条消息,我会给你发送捆绑包:)我的错误在这里

代码语言:javascript
复制
data[espece.attr('nom')] = espece.val();

关于DOM,好的回答是

代码语言:javascript
复制
data[espece.attr('name')] = espece.val();

我认为“名字”是体育实体的属性,而不是<div name="beeeeer">的属性

希望这能帮助到一些人

票数 0
EN

Stack Overflow用户

发布于 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),但只获取所需的信息可能会更好。为此,您可以创建一个保存此信息的数组

总而言之,你的控制器方法看起来像这样:

代码语言:javascript
复制
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数组,如下所示:

代码语言: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中的每个条目都是这样包装的:

代码语言:javascript
复制
<ul>
</li>race1</li>
</li>race2</li>
</li>race3</li>
</ul>

它是一个广泛的实现。我可能在语法上犯了错误,所以要小心。我也推荐你使用'FOSJsRoutingBundle',它可以让你从javascript中的路由创建url。您可能会使用它将路由的路径转换为保存url的javascript变量。

祝好运!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44741993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档