I have two entities Location and Person. Person has four many to one relationships to the Location entity.
A Person has one of each of the following locations:
- Home Town
- List item
- Current Town
- Departure Arrival
Like this:
class Person {
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="notes", type="string", length=255, nullable=false)
*/
private $name;
/**
* @ORM\ManyToOne(targetEntity="Location", inversedBy="locationHomeTowns")
* @ORM\JoinColumn(name="home_town_location_id", referencedColumnName="id", onDelete="SET NULL")
*/
protected $locationHomeTown;
/**
* @ORM\ManyToOne(targetEntity="Location", inversedBy="locationCurrentTowns")
* @ORM\JoinColumn(name="current_town_location_id", referencedColumnName="id", onDelete="SET NULL")
*/
protected $locationCurrentTown;
/**
* @ORM\ManyToOne(targetEntity="Location", inversedBy="locationDepartures")
* @ORM\JoinColumn(name="departure_location_id", referencedColumnName="id", onDelete="SET NULL")
*/
protected $locationDeparture;
/**
* @ORM\ManyToOne(targetEntity="Location", inversedBy="locationArrivals")
* @ORM\JoinColumn(name="arrival_location_id", referencedColumnName="id", onDelete="SET NULL")
*/
protected $locationArrival;
…
}
class Location {
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="latitude", type="decimal", scale=12, precision=18, nullable=false)
*/
private $latitude;
/**
* @var string
*
* @ORM\Column(name="longitude", type="decimal", scale=12, precision=18, nullable=false)
*/
private $longitude;
/**
* @var string
*
* @ORM\Column(name="notes", type="string", length=255, nullable=false)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="Person", mappedBy="locationHomeTown", cascade={"persist"}, orphanRemoval=false)
*/
protected $locationHomeTowns;
/**
* @ORM\OneToMany(targetEntity="Person", mappedBy="locationCurrentTown", cascade={"persist"}, orphanRemoval=false)
*/
protected $locationCurrentTowns;
/**
* @ORM\OneToMany(targetEntity="Person", mappedBy="locationDeparture", cascade={"persist"}, orphanRemoval=false)
*/
protected $locationDepartures;
/**
* @ORM\OneToMany(targetEntity="Person", mappedBy="locationArrival", cascade={"persist"}, orphanRemoval=false)
*/
protected $locationArrivals;
…
}
I have setup the admin classes both entities as follows:
class LocationAdmin extends Admin {
…
/**
* @param FormMapper $formMapper
*/
protected function configureFormFields(FormMapper $formMapper) {
$formMapper
->add('longitude', null, array('attr' => array(
'placeholder' => 'decimal degrees e.g. 51.5072',
)))
->add('latitude', null, array('attr' => array(
'placeholder' => 'decimal degrees e.g. -0.1275',
)))
->add('name')
;
}
…
}
class ExileAdmin extends Admin {
…
/**
* @param FormMapper $formMapper
*/
protected function configureFormFields(FormMapper $formMapper) {
$formMapper
->add('name')
->add('locationHomeTown', 'sonata_type_model', array(
'required' => false
))
->add('locationCurrentTown', 'sonata_type_model', array(
'required' => false
))
->add('locationDeparture', 'sonata_type_model', array(
'required' => false
))
->add('locationArrival', 'sonata_type_model', array(
'required' => false
))
;
}
…
}
I have set the locations as sonata_type_model in the person form to allow me to add new locations whilst editing the person entity. This works as expected for each input, however only that list of locations updates. This means I have to save the whole Person form if I need to use this new location in one of the other location fields on the form.
Is there a way to have all of the location input widgets update when I add a new location to one of the other inputs?
For example, if I currently have London, Paris and Berlin stored in the database and I add Rome to Home Town I would like the form input widgets for Current Town, Departure and Arrival to update too. If I then add Dublin to Current Town I would like Home Town, Departure and Arrival to update too, and so on for Departure and Arrival.
What you need to do is catch the
sonata-admin-append-form-element
javascript event when the new Location presisted and sync all other select element's options with the triggered one.First override Sonata's form admin fields; this will generate the event handling javascript block for each element in your form.
I know this is not the most elegant way to use "select" selectors and filter appropriate elements in the for loop but this may guide you.
YourBundle/resources/views/Form/form_admin_fields.html.twig
Then override your ExileAdmin getFormTheme method;
I guess that's all now when you persist a Location all select elements are synced with the most updated one.