Symfony 形式:Country State City 三个动态下拉菜单

如何解决Symfony 形式:Country State City 三个动态下拉菜单

您好,我使用的是 Symfony 5。我需要三个动态选择下拉列表。这是我的实体之间的关系:国家 -> 州 -> 城市。这些链接到这样的用户实体

当我添加一个新用户时,我应该能够选择一个国家并根据国家选择更新状态下拉菜单;在我选择了一个州后,城市下拉列表也是如此。我按照此处的官方 Symfony 指南为 Country 和 State 工作https://symfony.com/doc/current/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms 我应该如何管理添加第三个下拉列表?

    <?PHP

namespace App\Entity;

use App\Repository\UserRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use App\Entity\EmployeeDetails;

/**
 * @ORM\Entity(repositoryClass=UserRepository::class)
 * @UniqueEntity(fields={"email"},message="There is already an account with this email")
 */
class User implements UserInterface,PasswordAuthenticatedUserInterface
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    

    /**
     * @ORM\OnetoOne(targetEntity=EmployeeDetails::class,mappedBy="user_id",cascade={"persist","remove"})
     */
    private $employeeDetails;

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

    /**
     * @ORM\ManyToOne(targetEntity=Country::class,inversedBy="users")
     */
    private $country;

    /**
     * @ORM\ManyToOne(targetEntity=State::class,inversedBy="users")
     */
    private $state;

    /**
     * @ORM\ManyToOne(targetEntity=City::class,inversedBy="users")
     */
    private $city;


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

    
    public function getEmployeeDetails(): ?EmployeeDetails
    {
        return $this->employeeDetails;
    }

    public function setEmployeeDetails(?EmployeeDetails $employeeDetails): self
    {
        // unset the owning side of the relation if necessary
        if ($employeeDetails === null && $this->employeeDetails !== null) {
            $this->employeeDetails->setUserId(null);
        }

        // set the owning side of the relation if necessary
        if ($employeeDetails !== null && $employeeDetails->getUserId() !== $this) {
            $employeeDetails->setUserId($this);
        }

        $this->employeeDetails = $employeeDetails;

        return $this;
    }

    public function getDeleteData(): ?string
    {
        return $this->delete_data;
    }

    public function setDeleteData(string $delete_data): self
    {
        $this->delete_data = $delete_data;

        return $this;
    }

    public function getCountry(): ?Country
    {
        return $this->country;
    }

    public function setCountry(?Country $country): self
    {
        $this->country = $country;

        return $this;
    }

    public function getState(): ?State
    {
        return $this->state;
    }

    public function setState(?State $state): self
    {
        $this->state = $state;

        return $this;
    }

    public function getCity(): ?City
    {
        return $this->city;
    }

    public function setCity(?City $city): self
    {
        $this->city = $city;

        return $this;
    }

}

国家

<?PHP

namespace App\Entity;

use App\Repository\CountryRepository;
use App\Entity\State;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

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

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

    /**
     * @ORM\OnetoMany(targetEntity=State::class,mappedBy="country")
     */
    private $states;

    /**
     * @ORM\OnetoMany(targetEntity=City::class,mappedBy="country")
     */
    private $cities;

    /**
     * @ORM\OnetoMany(targetEntity=User::class,mappedBy="country")
     */
    private $users;

    public function __construct()
    {
        $this->states = new ArrayCollection();
        $this->cities = new ArrayCollection();
        $this->users = new ArrayCollection();
    }

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

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    /**
     * @return Collection|State[]
     */
    public function getStates(): Collection
    {
        return $this->states;
    }

    public function addState(State $state): self
    {
        if (!$this->states->contains($state)) {
            $this->states[] = $state;
            $state->setCountry($this);
        }

        return $this;
    }

    public function removeState(State $state): self
    {
        if ($this->states->removeElement($state)) {
            // set the owning side to null (unless already changed)
            if ($state->getCountry() === $this) {
                $state->setCountry(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|City[]
     */
    public function getCities(): Collection
    {
        return $this->cities;
    }

    public function addCity(City $city): self
    {
        if (!$this->cities->contains($city)) {
            $this->cities[] = $city;
            $city->setCountry($this);
        }

        return $this;
    }

    public function removeCity(City $city): self
    {
        if ($this->cities->removeElement($city)) {
            // set the owning side to null (unless already changed)
            if ($city->getCountry() === $this) {
                $city->setCountry(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|User[]
     */
    public function getUsers(): Collection
    {
        return $this->users;
    }

    public function addUser(User $user): self
    {
        if (!$this->users->contains($user)) {
            $this->users[] = $user;
            $user->setCountry($this);
        }

        return $this;
    }

    public function removeUser(User $user): self
    {
        if ($this->users->removeElement($user)) {
            // set the owning side to null (unless already changed)
            if ($user->getCountry() === $this) {
                $user->setCountry(null);
            }
        }

        return $this;
    }
}

状态

<?PHP

namespace App\Entity;

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

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

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

    /**
     * @ORM\ManyToOne(targetEntity=Country::class,inversedBy="states")
     */
    private $country;

    /**
     * @ORM\OnetoMany(targetEntity=City::class,mappedBy="state")
     */
    private $cities;

    /**
     * @ORM\OnetoMany(targetEntity=User::class,mappedBy="state")
     */
    private $users;

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

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

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getCountry(): ?Country
    {
        return $this->country;
    }

    public function setCountry(?Country $country): self
    {
        $this->country = $country;

        return $this;
    }

    /**
     * @return Collection|City[]
     */
    public function getCities(): Collection
    {
        return $this->cities;
    }

    public function addCity(City $city): self
    {
        if (!$this->cities->contains($city)) {
            $this->cities[] = $city;
            $city->setState($this);
        }

        return $this;
    }

    public function removeCity(City $city): self
    {
        if ($this->cities->removeElement($city)) {
            // set the owning side to null (unless already changed)
            if ($city->getState() === $this) {
                $city->setState(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|User[]
     */
    public function getUsers(): Collection
    {
        return $this->users;
    }

    public function addUser(User $user): self
    {
        if (!$this->users->contains($user)) {
            $this->users[] = $user;
            $user->setState($this);
        }

        return $this;
    }

    public function removeUser(User $user): self
    {
        if ($this->users->removeElement($user)) {
            // set the owning side to null (unless already changed)
            if ($user->getState() === $this) {
                $user->setState(null);
            }
        }

        return $this;
    }
}

城市

<?PHP

namespace App\Entity;

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

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

    /**
     * @ORM\Column(type="string",inversedBy="cities")
     */
    private $country;

    /**
     * @ORM\ManyToOne(targetEntity=State::class,inversedBy="cities")
     */
    private $state;

    /**
     * @ORM\OnetoMany(targetEntity=User::class,mappedBy="city")
     */
    private $users;

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

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

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getCountry(): ?Country
    {
        return $this->country;
    }

    public function setCountry(?Country $country): self
    {
        $this->country = $country;

        return $this;
    }

    public function getState(): ?State
    {
        return $this->state;
    }

    public function setState(?State $state): self
    {
        $this->state = $state;

        return $this;
    }

    /**
     * @return Collection|User[]
     */
    public function getUsers(): Collection
    {
        return $this->users;
    }

    public function addUser(User $user): self
    {
        if (!$this->users->contains($user)) {
            $this->users[] = $user;
            $user->setCity($this);
        }

        return $this;
    }

    public function removeUser(User $user): self
    {
        if ($this->users->removeElement($user)) {
            // set the owning side to null (unless already changed)
            if ($user->getCity() === $this) {
                $user->setCity(null);
            }
        }

        return $this;
    }
}

表格类型

<?PHP

namespace App\Form;

use App\Entity\User;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\Regex;
use Symfony\Component\Validator\Constraints\IsTrue;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; 
use Symfony\Component\Form\Extension\Core\Type\CheckBoxType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType; 
use App\Entity\Country;
use App\Entity\State;
use App\Entity\City;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormInterface;
use App\Repository\CountryRepository;
use App\Repository\StateRepository;
use App\Repository\CityRepository;
use Doctrine\ORM\EntityRepository;





class RegistrationFormType extends AbstractType
{
    private $countryRepository;
    private $StateRepository;
    private $stateCitiesRepository;

    public function __construct(
        CountryRepository $countryRepository,StateRepository $stateRepository,CityRepository $stateCitiesRepository
        ) {
        $this->countryRepository = $countryRepository;
        $this->countryStateRepository = $stateRepository;
        $this->stateCitiesRepository = $stateCitiesRepository;
}

    public function buildForm(FormBuilderInterface $builder,array $options)
    {
        $builder
            ->add('first_name')
            ->add('last_name')
            ->add('gender',ChoiceType::class,array( 
                'choices'  => array( 
                   'Male' => true,'Female' => false,),))
            ->add('dob')
            ->add('mobile')
            ->add('address',TextareaType::class)
            ->add('country',EntityType::class,[
                'class' => Country::class,'label' => 'Country','required' => true,'choice_label' => function(Country $country) {
                    return $country->getName();
                },'invalid_message' => 'You must select a Country','placeholder' => 'Select Country',])
            ->add('state',[
                'choices' => [],'placeholder' => 'Select State',])
            ->add('city',])        
            ->add('pincode')
            ->add('email')
            ->add('plainPassword',RepeatedType::class,[
                'mapped' => false,'attr' => ['autocomplete' => 'new-password'],'constraints' => [
                    new NotBlank([
                        'message' => 'Please enter a password',]),new Length([
                        'min' => 6,'minMessage' => 'Your password should be at least {{ limit }} characters',// max length allowed by Symfony for security reasons
                        'max' => 4096,new Regex([
                        'pattern'=>"/^\S*(?=\S{8,})(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[\d])\S*$/",'message'=>" Password must be at least 6 characters: 1 uppercase,1 lowercase,numbers,or symbols."
                    ])
                ],'type' => PasswordType::class,'invalid_message' => 'The password fields must match.','options' => ['attr' => ['class' => 'password-field']],'first_options'  => ['label' => 'Password'],'second_options' => ['label' => 'Confirm Password'],])
            ->add('agreeTerms',CheckBoxType::class,'constraints' => [
                    new IsTrue([
                        'message' => 'You should agree to our terms.',],])
            ->add('submit',SubmitType::class)
        ;

        //**************** Start State Form
        $addStateForm = function (FormInterface $form,$country_id) {

            $form->add('state',[
                'label' => 'state','placeholder' => 'Select state','class' => State::class,'query_builder' => function (StateRepository $repository) use ( $country_id ) {
                    
                    return $repository->createqueryBuilder('c')
                    ->where('c.country = :id')
                    ->setParameter('id',$country_id)
                    ->orderBy('c.name','ASC')                    
                    ;
                    // echo "<pre>"; print_r(($sql->getQuery()->getArrayResult())); exit;
                },'choice_label' => 'name','choice_value' => 'name','constraints' => [
                    new NotBlank([
                        'message' => 'State is required',]);
        };
        

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,function (FormEvent $event) use ($addStateForm) {
                $country = $event->getData()->getCountry();
                $country_id = $country ? $country->getId() : null;
                $addStateForm($event->getForm(),$country_id);
            }
        );

        $builder->addEventListener(
            FormEvents::PRE_SUBMIT,function (FormEvent $event) use ($addStateForm) {
                $data = $event->getData();

                $country_id = array_key_exists('country',$data) ? $data['country'] : null;
                

                $addStateForm($event->getForm(),$country_id);
            }
        );
        //**************** End State Form

        //**************** Start City Form

        $addCityForm = function (FormInterface $form,$state_id) {

            $form->add('city',[
                'label' => 'city','placeholder' => 'Select city','class' => City::class,'query_builder' => function (CityRepository $repository) use ( $state_id ) {
                    
                    return $repository->createqueryBuilder('c')
                    ->where('c.state = :id')
                    ->setParameter('id',$state_id)
                    ->orderBy('c.name','constraints' => [
                    new NotBlank([
                        'message' => 'City is required',function (FormEvent $event) use ($addCityForm) {
                $state = $event->getData()->getState();
                print_r($state);
                $state_id = $state ? $state->getId() : null;
                $addCityForm($event->getForm(),$state_id);
            }
        );

        $builder->addEventListener(
            FormEvents::PRE_SUBMIT,function (FormEvent $event) use ($addCityForm) {
                $data = $event->getData();

                $state_id = array_key_exists('state',$data) ? $data['state'] : null;
                

                $addCityForm($event->getForm(),$state_id);
            }
        );

        //**************** End City Form


    
    }

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

树枝

<script>
      $(document).ready(function() {

                var $country = $('#registration_form_country');
                var $state = $('#registration_form_state');
                
                // When country gets selected ...
                $country.change(function () {
                    // ... retrieve the corresponding form.
                    var $form = $(this).closest('form');
                    // Simulate form data,but only include the selected country value.
                    var data = {};
                    data[$country.attr('name')] = $country.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 state field ...
                            $('#registration_form_state').replaceWith(
                                // ... with the returned one from the AJAX response.
                                $(html).find('#registration_form_state')
                            );
                        }
                    });
                });

                
                // When state gets selected ...
                $state.change( function () {
                    // ... retrieve the corresponding form.
                    var $form = $(this).closest('form');
                    // Simulate form data,but only include the selected state value.
                    var data = {};
                    data[$state.attr('name')] = $state.val();
                    // Submit data via AJAX to the form's action path.
                    $.ajax({
                        url: $form.attr('action'),success: function (html) {
                            // Replace current city field ...
                            $('#registration_form_city').replaceWith(
                                // ... with the returned one from the AJAX response.
                                $(html).find('#registration_form_city')
                            );
                        }
                    });
                });

            });
        </script>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?