siganushka/region-bundle

Region bundle for symfony.

Installs: 60

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 1

Forks: 0

Open Issues: 0

Type:symfony-bundle

v0.6.0 2022-05-09 09:44 UTC

This package is auto-updated.

Last update: 2024-04-05 08:42:55 UTC


README

Build Status Latest Stable Version Latest Unstable Version License

国内行政区划(省、市、区选择) Bundle

安装

$ composer require siganushka/region-bundle

使用

更新数据库映射信息。

$ php bin/console doctrine:schema:update --force

导入行政区划数据。

$ php bin/console siganushka:region:update

导入控制器。

# ./config/routes.yaml

siganushka_region:
    resource: "@SiganushkaRegionBundle/Resources/config/routes.php"

为实体添字段,默认为省 province、市 city、区 district 三级。

// src/Entity/Foo.php

use Siganushka\RegionBundle\Entity\RegionSubjectInterface;
use Siganushka\RegionBundle\Entity\RegionSubjectTrait;

class Foo implements RegionSubjectInterface
{
    use RegionSubjectTrait;

    // ...
}

添加表单字段。

// src/Form/FooType.php

use Siganushka\RegionBundle\Form\Type\RegionSubjectType;

class FooType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            // region 为虚拟名称,可随便填写
            ->add('region', RegionSubjectType::class, [
                // 'province_options' => [
                //     'placeholder' => '--- 请选择 ---',
                //     'constraints' => new NotBlank(),
                // ],
                // 'city_options' => [
                //     'placeholder' => '--- 请选择 ---',
                //     'constraints' => new NotBlank(),
                // ],
                // 'district_options' => [
                //     'placeholder' => '--- 请选择 ---',
                //     'constraints' => new NotBlank(),
                // ],
            ])
        ;
    }

    // ...
}

客户端实现联动效果,以 jquery 获取为例:

$(function() {
  var $province = $('#{{ form.region.province.vars.id }}')
  var $city = $('#{{ form.region.city.vars.id }}')
  var $district = $('#{{ form.region.district.vars.id }}')

  var update = function(parent, $target) {
    $.getJSON('{{ path("siganushka_region_collection_get") }}', { parent: parent }, function(r) {
      var options = []
      $.each(r, function(idx, el) {
        options.push('<option value="'+ el.code +'">'+ el.name +'</option>')
      })
      $target.html(options.join('')).trigger('change')
    })
  }

  $province.on('change', function (event) {
    update(event.currentTarget.value, $city)
  })

  $city.on('change', function (event) {
    update(event.currentTarget.value, $district)
  })
})

获取数据时如果想排除某些数据,可以使用 RegionFilterEvent 事件过滤,比如过滤掉直辖市:

// src/EventListener/RemoveDirectlyRegionListener.php

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Siganushka\RegionBundle\Event\RegionFilterEvent;
use Siganushka\RegionBundle\Entity\RegionInterface;

class RemoveDirectlyRegionListener implements EventSubscriberInterface
{
    const DIRECTLY_CODES = [110000, 120000, 310000, 500000];

    public function onRegionFilter(RegionFilterEvent $event)
    {
        $regions = array_filter($event->getRegions(), function(RegionInterface $region) {
            return !in_array($region->getCode(), self::DIRECTLY_CODES);
        });

        $event->setRegions($regions);
    }

    public static function getSubscribedEvents(): array
    {
        return [
            RegionFilterEvent::class => 'onRegionFilter',
        ];
    }
}