首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Symfony 5表单:2动态选择

Symfony 5表单:2动态选择
EN

Stack Overflow用户
提问于 2022-02-08 18:56:00
回答 1查看 289关注 0票数 -1

我正在使用Symfony 5。我已经成功地将两个带有表单事件的选择框连接起来,但是我需要有三个动态选择框。这是我的实体之间的关系:类别(家庭) -> sub_category(sous_famille) -> sub_sub_category (sous_sous_famille)。sub_sub_category链接到这样的项目实体:

一个范畴->多sub_categorys

A sub_category ->多sub_sub_category

A sub_sub_category ->多篇文章

当我添加一篇新文章时,我应该能够选择一个类别,并根据类别选择更新sub_category下拉列表;在我选择了一个sub_sub_category下拉列表之后,sub_sub_category下拉列表也是一样的。我为类别和sub_category制作了一段法语视频,因为Symfony指南中的一段不起作用(我不知道为什么)。这是类别(家庭)实体:

代码语言:javascript
复制
/**
 * @ORM\Entity(repositoryClass=FamilleRepository::class)
 * @UniqueEntity("fam_code")
 */
class Famille
{

    /**
     * @ORM\Id
     * @ORM\Column(type="string", length=255,unique=true)
     * @Assert\NotBlank
     */
    private $fam_code;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank
     */
    private $fam_libelle_a;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank
     */
    private $fam_libelle_f;

    /**
     * @ORM\OneToMany(targetEntity=SousFamille::class, mappedBy="fam_code")
     * 
     */
    private $sousFamilles;
...
}

这是sub_category(sous_famille)实体:

代码语言:javascript
复制
/**
 * @ORM\Entity(repositoryClass=SousFamilleRepository::class)
 * @UniqueEntity("sf_code")
 */
class SousFamille
{

    /**
     * @ORM\Id
     * @ORM\Column(type="string", length=255, unique=true)
     * @Assert\NotBlank
     */
    private $sf_code;

    /**
     * 
     * @ORM\ManyToOne(targetEntity=Famille::class, inversedBy="sousFamilles")
     * @ORM\JoinColumn(name="fam_code", referencedColumnName="fam_code",nullable=false)
     * @Assert\NotBlank
     */
    private $fam_code;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank
     */
    private $sf_libelle_a;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank
     */
    private $sf_libelle_f;

    /**
     * @ORM\OneToMany(targetEntity=SousSousFamille::class, mappedBy="sf_code")
     */
    private $sousSousFamilles;
...

}

这是sub_sub_category(sous_sous_famille):

代码语言:javascript
复制
/**
 * @ORM\Entity(repositoryClass=SousSousFamilleRepository::class)
 * @UniqueEntity("ssf_code")
 */
class SousSousFamille
{

    /**
     * @ORM\Id
     * @ORM\Column(type="string", length=255,unique=true)
     * @Assert\NotBlank
     */
    private $ssf_code;

    /**
     * @ORM\ManyToOne(targetEntity=SousFamille::class, inversedBy="sousSousFamilles")
     * @ORM\JoinColumn(name="sf_code", referencedColumnName="sf_code",nullable=false)
     * @Assert\NotBlank
     */
    private $sf_code;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank
     */
    private $ssf_libelle_a;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank
     */
    private $ssf_libelle_f;

    /**
     * @ORM\OneToMany(targetEntity=Article::class, mappedBy="ssf_code")
     */
    private $articles;

    /**
     * @return Collection|Article[]
     */
    public function getArticles(): Collection
    {
        return $this->articles;
    }
...
}

这是一条实体:

代码语言:javascript
复制
/**
 * @ORM\Entity(repositoryClass=ArticleRepository::class)
 * @UniqueEntity("art_code")
 */

class Article
{

 /**
 * @ORM\Id
 * @ORM\Column(type="string", length=255,unique=true)
 * @Assert\NotBlank
 */
private $art_code;

/**
 * @ORM\ManyToOne(targetEntity=SousSousFamille::class, inversedBy="articles")
 * @ORM\JoinColumn(name="ssf_code", referencedColumnName="ssf_code",nullable=false)
 * @Assert\NotBlank
 */
private $ssf_code;

/**
 * @ORM\Column(type="string", length=255)
 * @Assert\NotBlank
 */
private $art_libelle_a;

/**
 * @ORM\Column(type="string", length=255)
 * @Assert\NotBlank
 */
private $art_libelle_f;
...

}

更新了!我有两个表单,一个ArticleType表单和一个CategorySelectionType表单,如下所示:

CategorySelectionType:

代码语言:javascript
复制
class CategorySelectionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('fam_code', EntityType::class, [
                'class' => Famille::class,
                'placeholder' => 'Choisir une Catégorie',
                'required' => 'true',
                'mapped' => false,
                'query_builder' => function (FamilleRepository $code) {
                    return $code->createQueryBuilder('c')->orderBy('c.fam_libelle_f', 'ASC');
                }
            ])
            ->add('sf_code', EntityType::class, [
                'class' => SousFamille::class,
                'mapped' => false,
                'required' => true,
                'placeholder' => 'Choisir une Sous Catégorie',
                'query_builder' => function (SousFamilleRepository $code) {
                    return $code->createQueryBuilder('c')->orderBy('c.sf_libelle_f', 'ASC');
                }
            ]);
        $fm = function (FormInterface $form, Famille $fam = null) {
            $sf = (null === $fam) ? [] : $fam->getSousFamilles();
            $form->add('sf_code', EntityType::class, [
                'class' => SousFamille::class,
                'choices' => $sf,
                'mapped' => false,
                'required' => true,
                'placeholder' => 'Choisir une Sous Catégorie',
                'query_builder' => function (SousFamilleRepository $code) {
                    return $code->createQueryBuilder('c')->orderBy('c.sf_libelle_f', 'ASC');
                }

            ]);
        };
        $builder->get('fam_code')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $e) use ($fm) {
                $fam = $e->getForm()->getData();
                $fm($e->getForm()->getParent(), $fam);
            }
        );
    }
..}

ArticleType:

代码语言:javascript
复制
    class ArticleType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('art_code', TextType::class, ['label' => 'Code Article', 'required' => 'true'])
            ->add('art_libelle_a', TextType::class, ['label' => 'Libellé Article en Arabe', 'required' => 'true'])
            ->add('art_libelle_f', TextType::class, ['label' => 'Libellé Article en Français', 'required' => 'true'])
            ->add('ssf_code', EntityType::class, [
                'class' => SousSousFamille::class,
                'choices' => $options['ssfs'],
                'placeholder' => 'Choisir une Sous Sous Catégorie',
                'required' => 'true',
                'query_builder' => function (SousSousFamilleRepository $code) {
                    return $code->createQueryBuilder('c')->orderBy('c.ssf_libelle_f', 'ASC');
                }
            ]);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Article::class,
            'ssfs' => [],
        ]);
    }
}

在主计长中:

代码语言:javascript
复制
/**
     * @Route("/ajoutArticle", name="app_ajoutA")
     */
    public function ajoutA(Request $req, EntityManagerInterface $em, SousFamilleRepository $ssrep): Response
    {
        $step = 1;
        $art = new Article();
        $sel = $this->createForm(CategorySelectionType::class);
        $sel->handleRequest($req);
        $ssf = [];
        if ($sel->isSubmitted() && $sel->isValid()) {
            $rep = $sel->get('sf_code')->getData();
            $ssf = $ssrep->find($rep->getSFCODE())->getSousSousFamilles();
            $step = 2;
        }
        $form = $this->createForm(ArticleType::class, $art, ['ssfs' => $ssf]);
        dd($req->get('ssf_code'));
        $form->handleRequest($req);

        if ($form->isSubmitted() && $form->isValid()) {

            $em->persist($art);
            $em->flush();
            $this->addFlash('success', 'Article créé avec succès !');
            return $this->redirectToRoute('app_article');
        }

        return $this->render('fr/gestion-articles/Articles/ajoutA.html.twig', ['form' => $form->createView(), 'sel' => $sel->createView(), 'step' => $step]);
    }

下面是我的脚本模板:

代码语言:javascript
复制
<script>
window.onload = () => {
let fam = document.querySelector("#category_selection_fam_code");
fam.addEventListener("change", function () {
let form = this.closest("form").closest("form");
let data = this.name + "=" + this.value;
fetch(form.action, {
method: form.getAttribute("method"),
body: data,
headers: {
"Content-Type": "application/x-www-form-urlencoded;charset:ut_8"
}
}).then(response => response.text()).then(html => {
let content = document.createElement("html");
content.innerHTML = html;
let nouvSelect = content.querySelector("#category_selection_sf_code");
document.querySelector("#category_selection_sf_code").replaceWith(nouvSelect);
})
});
}
</script>

但是我遇到了新的问题,当提交表单(ArticleType)时,字段ssf_code被设置为null --我不知道为什么它没有使用我选择的值。你能帮帮我吗? 1:https://www.youtube.com/watch?v=f7tdb30evUk

EN

回答 1

Stack Overflow用户

发布于 2022-02-09 12:39:15

我认为,您的类别类的类图需要是一个递归关系,在这里您需要添加一个父类attribut,因为您所做的方式并不灵活和非常有限(假设您需要添加一个未来的子类别SousSousSousCategory)。如果您需要向家庭添加attribut或方法,则需要向每个子类别添加相同的代码,代码的维护将很困难。

检查此图像以了解

你需要这样设置你的班级

代码语言:javascript
复制
<?php

namespace App\Entity;

use App\Repository\FamilleRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=FamilleRepository::class)
 */
class Famille
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $fam_code;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $fam_libelle_a;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $fam_libelle_f;

    /**
     * @ORM\ManyToOne(targetEntity=Famille::class, inversedBy="sous_familles")
     */
    private $parent;

    /**
     * @ORM\OneToMany(targetEntity=Famille::class, mappedBy="parent")
     */
    private $sous_familles;

    public function __construct()
    {
        $this->sous_familles = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getFamCode(): ?string
    {
        return $this->fam_code;
    }

    public function setFamCode(string $fam_code): self
    {
        $this->fam_code = $fam_code;

        return $this;
    }

    public function getFamLibelleA(): ?string
    {
        return $this->fam_libelle_a;
    }

    public function setFamLibelleA(string $fam_libelle_a): self
    {
        $this->fam_libelle_a = $fam_libelle_a;

        return $this;
    }

    public function getFamLibelleF(): ?string
    {
        return $this->fam_libelle_f;
    }

    public function setFamLibelleF(string $fam_libelle_f): self
    {
        $this->fam_libelle_f = $fam_libelle_f;

        return $this;
    }

    public function getParent(): ?self
    {
        return $this->parent;
    }

    public function setParent(?self $parent): self
    {
        $this->parent = $parent;

        return $this;
    }

    /**
     * @return Collection|self[]
     */
    public function getSousFamilles(): Collection
    {
        return $this->sous_familles;
    }

    public function addSousFamille(self $sousFamille): self
    {
        if (!$this->sous_familles->contains($sousFamille)) {
            $this->sous_familles[] = $sousFamille;
            $sousFamille->setParent($this);
        }

        return $this;
    }

    public function removeSousFamille(self $sousFamille): self
    {
        if ($this->sous_familles->contains($sousFamille)) {
            $this->sous_familles->removeElement($sousFamille);
            // set the owning side to null (unless already changed)
            if ($sousFamille->getParent() === $this) {
                $sousFamille->setParent(null);
            }
        }

        return $this;
    }
}

此代码由php /console make:entity命令生成

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

https://stackoverflow.com/questions/71039400

复制
相关文章

相似问题

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