繁体   English   中英

SonataAdmin捆绑包链接的字段(级联选择)

[英]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。

如何在Sonata Admin表单中使用Ajax?

有什么帮助吗? 提前致谢。

我为此付出了很多努力,但是我认为我提出了一个可行的解决方法。 希望这可以节省将来的时间。

我的情况是:我有多个Company实体,其中有1n ContactPerson实体。 当我创建一个新Job ,我必须选择Company ,然后我ContactPerson所选公司过滤ContactPerson的列表。 如您所见,它的工作原理。 根据选择的Company ,如果已加载ContactPerson则匹配列表:

筛选截图1筛选截图2

因此,使此工作正常进行,我只是禁用了CustomerContactPersonmapping标志,以自己在admin类的postPersistpostUpdate中映射数据(扩展了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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM