【问题标题】:Symfony forms and dependent selectsSymfony 表单和依赖选择
【发布时间】:2017-03-15 18:27:26
【问题描述】:

我正在使用 symfony 2.8 和 php 7 并且确实遇到了用地理数据(国家/州/省/市/邮编)填写表格的问题。

我只需要 5 个选择框,第一个已经填满,其他的在我之前更改选择后重新加载。例如,如果我更改国家/地区,则选择的州将充满新值。

我今天阅读了很多示例,但仍然不知道如何运行它。

这是我的代码:

如果有 5 个方法返回数组,你可以通过名称了解它们返回的内容:

private function getCountryList()
private function getStatesList( $idCountry )
private function getProvinceList( $idState )
private function getCityList( $idProvince )
private function getZipList( $idCity )

这是我的表格:

$locationForm = $builder->create('location', FormType::class, array('data_class' => 'M3\CoreBundle\Entity\Location',
        'by_reference' => true));

$locationForm->add('GeoCountryId', ChoiceType::class, array(
                'label' => 'Country',
                'choices' => $this->getCountryList(),
            ));
$locationForm->add('GeoStateId', ChoiceType::class, array('label' => 'State', 'choices' => array()));
$locationForm->add('GeoProvinceId', ChoiceType::class, array('label' => 'Province', 'choices' => array()));
$locationForm->add('GeoCityId', ChoiceType::class, array('label' => 'City', 'choices' => array()));
$locationForm->add('GeoZipCodeId', ChoiceType::class, array('label' => 'Zip Code', 'choices' => array()));

我尝试添加一些这样的事件

$locationForm->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) {
                $data = $event->getData();
                $form = $event->getForm();
                $country = $form->get('GeoCountryId')->getData();
            //here i tried a lot of things               
            $form->get('GeoStateId')->setData($this->getStatesList($country));
            }
        );

我尝试了很多东西,但一无所获。我阅读了本手册http://symfony.com/doc/2.8/form/dynamic_form_modification.html#form-events-user-data,但也没有任何效果。你能帮帮我吗?

也许我只需要添加javascript事件“更改”以手动选择并加载所有数据?

【问题讨论】:

  • 您需要在 JS 中处理它,例如在 onChange 事件中使用 ajax 调用服务器以获取下一个 select 的数据。然后你还需要一个服务器端表单中的事件监听器,但它只是为了能够在提交期间验证表单。

标签: php forms symfony


【解决方案1】:

您必须使用 PHP 和 JS 的组合。您可以使用以下几段文档的示例:http://symfony.com/doc/2.8/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms

{# app/Resources/views/Meetup/create.html.twig #}
{{ form_start(form) }}
    {{ form_row(form.sport) }}    {# <select id="meetup_sport" ... #}
    {{ form_row(form.position) }} {# <select id="meetup_position" ... #}
    {# ... #}
{{ form_end(form) }}

<script>
var $sport = $('#meetup_sport');
// When sport gets selected ...
$sport.change(function() {
  // ... retrieve the corresponding form.
  var $form = $(this).closest('form');
  // Simulate form data, but only include the selected sport value.
  var data = {};
  data[$sport.attr('name')] = $sport.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 position field ...
      $('#meetup_position').replaceWith(
        // ... with the returned one from the AJAX response.
        $(html).find('#meetup_position')
      );
      // Position field now displays the appropriate positions.
    }
  });
});
</script>

【讨论】:

  • 我现在的问题是,当我尝试提交表单时,所有通过 JS 用新元素更改的输入都变为空。
【解决方案2】:

树枝页面:

// 继续

{{ form_widget(form.matiere) }}

///

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
  $( "select[name='continue[matiere]']" ).change(function () {
      var matiereID = $(this).val();


      if(matiereID) {


          $.ajax({
              url: "{{ path('ajaxform') }}",
              dataType: 'Json',
              data: {'id':matiereID},
              type:'POST',
              success: function(data) {
                  $('select[name="continue[chapitre]"]').empty();
                  for(i = 0; i < data.length; i++) {  
                    student = data[i];  

                      $('select[name="continue[chapitre]"]').append('<option value="'+ student['id'] +'">'+ student['nom'] +'</option>');
                  };
              }
          });


      }else{
          $('select[name="continue[chapitre]"]').empty();
      }
  });
  </script>

在表单中(例如:continueType):

    ->add('classe',EntityType::class,array(
        'class'=> Classe::class,
        'choice_label'=>'nom',
        'placeholder'=>'choisir une classe'));
     $builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData'));
    $builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPreSubmit'));
}

protected function addElements(FormInterface $form, matiere $matiere = null) {
    // 4. Add the province element
    $form->add('matiere', EntityType::class, array(
        'required' => true,
        'data' => $matiere,
        'placeholder' => 'Select a matiere...',
        'class' => Matiere::class
    ));

    // chapitres empty, unless there is a selected matiere (Edit View)
    $chapitres = array();

    // If there is a matiere stored in the Person entity, load the chapitres of it
    if ($matiere) {
        // Fetch chapitres of the matiere if there's a selected matiere
        $repochapitres = $this->em->getRepository(Chapitre::class);


        $chapitres = $repochapitres->createQueryBuilder("q")
            ->where("q.matiere = :matiereid")
            ->setParameter("matiereid", $matiere->getId())
            ->getQuery()
            ->getResult();
    }

    // Add the chapitres field with the properly data
    $form->add('chapitre', EntityType::class, array(
        'required' => true,
        'placeholder' => 'Select a matiere first ...',
        'class' => Chapitre::class,
        'choices' => $chapitres
    ));
}

function onPreSubmit(FormEvent $event) {
    $form = $event->getForm();
    $data = $event->getData();

    // Search for selected matiere and convert it into an Entity
    $matiere = $this->em->getRepository(Matiere::class)->find($data['matiere']);

    $this->addElements($form, $matiere);
}

function onPreSetData(FormEvent $event) {
    $contenue = $event->getData();
    $form = $event->getForm();

    // When you create a new person, the matiere is always empty
    $matiere = $contenue->getMatiere() ? $contenue->getMatiere() : null;

    $this->addElements($form, $matiere);
}





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

}

在控制器中 /** * @Route("/exercice/ajax",name="ajaxform") */ 公共函数 ajaxAction(请求 $request) {

$responseArray[] = array();  
if ($request->isXmlHttpRequest() ) {  
   $id= $_POST['id'] ;
    $matriere = $this->getDoctrine() 
   ->getRepository(Matiere::class) 
   ->find($id);  
   $chapitre=$matriere->getChapitres();

   foreach($chapitre as $chapitres) {  
    $responseArray[] = array(
         'id' => $chapitres->getId(),  
         'nom' => $chapitres-> getNom(),  
      );   

   } 
}
   return new JsonResponse($responseArray); 

}

【讨论】:

    猜你喜欢
    • 2011-07-22
    • 1970-01-01
    • 2019-04-23
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    相关资源
    最近更新 更多