[英]SonataAdmin bundle linked fields (cascading select)
我正在尝试使用Sonata管理员捆绑包创建链接的下拉列表。
有
产品
product_categories (许多与产品有关)
product_features (与product_categories链接)(基数:与产品多对多,与类别多对一,即一个类别可以具有许多功能,但一个功能与一个类别链接)
一切工作正常,正在使用此显示一个启用多选的组合(用于类别)字段和另一组复选框(用于product_features)字段
在产品输入表格中:
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('category', 'sonata_type_model', array('required' => false, 'expanded' => false, 'multiple' => true, 'label' => 'Choose your categories'))
->add('features', 'sonata_type_model', array('required' => false, 'expanded' => true, 'multiple' => true, 'label' => 'Choose Features'))
但是我想要的是当我在第一个组合(即类别)中选择值时,复选框的第二个列表(即要素)应相应地动态加载(仅与该类别链接的要素)
由于第一个选择框已启用多选功能,因此第二个列表将是累积的,即更好。即,当类别1被选中时,显示与类别1相关的特征,然后,当类别2被选中(还选择了1)时,其显示与类别1关联的特征;猫2
我该怎么做?
我一直在搜索,发现的唯一好答案是这个已有2年历史的解决方案,它似乎已经很久很久了。 还有其他解决方案吗? 在过去的两年中,事情一定已经发生了变化,因为在此期间发行了多个版本的sonata-admin。
有什么帮助吗? 提前致谢。
我为此付出了很多努力,但是我认为我提出了一个可行的解决方法。 希望这可以节省将来的时间。
我的情况是:我有多个Company
实体,其中有1
到n
ContactPerson
实体。 当我创建一个新Job
,我必须选择Company
,然后我ContactPerson
所选公司过滤ContactPerson
的列表。 如您所见,它的工作原理。 根据选择的Company
,如果已加载ContactPerson
则匹配列表:
因此,使此工作正常进行,我只是禁用了Customer
和ContactPerson
的mapping
标志,以自己在admin类的postPersist
和postUpdate
中映射数据(扩展了BaseAdmin
)。
然后,我对所有Company
实体都使用sonata_type_choice_field_mask
。 我自己建立一个数据数组。 之后,我使用sonata_type_model
类型添加了一个预过滤的(通过匹配过滤器) ContactPerson
下拉列表。
这非常有效-但当然,如果您有成千上万的公司和客户,它将失败。 就我而言,这不会受到限制,因此这是一个可行的解决方案。
代码(删除了不必要的内容):
<?php
namespace AppBundle\Admin;
use AppBundle\Entity\Customer;
use AppBundle\Entity\Job;
use AppBundle\Form\Types;
use AppBundle\Repository\CustomerRepository;
use AppBundle\Service\EntityManager;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Route\RouteCollection;
use Sonata\AdminBundle\Show\ShowMapper;
class JobAdmin extends BaseAdmin
{
const CONTACT_PERSON_DROPDOWN_PREFIX = 'contactPersons';
/**
* @param Job $job
* @return null|string
*/
protected function getPreselectedCustomerId(Job $job)
{
if ($job) {
$customer = $job->getCustomer();
if ($customer) {
$customerId = $customer->getId();
return $customerId;
}
}
return null;
}
/**
* @return \Doctrine\ORM\EntityRepository
*/
protected function getEnabledCustomers()
{
$customerRepository = $this->getCustomerRepository();
$customers = $customerRepository->findByEnabled();
return $customers;
}
/**
* @param $enabledCustomers
* @return array
*/
protected function getFilterMap($enabledCustomers)
{
$filterMap = [];
/**
* @var $customer Customer
*/
foreach ($enabledCustomers as $customer) {
$customerId = $customer->getId();
$fieldName = self::CONTACT_PERSON_DROPDOWN_PREFIX . $customerId;
$filterMap[$customerId] = [$fieldName];
}
return $filterMap;
}
/**
* @param $enabledCustomers
* @return array
*/
protected function getCustomerDropDown($enabledCustomers)
{
$customerDropDown = [];
/**
* @var $customer Customer
*/
foreach ($enabledCustomers as $customer) {
$customerId = $customer->getId();
$name = $customer->getName();
$customerDropDown[$name] = $customerId;
}
return $customerDropDown;
}
/**
* @param Customer $customer
* @return \Doctrine\ORM\QueryBuilder
*/
protected function getFilterQueryForCustomer(Customer $customer)
{
$entityManager = $this->getEntityManager();
$contactPersonQuery = $entityManager->createQueryBuilder('cp')
->select('cp')
->from('AppBundle:ContactPerson', 'cp')
->where('cp.customer = :customer')
->setParameter('customer', $customer)
->orderBy('cp.name', 'ASC')
;
return $contactPersonQuery;
}
/**
* @param FormMapper $formMapper
*/
protected function configureFormFields(FormMapper $formMapper)
{
$job = $this->getSubject();
$enabledCustomers = $this->getEnabledCustomers();
$filterMap = $this->getFilterMap($enabledCustomers);
$customerDropDown = $this->getCustomerDropDown($enabledCustomers);
$preselectedId = $this->getPreselectedCustomerId($job);
$formMapper
->tab('BaseData')
->with('JobData')
->add('customer', 'sonata_type_choice_field_mask', array(
'choices' => $customerDropDown,
'data' => $preselectedId,
'map' => $filterMap,
'by_reference' => false,
'required' => true,
'mapped' => false,
)
)
->end()
->end()
;
/**
* @var $customer Customer
*/
foreach ($enabledCustomers as $customer) {
$customerId = $customer->getId();
$fieldName = self::CONTACT_PERSON_DROPDOWN_PREFIX . $customerId;
$filterQuery = $this->getFilterQueryForCustomer($customer);
$formMapper
->tab('BaseData')
->with('JobData')
->add($fieldName, 'sonata_type_model', array(
'class' => 'AppBundle\Entity\ContactPerson',
'query' => $filterQuery,
'mapped' => false,
'label' => 'Contact Person'
))
->end()
->end()
;
}
$formMapper
->tab('BaseData')
->with('JobData')
->add('name')
// Add more fields
->end()
->end()
;
}
/**
* @param EntityManager $entityManager
* @return \Doctrine\ORM\EntityRepository
*/
protected function getCustomerRepository(EntityManager $entityManager = null)
{
if (!$entityManager) {
$entityManager = $this->getEntityManager();
}
$customerRepository = $entityManager->getRepository(Customer::class);
return $customerRepository;
}
/**
* @return EntityManager
*/
protected function getEntityManager()
{
$entityManager = $this->getConfigurationPool()->getContainer()->get('doctrine')->getManager();
return $entityManager;
}
/**
* @param Job $job
*/
protected function mapUnmappedFields (Job $job)
{
$customerId = $this->getForm()->get('customer')->getData();
if ($customerId)
{
$entityManager = $this->getEntityManager();
$contactPerson = $this->getForm()->get(self::CONTACT_PERSON_DROPDOWN_PREFIX.$customerId)->getData();
$customerRepository = $this->getCustomerRepository($entityManager);
$customer = $customerRepository->findById($customerId);
if ($contactPerson) {
$job->setContactPerson($contactPerson);
}
if ($customer) {
$job->setCustomer($customer);
}
$entityManager->persist($job);
$entityManager->flush($job);
}
}
/**
* @param mixed $object
*/
public function postPersist($object)
{
$this->mapUnmappedFields($object);
parent::postPersist($object);
}
/**
* @param mixed $object
*/
public function postUpdate($object)
{
$this->mapUnmappedFields($object);
parent::postUpdate($object);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.