我有3个实体正常工作但是在创建symfony表单时存在问题
// My FormType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$translator = $this->translator;
$builder
->add('Country', EntityType::class, array(
'class' => 'App\Entity\Countries',
'placeholder' => '',
))
->add('City', EntityType::class,array(
'class' =>'App\Entity\Cities'
))
;
$formModifier = function (FormInterface $form, Countries $sport = null) {
$positions = null === $sport ? array() : $sport->getCities();
$form->add('City', EntityType::class, array(
'class' => 'App\Entity\Cities',
'placeholder' => '',
'choices' => $positions,
));
};
$formModifier2 = function (FormInterface $form, Cities $sport = null) {
$positions = null === $sport ? array() : $sport->getCountryId();
$form->add('District', EntityType::class, array(
'class' => 'App\Entity\Districts',
'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->getCountry());
}
);
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier2) {
// this would be your entity, i.e. SportMeetup
$data = $event->getData();
$formModifier2($event->getForm(), $data->getCity());
}
);
$builder->get('Country')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
// It's important here to fetch $event->getForm()->getData(), as
// $event->getData() will get you the client data (that is, the ID)
$sport = $event->getForm()->getData();
// since we've added the listener to the child, we'll have to pass on
// the parent to the callback functions!
$formModifier($event->getForm()->getParent(), $sport);
}
);
$builder->get('City')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier2) {
// It's important here to fetch $event->getForm()->getData(), as
// $event->getData() will get you the client data (that is, the ID)
$sport = $event->getForm()->getData();
// since we've added the listener to the child, we'll have to pass on
// since we've added the listener to the child, we'll have to pass on
// the parent to the callback functions!
$formModifier2($event->getForm()->getParent()->getParent(), $sport);
}
);
}
// this my controller
public function userAddress(UserInterface $user,Request $request,HelperService $helper, MailGenerator $mail,TranslatorInterface $translator)
{
$user_address = new UserAddresses();
$form = $this->createForm(NewAddressFormType::class,$user_address,array('csrf_protection' => false));
$form->handleRequest($request);
if($form->isSubmitted()) {
$data = $form->getData();
}
return $this->output('checkout/checkout_address',array('form'=>$form->createView()));
}
Form rendering ok i change my first select box and working ajax post but second one first but third one is not working not send ajax data
{% block script%}
<script>
var $sport = $('#new_address_form_Country');
// When sport gets selected ...
$sport.change(function() {
// ... retrieve the corresponding form.
var $form = $('#new_address_form').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 ...
$('#new_address_form_City').replaceWith(
// ... with the returned one from the AJAX response.
$(html).find('#new_address_form_City')
);
}
});
});
var $sport2 = $('#new_address_form_City');
// When sport gets selected ...
$sport2.change(function() {
// ... retrieve the corresponding form.
var $form = $('#new_address_form').closest('form');
// Simulate form data, but only include the selected sport value.
var data = {};
data[$sport2.attr('name')] = $sport2.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 ...
$('#new_address_form_District').replaceWith(
// ... with the returned one from the AJAX response.
$(html).find('#new_address_form_District')
);
}
});
});
</script>
{% endblock %}
答案 0 :(得分:1)
您应该使用$ builder-&gt; addEventListener。对于多个字段,您需要做的就是在FormEvents :: PRE_SET_DATA事件处理程序中包含动态字段。此外,使用父字段数据,如文档中所述,以获取子字段选项。
我使用这种方法,用于在分层字段中生成Country,City和District实体。如果有帮助或者您需要更多信息,请告诉我。
$builder->add(); // all other fields..
$builder->addEventSubscriber(new DynamicFieldsSubscriber());
创建doc中定义的eventSubscriber,此处文件名为DynamicFieldsSubscriber
public static function getSubscribedEvents()
{
return array(
FormEvents::PRE_SET_DATA => 'preSetData',
FormEvents::PRE_SUBMIT => 'preSubmitData',
);
}
/**
* Handling form fields before form renders.
* @param FormEvent $event
*/
public function preSetData(FormEvent $event)
{
$translator = $this->translator;
$location = $event->getData();
// Location is the main entity which is obviously form's (data_class)
$form = $event->getForm();
$country = "";
$city = "";
$district = "";
if ($location) {
// collect preliminary values for 3 fields.
$country = $location->getCountry();
$city = $location->getCity();
$district = $location->getDistrict();
}
// Add country field as its static.
$form->add('country', EntityType::class, array(
'class' => 'App\Entity\Countries',
'label' => $translator->trans('country'),
'placeholder' => $translator->trans('select'),
'required' => true,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('c');
}
));
// Now add all child fields.
$this->addCityField($form, $country);
$this->addDistrictField($form, $city);
}
/**
* Handling Form fields before form submits.
* @param FormEvent $event
*/
public function preSubmitData(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
// Here $data will be in array format.
// Add property field if parent entity data is available.
$country = isset($data['country']) ? $data['country'] : null;
$city = isset($data['city']) ? $data['city'] : null;
$district = isset($data['district']) ? $data['district'] : null;
// Call methods to add child fields.
$this->addCityField($form, $country);
$this->addDistrictField($form, $city);
}
/**
* Method to Add City Field. (first dynamic field.)
* @param FormInterface $form
* @param type $country
*/
private function addCityField(FormInterface $form, $country = null)
{
$translator = $this->translator;
$countryCode = (is_object($country)) ? $country->getId() : $country;
// $countryCode is dynamic here, collected from the event based data flow.
$form->add('city', EntityType::class, array(
'class' => 'App\Entity\Cities',
'label' => $translator->trans('city'),
'placeholder' => $translator->trans('select'),
'required' => true,
'attr' => array(
'class' => 'col-md-12 validate-required',
'placeholder' => 'City *'
),
'query_builder' => function (EntityRepository $er) use($countryCode) {
return $er->createQueryBuilder('p')
->where('p.country_id = :country')
->setParameter('country', $countryCode);
}
));
}
/**
* Method to Add District Field, (second dynamic field)
* @param FormInterface $form
* @param type $city
*/
private function addDistrictField(FormInterface $form, $city = null)
{
$translator = $this->translator;
$cityCode = (is_object($city)) ? $city->getId() : $city;
// $cityCode is dynamic in here collected from event based data flow.
$form->add('district', EntityType::class, array(
'class' => 'App\Entity\Districts',
'label' => $translator->trans('district'),
'placeholder' => $translator->trans('select'),
'required' => true,
'attr' => array('class' => 'district'),
'query_builder' => function (EntityRepository $er) use($cityCode) {
return $er->createQueryBuilder('s')
->where('s.city = :city')
->setParameter('city', $cityCode);
}
));
}
你的项目JQuery看起来应该是这样的
<script>
var $sport = $('#new_address_form_country');
// When sport gets selected ...
$sport.change(function() {
// ... retrieve the corresponding form.
var $form = $('#new_address_form').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 ...
$('#new_address_form_city').replaceWith(
// ... with the returned one from the AJAX response.
$(html).find('#new_address_form_city')
);
}
});
});
$(document).on('change','#new_address_form_city',function () {
// ... retrieve the corresponding form.
var $form2 = $('#new_address_form').closest('form');
// Simulate form data, but only include the selected sport value.
var data2 = {};
data2[$('#new_address_form_city').attr('name')] = $('#new_address_form_city').val();
// Submit data via AJAX to the form's action path.
$.ajax({
url : $form2.attr('action'),
type: $form2.attr('method'),
data : data2,
success: function(html) {
console.log($(html).find('#new_address_form_district'));
// Replace current position field ...
$('#new_address_form_district').replaceWith(
// ... with the returned one from the AJAX response.
$(html).find('#new_address_form_district')
);
}
});
});
</script>
我希望这会有所帮助。
答案 1 :(得分:0)
我相信在ajax调用之后有时ajax调用不起作用,因为它失去了与jquery事件监听器的联系。
为$sport2.change
事件监听器创建一个函数,并将其命名为例如sport2Change
。并尝试在ID为onchange
new_address_form_City
事件上调用该函数