Symfony Form에서 연월을 풀다운으로 선택하는 필드를 만드는 방법

9781 단어 심포니PHP
과 같은 연월만을 선택하는 경우를 위해. DateTime 오브젝트에 매핑하는 전제.



어떻게 하는 것이 정답인지는 모르지만, DateType 를 그대로 사용하면 괴롭기 때문에 우선 잡하게 만들어 움직인 확장 FormType 를 실어 둡니다.
<?php
namespace Fivestar\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\ReversedTransformer;
use Symfony\Component\OptionsResolver\OptionsResolver;

class YearMonthType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function getParent()
    {
        return DateType::class;
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        if ($options['widget'] === 'choice') {
            $builder
                ->resetViewTransformers()
                ->addViewTransformer(new DateTimeToArrayTransformer(
                    $options['model_timezone'], $options['view_timezone'], array('year', 'month')
                ))
            ;
        }

        if ($options['input'] === 'array') {
            $builder
                ->resetModelTransformers()
                ->addModelTransformer(new ReversedTransformer(
                    new DateTimeToArrayTransformer($options['model_timezone'], $options['model_timezone'], array('year', 'month'))
                ))
            ;
        }
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'widget' => 'choice',
        ]);
    }

    /**
     * {@inheritdoc}
     */
     public function finishView(FormView $view, FormInterface $form, array $options)
     {
         if ($options['widget'] === 'choice') {
             $view['day']->vars['attr']['style'] = 'display:none;';
         }
     }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'year_month';
    }
}

DateType 를 기반으로 풀다운 형식을 사용하는 전제로서, day 필드의 존재마다 지우고 싶지만 아마 무리인 것 같다.

포인트는 Transformer 계를 한 번 리셋하고 재설정하고 있는 곳. style="display:none;" 오브젝트로 연월만을 취급하는 경우, 내부적으로는 일이나 시분초도 보완되어 1번 오브젝트를 경유하면 DateTimeday 는 아니고 null 제3 인수에서 1year 만을 참조하도록 해 두면 평화입니다.
$ php -r "var_dump((new DateTime('2015-12'))->format('Y-m-d H:i:s'));"
string(19) "2015-12-01 00:00:00"

입력 필수 요소라면 month 근처에 적당한 finishView 값을 value 라고 입력 필수의 경우 밖에 고려하지 않을 것 같은 코드도 상당히 많았으므로, 여러가지 고려된 녀석이 표준 나름으로 들어가 있으면 좋다고 생각했습니다. 난 하지 않습니다.

표시 결과


$builder->add('yearMonth', YearMonthType::class);

우선 그대로 낸 경우:


{{ form_row(form.yearMonth) }}

크레카의 유효 연월용 :


{{ form_row(form.yearMonth, {
  'date_pattern': '{{ month }}/{{ year }}',
}) }}

좋은 웹페이지 즐겨찾기