sonata-project / SonataAdminBundle

The missing Symfony Admin Generator
https://docs.sonata-project.org/projects/SonataAdminBundle
MIT License
2.11k stars 1.26k forks source link

Form field type 'sonata_type_translatable_choice' cannot be used readonly or disabled #2842

Closed webdevilopers closed 9 years ago

webdevilopers commented 9 years ago

I have a sonata_type_translatable_choice expanded rendered as radio buttons. These buttons have to be "readonly" by default until e.g. a Javascript event "enables" it.

I tried the read_only attribute:

            $formMapper->add('durationType', 'sonata_type_translatable_choice', array(
                'choices' => DurationType::getTypeList(),
                'catalogue' => 'TimekeepingBundle',
                'empty_value' => 'type_not_specified',
                'expanded' => true,
                'required' => false,
//                'readonly' => true,
                'read_only' => true,
                'attr' => array(
                    'readonly' => 'readonly',
                    'disabled' => 'disabled',
                )
            ));

The HTML result:

<div id="sonata-ba-field-container-s55101cf205720_durationType" class="form-group">
        <label class=" control-label">
                                    Tageslänge
                            </label>
        <div class="sonata-ba-field sonata-ba-field-standard-natural">
            <ul class=" list-unstyled" readonly="readonly" disabled="disabled" id="s55101cf205720_durationType">
<li><label class=""><div class="iradio_flat-blue checked" style="position: relative;">
<input type="radio" checked="checked" value="" readonly="readonly" name="s55101cf205720[durationType]" id="s55101cf205720_durationType_placeholder" style="position: absolute; opacity: 0;"><ins class="iCheck-helper" style="position: absolute; top: 0%; left: 0%; display: block; width: 100%; height: 100%; margin: 0px; padding: 0px; background: none repeat scroll 0% 0% rgb(255, 255, 255); border: 0px none; opacity: 0;"></ins></div><span>
keine Angabe                </span></label></li>
<li><label class=""><div class="iradio_flat-blue" style="position: relative;">
<input type="radio" value="half" readonly="readonly" name="s55101cf205720[durationType]" id="s55101cf205720_durationType_0" style="position: absolute; opacity: 0;"><ins class="iCheck-helper" style="position: absolute; top: 0%; left: 0%; display: block; width: 100%; height: 100%; margin: 0px; padding: 0px; background: none repeat scroll 0% 0% rgb(255, 255, 255); border: 0px none; opacity: 0;"></ins></div><span>
halbtags                </span></label></li>
<li><label class=""><div class="iradio_flat-blue" style="position: relative;">
<input type="radio" value="full" readonly="readonly" name="s55101cf205720[durationType]" id="s55101cf205720_durationType_1" style="position: absolute; opacity: 0;"><ins class="iCheck-helper" style="position: absolute; top: 0%; left: 0%; display: block; width: 100%; height: 100%; margin: 0px; padding: 0px; background: none repeat scroll 0% 0% rgb(255, 255, 255); border: 0px none; opacity: 0;"></ins></div><span>
                    ganztags                </span></label></li></ul>             
                    </div>
    </div>

Though the HTML attribute is passed to every single input but has no effect. I still can click the buttons. This seems to be the expected behaviour

The disabled HTML attribute is passed to the ul element but not the input.

Using the form attribute disabled would have the expected effect on the input:

            $formMapper->add('durationType', 'sonata_type_translatable_choice', array(
                'choices' => DurationType::getTypeList(),
                'catalogue' => 'TimekeepingBundle',
                'empty_value' => 'type_not_specified',
                'expanded' => true,
                'required' => false,
//                'readonly' => true,
                'read_only' => true,
                'attr' => array(
//                    'disabled' => 'disabled',
                    'readonly' => 'readonly'
                ),
                'disabled' => true
            ));

but unfortunately this will complety remove the field from validation:

    /**
     * @Assert\Callback
     */
    public function validateDurationType(ExecutionContextInterface $context)
    {
        if ($this->getDurationType() === null) {
            $context->addViolationAt('durationType', 'timekeepingEntry.durationType.notNull', array(), null);
        }
    }

This assert will have no effect because it cannot add a violation to a disabled field.

I think the latter could be an issue with Symfony forms and validation itself. Maybe this can also be regarded as the expected behaviour. A workaround would be to set the violation on a diffrent - non-disabled - element.

But shouldn't the HTML template add the disabled attribute to the inputs then?

Related issues:

webdevilopers commented 9 years ago

The readonly attribute is not available for radio buttons:

As stated a disabled element will not be validated. Ergo should the HTML:

webdevilopers commented 9 years ago

This seems to be a Symfony Form Radio Button problem itself:

Closing this issue for now.