I already tried docs and as you can see in my code I got a country/state example working. But I want to set another field (country code) based in the country, not just the state.
Here is my code, starting with entities:
Address:
<?php
namespace Costo\AddressBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Address
*
* @ORM\Table()
* @ORM\Entity
*/
class Address
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="address", type="string", length=255)
*/
private $address;
/**
* @ORM\ManyToOne(targetEntity="Country", inversedBy="addresses")
*/
private $country;
/**
* @var string
*
* @ORM\Column(name="countryCode", type="string", length=255)
*/
private $countryCode;
/**
* @ORM\ManyToOne(targetEntity="State", inversedBy="addresses")
*/
private $state;
Country:
<?php
namespace Costo\AddressBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Pais
*
* @ORM\Table()
* @ORM\Entity
*/
class Country
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="code", type="string", length=255)
*/
private $code;
/**
* @ORM\OneToMany(targetEntity="State", mappedBy="country")
*/
private $states;
/**
* @ORM\OneToMany(targetEntity="Address", mappedBy="country")
*/
private $addresses;
And State:
<?php
namespace Costo\AddressBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Estado
*
* @ORM\Table()
* @ORM\Entity
*/
class State
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @ORM\ManyToOne(targetEntity="Country", inversedBy="states")
*/
private $country;
/**
* @ORM\OneToMany(targetEntity="Address", mappedBy="state")
*/
private $addresses;
The Form:
<?php
namespace Costo\AddressBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormInterface;
use Costo\AddressBundle\Entity\Country;
class AddressType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('address')
->add('country');
$formModifier = function (FormInterface $form, Country $country = NULL) {
$states = NULL === $country ? array() : $country->getStates();
$code = NULL === $country ? '' : $country->getCode();
$form->add('state', 'entity', array(
'class' => 'AddressBundle:State',
'choices' => $states
));
$form->add('countryCode', 'text', array(
'data' => $code
));
};
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($formModifier){
//entity
$data = $event->getData();
$formModifier($event->getForm(), $data->getCountry());
});
$builder->get('country')->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($formModifier){
$data = $event->getForm()->getData();
$formModifier($event->getForm()->getParent(), $data);
});
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Costo\AddressBundle\Entity\Address'
));
}
/**
* @return string
*/
public function getName()
{
return 'costo_addressbundle_address';
}
}
And Finally my template:
{% extends '::base.html.twig' %}
{% form_theme form 'bootstrap_3_horizontal_layout.html.twig' %}
{% block body -%}
<h3>Add Address</h3>
{{ form_start(form) }}
{{ form_widget(form) }}
<div class="form-group">
<div class="col-sm-2"></div>
<div class="col-sm-10">
<input type="submit" class="btn btn-primary btn" value="Aceptar">
<a href="{{ path('address') }}" class="btn btn-info" role="button">
<span class="glyphicon glyphicon-list"></span> List</a>
</div>
</div>
{{ form_end(form) }}
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script>
var $country = $('#costo_addressbundle_address_country');
// 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 ...
$('#costo_addressbundle_address_state').replaceWith(
// ... with the returned one from the AJAX response.
$(html).find('#costo_addressbundle_address_state')
);
}
});
});
</script>
{% endblock %}
I would like to set the country code in my address entity,I don't know if the problem is in the form class or it's a problem in the template with the ajax stuff