【问题标题】:Symfony2.6: make a dynamic ajax form to populate dropdownlist dynamicallySymfony2.6:制作动态 ajax 表单以动态填充下拉列表
【发布时间】:2015-05-26 06:25:41
【问题描述】:

我使用 Ajax 处理 symfony 动态表单。我尝试动态填充下拉列表,即我想在第二次选择结果中显示结果。我的第三个选择也是如此。实际上,第一个下拉列表允许用户选择一个 parc,当他们选择一个 parc 时,第二个选择填充 Ensembles.php 属于该 parc 的结果,然后用户可以在第三个下拉列表中选择一个 batiments 属于 Ensembles.php .这是example

当我想要添加 Zonestechnique 时会显示此表单。 以下是我的实体之间的关系:

Parcsimmobilier.php

这是我的表格ZonestechniqueType.php

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\ParcsimmobilierRepository;
use Doctrine\ORM\EnsemblesRepository;
use Doctrine\ORM\BatimentsRepository;


class ZonestechniqueType extends AbstractType
{
    /* @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('parcsimmobilier', 'entity', array(
                                    'mapped' => false,
                                    'class'    => 'MySpaceDatabaseBundle:Parcsimmobilier',
                                    'property' => 'nom',
                                    'empty_value' => '-- choose a parc parc --',
                                    'label'    => 'choose a parc immobilier : ',
                                    'multiple' => false,
                                    ))
            ->add('ensembles', 'entity', array(
                                    'mapped' => false,
                                    'multiple' => false,
                                    'class'    => 'MySpaceDatabaseBundle:Ensembles',
                                    'property' => 'nom',
                                    'empty_value' => '-- choose an ensemble --',
                                    'label'    => 'choose an ensemble : ',
                                    ))
            ->add('batiments','entity', array(
                                    'class'    => 'MySpaceDatabaseBundle:Batiments',
                                    'property' => 'nom',
                                    'empty_value' => '-- choose a batiment --',
                                    'label'    => 'choose a batiment : ',
                                    ))
            ->add('categorieszonestechnique')
            ->add('nom')
            ->add('localisation')
            ->add('commentaire')
            ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'MySpace\DatabaseBundle\Entity\Zonestechnique'
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'mySpace_databasebundle_zonestechnique';
    }
}

我在控制器中创建了两个方法。一个用于显示/添加 Zonestechnique,另一个用于使用 Ajax 填充我的下拉列表。现在我尝试使用前两个选择,即我选择一个 parc,然后第二个下拉列表填充属于我选择的 parc 的所有集合的名称。

这是我的控制器方法:

public function formZonesAction() {

        $request = $this->getRequest();
        $em = $this->getDoctrine()->getEntityManager();

        if($request->isXmlHttpRequest()) {
            $id = '';
            $id = $request->get('id');

                if ($id != '') {

                    $ensembles = $em->getRepository('MySpaceDatabaseBundle:Ensembles')
                                    ->getEnsemblesByParcsimmobilierQueryBuilder($id);

                    $tabEnsembles = array();
                    $i = 0;

                        foreach($ensembles as $ensemble) {

                            $tabEnsembles[$i]['id'] = $ensemble->getId();
                            $tabEnsembles[$i]['nom'] = $ensemble->getNom();
                            $i++;
                        }

                    $response = new Response();

                    $data = json_encode($tabEnsembles); // formater le résultat de la requête en json

                    $response->headers->set('Content-Type', 'application/json');
                    $response->setContent($data);

                    return $response;
                }

        } else {

            return new Response('no ajax');
        }
    }

/**
     *
     * @Route("/gestionzonestechniquesconformites/addform", name="formZones")
     * @Method("GET")
     */
    public function addZonesConformitesAction() {

        $em=$this->getDoctrine()->getManager();
        $zones = $em->getRepository('MySpaceDatabaseBundle:Zonestechnique');

        $zones = new Zonestechnique;
        $form=$this->createForm(new ZonestechniqueType(), $zones);
        $request = $this->getRequest();

            if($request->isMethod('POST') | $form->isValid()) {

                $form->bind($request);
                $zoneConformite = $form->getData();

                $em->persist($zones);
                $em->flush();

                return $this->redirect($this->generateUrl('indexRechercheZones'));
            }

            else {
                    return $this->render('MySpaceGestionEquipementsTechniquesBundle:ZonesTechnique:addZonesTechniqueConformites.html.twig', array('form' => $form->createView(), 'zone' => $zones ));
                }
    }

这是EnsemblesRepository.php存储库

class EnsemblesRepository extends EntityRepository
{
    public function getEnsemblesByParcsimmobilierQueryBuilder($id)
    {
        return $this
          ->createQueryBuilder('e')
          ->where('e.parcsimmobilier = :parcsimmobilier')
        ->setParameter('id', $id);
        ;
    }
}

您可以在我的 Ajax 方法的控制器中找到此请求。

显示表单/页面时没有错误,但我的 Ajax 请求不起作用。 这是我的路由文件:

addZonesConformites:
    path:     /gestionzonestechniquesconformites/add
    defaults: { _controller: MySpaceGestionEquipementsTechniquesBundle:GestionZonesTechniques:addZonesConformites }
    requirements:
    methods: GET

# Ajax
formZones:
    pattern:  /gestionzonestechniquesconformites/addform
    defaults: { _controller: MySpaceGestionEquipementsTechniquesBundle:GestionZonesTechniques:formZones }
    requirements:
    methods: GET

addZonesConformites_process:
    path:     /gestionzonestechniquesconformites/add/process
    defaults: { _controller: MySpaceGestionEquipementsTechniquesBundle:GestionZonesTechniques:addZonesConformites }
    requirements:
    methods: POST

如您所见,我有 3 条路线,一条用于显示表单,一条用于使用 Ajax 填充下拉列表,最后一条用于验证表单。

当然,我在我的树枝上做了这个表格:

 <form action="{{ path('addZonesConformites_process') }}" method="POST">
          <div class="row">
            <div class="col-md-6">
              <div>
                {{ form_errors(form) }}
              </div>
              <div>
                {{ form_label(form.parcsimmobilier, "choisir un parc", {'label_attr': {'class': 'control-label'}}) }}
                {{ form_errors(form.parcsimmobilier) }}
                {{ form_widget(form.parcsimmobilier, {'attr': {'class': 'form-control', 'id': 'parcsimmobilier',   'onChange':'populateEnsembles();'}}) }}
              </div>
              <div>
                {{ form_label(form.ensembles, "choisir un ensemble:", {'label_attr': {'class': 'control-label'}}) }}
                {{ form_errors(form.ensembles) }}
                {{ form_widget(form.ensembles, {'attr': {'class': 'form-control', 'id': 'ensembles'}}) }}
              </div>
              <div>
                {{ form_label(form.batiments, "Appartenant au bâtiment:", {'label_attr': {'class': 'control-label'}}) }}
                {{ form_errors(form.batiments) }}
                {{ form_widget(form.batiments, {'attr': {'class': 'form-control'}}) }}
              </div>
<div class="row">
            <div class="clo-md-4"></div>
              <input onclick="clear_form_elements(this.form)" type="reset" value="Vider les champs" class="btn btn-xs btn-default"/>
            </div>
            <br>
            <div class="clo-md-4"></div>
              <input type="submit" value="add" class="btn btn-small btn-success"/>
            </div>
          </div>
        </form>

最后加上这个脚本:

 <script type="text/javascript">
      function populateEnsembles(){
        var id_select = $('#mySpace_databasebundle_zonestechnique_parcsimmobilier').val();
          $.ajax({
            url: "{{ path('addZonesConformites') }}",
            type: 'GET',
            data: {'id': id_select},
            dataType: 'json',
            success: function(json){
              $('#mySpace_databasebundle_zonestechnique_ensembles').html('');
              $.each(json, function(index, value) {
           $('#mySpace_databasebundle_zonestechnique_ensembles').append('<option value="'+ value.id +'">'+ value.nom +'</option>');
              });
            }
          });
      }
    </script>

这是我第一次使用 Ajax。所以我真的不知道这是否是正确的方法,但现在没有任何匹配项并显示我正在尝试使用这种动态表单制作的内容。

有人可以帮助我吗?

这是一个屏幕截图:

如您所见,我选择了一个 parc,ajax 请求有效(symfony 工具栏底部的绿色数字)。当我在浏览器中进行调试时,在网络选项卡中,我的 ajax 请求工作并返回我选择的 parc 的好 id。但它没有填充合奏的第二个下拉列表。在第二个合奏选择中,我拥有数据库的所有合奏。 提前谢谢你。

【问题讨论】:

  • 为什么你认为 ajax 调用不起作用? console.dir(json) 显示正确吗?你得到什么错误?
  • @johnSmith,当我在我的 symfony 工具栏中显示表单/页面时,ajax 调用有效,当我在浏览器上调试时,在网络选项卡中,路由与 ajax 匹配。事实上我没有错误,但我的 ajax 请求没有填充第二个下拉列表的集合。我在网络选项卡中看到 ajax 请求返回了 parc 的 id。
  • @johnSmith,我用屏幕截图编辑了我的代码。谢谢
  • 嗯,你需要用 chrome 的浏览器控制台调试 javascript,放置 console.log()'s 以找出问题所在
  • @johnSmith,脚本显然没有问题,可能是我的 php 请求,或者我的存储库方法。

标签: javascript jquery ajax symfony populate


【解决方案1】:

我找到了解决办法,其实是菜鸟的错误。

我必须选择我的 ajax 路由的 url 路径,而不是我的表单路由。这就是我调试应用程序时控制台中没有代码错误的原因。所以这是我在 ajax 脚本中更改的行:url: "{{ path('addZonesConformites') }}" to url: "{{ path('formRoute') }}"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-05
    • 2023-04-03
    • 2020-06-26
    • 2015-12-11
    • 2019-06-06
    • 2014-03-01
    相关资源
    最近更新 更多