Browse Source

Form type : sonata_choice_field_mask

Copied from SonataDoctrinePhpcrAdminBundle
This widget allow to hide/display other fields in a form when a value in a select widget  is selected.
Jérôme FIX 11 years ago
parent
commit
475279fe1a

+ 69 - 0
Form/Type/ChoiceFieldMaskType.php

@@ -0,0 +1,69 @@
+<?php
+/*
+ * This file is part of the Sonata package.
+ *
+ * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ */
+
+namespace Sonata\AdminBundle\Form\Type;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\OptionsResolver\OptionsResolverInterface;
+use Symfony\Component\Form\FormInterface;
+use Symfony\Component\Form\FormView;
+
+class ChoiceFieldMaskType extends AbstractType
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function buildView(FormView $view, FormInterface $form, array $options)
+    {
+        $allFieldNames = array();
+        foreach ($options['map'] as $value => $fieldNames) {
+            foreach ($fieldNames as $fieldName) {
+                $allFieldNames[$fieldName] = $fieldName;
+            }
+        }
+        $allFieldNames = array_values($allFieldNames);
+
+        $view->vars['all_fields'] = $allFieldNames;
+        $view->vars['map'] = $options['map'];
+
+        $options['expanded'] = false;
+
+        parent::buildView($view, $form, $options);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setDefaultOptions(OptionsResolverInterface $resolver)
+    {
+        parent::setDefaultOptions($resolver);
+
+        $resolver->setDefaults(array(
+            'map' => array(),
+        ));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getParent()
+    {
+        return 'choice';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getName()
+    {
+        return 'sonata_type_choice_field_mask';
+    }
+}

+ 4 - 0
Resources/config/form_types.xml

@@ -34,6 +34,10 @@
         <service id="sonata.admin.form.type.collection" class="Sonata\AdminBundle\Form\Type\CollectionType">
             <tag name="form.type" alias="sonata_type_native_collection" />
         </service>
+        
+        <service id="sonata.admin.doctrine_orm.form.type.choice_field_mask" class="Sonata\AdminBundle\Form\Type\ChoiceFieldMaskType">
+            <tag name="form.type" alias="sonata_type_choice_field_mask" />
+        </service>
 
         <!-- Form Extension -->
         <service id="sonata.admin.form.extension.field" class="Sonata\AdminBundle\Form\Extension\Field\Type\FormTypeFieldExtension">

+ 35 - 0
Resources/doc/reference/form_types.rst

@@ -245,6 +245,41 @@ req_param_name_items_per_page
   defaults to "_per_page".  Ajax request parameter name which contains the limit of
   items per page.
 
+sonata_choice_field_mask
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Setting a field type of ``sonata_choice_field_mask`` will use an instance of
+``ChoiceFieldMaskType`` to render choice field.
+
+According the choice made only associated fields are displayed. The others fields are hidden.
+
+.. code-block:: php
+
+    class AcmeMenuAdmin extends Admin
+    {
+        protected function configureFormFields(FormMapper $formMapper)
+        {
+            $formMapper
+                ->add('linkType', 'sonata_type_choice_field_mask', array(
+                    'choices' =>  array('uri' => 'uri', 'route' => 'route'),
+                    'map' => array(
+                        'route' => array('route', 'parameters'),
+                        'uri' => array('uri'),
+                    ),
+                    'empty_value' => 'Choose an option',
+                    'required' => false
+                ))
+                ->add('route', 'text')
+                ->add('uri', 'text')
+                ->add('parameters')
+            ;
+        }
+    }
+
+map
+  Associative array. Describes the fields that are displayed for each choice.
+    
+    
 sonata_type_admin
 ^^^^^^^^^^^^^^^^^
 

+ 39 - 0
Resources/views/Form/form_admin_fields.html.twig

@@ -380,3 +380,42 @@ file that was distributed with this source code.
     </script>
 {% endspaceless %}
 {% endblock sonata_type_model_autocomplete_widget %}
+
+{% block sonata_type_choice_field_mask_widget %}
+    {{ block('choice_widget') }}
+    {% set main_form_name = id|slice(0, id|length - name|length) %}
+    <script type="text/javascript">
+        $(document).ready(function() {
+            var allFields = {{ all_fields|json_encode|raw }};
+            var map = {{ map|json_encode|raw }};
+
+            showMaskChoiceEl = $('#{{ main_form_name }}{{ name }}');
+            console.log(showMaskChoiceEl)
+            showMaskChoiceEl.on('change', function () {
+                choice_field_mask_show($(this).val());
+            });
+
+            function choice_field_mask_show(val)
+            {
+                var controlGroupIdFunc = function (field) {
+                    return '#sonata-ba-field-container-{{ main_form_name }}' + field;
+
+                };
+                if (map[val] == undefined) {
+                    $.each(allFields, function (i, field) {
+                        $(controlGroupIdFunc(field)).show();
+                    });
+                    return;
+                }
+
+                $.each(allFields, function (i, field) {
+                    $(controlGroupIdFunc(field)).hide();
+                });
+                $.each(map[val], function (i, field) {
+                    $(controlGroupIdFunc(field)).show();
+                });
+            }
+            choice_field_mask_show(showMaskChoiceEl.val());
+        });
+    </script>
+{% endblock %}

+ 52 - 0
Tests/Form/Type/ChoiceFieldMaskTypeTest.php

@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Sonata package.
+ *
+ * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Sonata\AdminBundle\Tests\Form\Type;
+
+use Sonata\AdminBundle\Form\Type\ChoiceFieldMaskType;
+
+use Symfony\Component\Form\Test\TypeTestCase;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class ChoiceFieldMaskTypeTest extends TypeTestCase
+{
+    public function testGetDefaultOptions()
+        {
+        $type = new ChoiceFieldMaskType();
+
+        $optionResolver = new OptionsResolver();
+
+        $type->setDefaultOptions($optionResolver);
+        $options = $optionResolver->resolve(
+            array(
+                'map' => array(
+                    'foo' => array( 'field1', 'field2'),
+                    'bar' => array( 'field3')
+            )
+        ));
+
+        $this->assertSame( array('foo'=> array('field1', 'field2'), 'bar'=> array('field3')), $options['map']);
+
+    }
+
+    public function testGetName()
+    {
+        $type = new ChoiceFieldMaskType();
+        $this->assertEquals('sonata_type_choice_field_mask', $type->getName());
+    }
+
+    public function testGetParent()
+    {
+        $type = new ChoiceFieldMaskType();
+        $this->assertEquals('choice', $type->getParent());
+    }
+
+}