1: <?php
2: namespace TIC\FormBundle\Form\Type;
3:
4: #use Symfony\Component\Form\AbstractType as BaseType;
5: use TIC\FormBundle\Base\TICWidgetType as BaseType;
6:
7: use Symfony\Component\OptionsResolver\OptionsResolver;
8: use Symfony\Component\OptionsResolver\Options;
9: use Symfony\Component\Form\FormBuilderInterface;
10: use Symfony\Component\Form\FormInterface;
11: use Symfony\Component\Form\FormView;
12:
13: /**
14: * Sélecteur de choix (select, radios, checkboxes, selectize).
15: * Reprise du widget Symfony avec options supplémentaires
16: */
17: class ChoiceType extends BaseType
18: {
19: protected $form_parent = \Symfony\Component\Form\Extension\Core\Type\ChoiceType::class;
20:
21:
22: /**
23: * {@inheritdoc}
24: */
25: public function configureOptions(OptionsResolver $resolver): void
26: {
27: parent::configureOptions($resolver);
28:
29: $resolver->setDefaults(array(
30: 'with_js' => false, // application de selectize.js sur le select
31: 'direction' => 'auto', // direction des choix (dropdown) : down, up, auto ?
32: 'plugins' => array(), // remove_button, restore_on_backspace, optgroup_columns, drag_drop
33: 'remove' => true, // pour ajout par défaut du remove_button quand multiple
34: 'sortable' => false, // pour pouvoir ordonner les choix sélectionnés (active le plugin drag_drop)
35: 'excluded_choices' => array(), // liste de valeurs à exclure de la liste des choix
36: 'by_reference' => false, // true provoque du merge en multiple risquant de laisser un hash des data
37: ));
38:
39: $resolver->setAllowedTypes('with_js', array('bool'));
40: $resolver->setAllowedTypes('plugins', array('array'));
41: $resolver->setAllowedTypes('remove', array('bool'));
42: $resolver->setAllowedTypes('sortable', array('bool'));
43: $resolver->setAllowedTypes('excluded_choices', array('array'));
44:
45: $resolver->setAllowedValues('expanded', array(false, true, 'inline'));
46: $resolver->setAllowedValues('direction', array('down', 'up', 'auto'));
47:
48: $resolver->setNormalizer('choices', function (Options $options, $choices) {
49: return array_diff($choices, $options['excluded_choices']);
50: });
51:
52: $resolver->setNormalizer('sortable', function (Options $options, $sortable) {
53: if (! $options['multiple']) $sortable = false;
54: return $sortable;
55: });
56: $resolver->setNormalizer('by_reference', function (Options $options, $by_reference) {
57: if ($options['sortable']) $by_reference = false;
58: return $by_reference;
59: });
60:
61: $resolver->setNormalizer('with_js', function (Options $options, $with_js) {
62: if ($options['sortable']) $with_js = true;
63: if ($with_js && $options['expanded']) {
64: @trigger_error("Expanded selector don't use JS Selectize");
65: return false;
66: }
67: return $with_js;
68: });
69: }
70:
71:
72: /**
73: * {@inheritdoc}
74: */
75: public function buildView(FormView $view, FormInterface $form, array $options): void
76: {
77: parent::buildView($view, $form, $options);
78:
79: if ($options['with_js']) {
80: if (! isset($view->vars['attr']['class'])) $view->vars['attr']['class'] = '';
81: $view->vars['attr']['class'].= ' tic-selectize';
82: }
83:
84: // spécification de la taille du widget (ajout de classe bootstrap)
85: $this->setViewInputSizing($view);
86:
87: if ($options['multiple'] && $options['remove'] ) array_push($options['plugins'], 'remove_button');
88: if ($options['multiple'] && $options['sortable']) array_push($options['plugins'], 'drag_drop');
89: $view->vars['plugins'] = array_unique($options['plugins']);
90: $view->vars['with_js'] = empty($options['with_js']) ? false : true;
91: $view->vars['sortable'] = $options['sortable'];
92: $view->vars['direction'] = $options['direction'];
93:
94: if ($options['expanded'] === 'inline') {
95: $class = $options['multiple'] ? 'checkbox-inline' : 'radio-inline';
96: $view->vars['label_attr'] = $options['label_attr'] + array('class' => '');
97: $view->vars['label_attr']['class'] = trim($view->vars['label_attr']['class'].' '.$class);
98: $view->vars['expanded'] = true;
99: }
100: }
101:
102:
103: }
104: