Symfony2, ¿Cómo agregar un campo de tipo de fecha oculta a un formulario?

Estoy probando el siguiente escenario:

In myclassType

public function buildForm(FormBuilder $builder, array $options)
{
    $builder
        ->add('day','hidden')
        ->add('date', 'hidden' ) 
        ->add('hours')
        ->add('comment','textarea')
    ;
}

In myclass

class myclass
{
    //.. Other stuff

    /**
     * @ORM\Column(type="date")
     *
     * @var date $date
     */
    protected $date;
}

Al renderizar me sale este error:

An exception has been thrown during the rendering of a template ("Catchable Fatal Error:
 Object of class DateTime could not be converted to string in 
C:\wamp\www\PMI_sf2\app\cache\dev\twig\fb\40\8957f80f2358a6f4112c3427b387.php line 684") in
 form_div_layout.html.twig at line 171.

¿Alguna idea de cómo puedo ocultar un campo de tipo Fecha?

preguntado el 22 de mayo de 12 a las 21:05

Por interés, ¿por qué quieres ocultarlo? ¿Cuál es el caso de uso? -

Digamos, para un formulario de edición para insertar la fecha de edición en segundo plano:

6 Respuestas

Forma

$builder
    ->add('day','hidden')
    ->add('date',null,array( 'attr'=>array('style'=>'display:none;')) )
... 

contestado el 22 de mayo de 12 a las 21:05

Nota: algunos navegadores (p. ej., IE8) no enviarán el campo si display: none Está establecido. Usar visibility: hidden en lugar de. - Luis Belli

¡Y usa 'label' => false para ocultar la etiqueta! - Rodrigo Ferrari

no debes usar un truco de visibilidad .css, pero deja que Symfony represente el formulario necesario: Mario

Cree un DataTransformer simple del objeto DateTime a una cadena y un nuevo tipo de formulario llamado, por ejemplo, 'hidden_datetime' que usa el nuevo DataTransformer y tiene el tipo de formulario oculto como padre.

<?php

namespace YourProject\YourBundle\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;

class DateTimeToStringTransformer implements DataTransformerInterface
{

    public function __construct()
    {   
    }

    /**
     * @param \DateTime|null $datetime
     * @return string
     */
    public function transform($datetime)
    {
        if (null === $datetime) {
            return '';
        }       
        return $datetime->format('Y-m-d H:i:s');
    }

    /**
     * @param  string $datetimeString
     * @return \DateTime
     */
    public function reverseTransform($datetimeString)
    {
        $datetime = new \DateTime($datetimeString);
        return $datetime;
    }
} 

..

<?php

namespace YourProject\YourBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormBuilderInterface;
use YourProject\YourBundle\Form\DataTransformer\DateTimeToStringTransformer;

class HiddenDateTimeType extends AbstractType
{

    public function __construct()
    {
    }

    public function getName()
    {
        return 'hidden_datetime';
    }

    public function getParent()
    {
        return 'hidden';
    }   

     public function buildForm(FormBuilderInterface $builder, array $options)
    {   
        $transformer = new DateTimeToStringTransformer();
        $builder->addModelTransformer($transformer);
    }   

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        parent::setDefaultOptions($resolver);   
        $resolver->setDefaults(array(
        ));
    }    
}

registre el nuevo tipo de formulario 'hidden_datetime' como un servicio en services.yml

yourproject.hidden_datetime.form.type:
    class: YourProject\YourBundle\Form\Type\HiddenDateTimeType
    tags:
        - { name: form.type, alias: hidden_datetime } 

El nuevo tipo hidden_datetime se puede usar en su formulario:

// EN mitipodeclase

public function buildForm(FormBuilder $builder, array $options)
{
    $builder
            ->add('createdAt','hidden_datetime')
            ->add('comment','textarea')
    ;
}

Respondido el 13 de enero de 14 a las 13:01

Ya existe un DateTimeTransformer para este propósito: Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer - Julien Fastre

Ninguna de las soluciones anteriores funcionó con Symfony 3.3. Terminé creando un tipo simple:

<?php

namespace <YourProject>\<YourBundle>\Form\Type;

use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;

class HiddenDateTimeType extends HiddenType implements DataTransformerInterface
{
    /**
    * {@inheritdoc}
    */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->addModelTransformer($this);
    }

    /**
    * {@inheritdoc}
    */
    public function transform($data)
    {
        return $data->format("Y-m-d H:i:s");
    }

    /**
    * {@inheritdoc}
    */
    public function reverseTransform($data)
    {
        try {
            return new \DateTime($data);
        } catch (\Exception $e) {
            throw new TransformationFailedException($e->getMessage());
        }
    }

    public function getName()
    {
        return 'hidden_datetime';
    }
}

Úselo en su formulario de esta manera:

<?php

namespace <YourProject>\<YourBundle>\Form;

use <YourProject>\<YourBundle>\Form\Type\HiddenDateTimeType;

class ReportType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('creationTime', HiddenDateTimeType::class, array(
                'required' => true,
            ));
    }
}

No hay nada que agregar services.yml.

Respondido 22 Feb 18, 13:02

Pequeño error tipográfico en su código, debería ser: throw new TransformationFailedException($e->getMessage()); - navitrónico

@navitronic Gracias por informar el error tipográfico. Estaba en el código real y pasó desapercibido :-) - Frederic Marchal

Por suerte, esta solución todavía funciona en Symfony 5 :-) Solo agrega un nuevo método para ocultar la etiqueta public function configureOptions(OptionsResolver $resolver) { parent::configureOptions($resolver); $resolver->setDefault('label', false); } Muchas gracias - okki

Aún más fácil. Basado en la solución martti

Simplemente extiende DateTimeType y define padre como 'oculto'.

<?php

namespace YourProject\YourBundle\Form\Type\HiddenDateTimeType

use Symfony\Component\Form\Extension\Core\Type\DateTimeType;

class HiddenDateTimeType extends DateTimeType
{
    public function getName()
    {
        return 'hidden_datetime';
    }

    public function getParent(array $options)
    {
        return 'hidden';
    }
}

Registre el tipo de formulario como un servicio:

yourproject.hidden_datetime.form.type:
    class: YourProject\YourBundle\Form\Type\HiddenDateTimeType
    tags:
        - { name: form.type, alias: hidden_datetime }

Y tendrá acceso completo a todas las opciones específicas de DateTimeType

public function buildForm(FormBuilder $builder, array $options)
{

    $builder
        ->add('from' , 'hidden_date', array(
            'widget' => 'single_text',
            'format' => 'Y-m-d',
            'label' => 'popin.from',
            'required' => true
        ));

Respondido 11 Feb 14, 10:02

Forma

public function buildForm(FormBuilder $builder, array $options){
    $builder
        ->add('day','hidden')
        ->add('date') 
        ->add('hours')
        ->add('comment','textarea');
}

Vista

<form action="{{ path('some-save-action') }}" method="post" {{ form_enctype(form) }}>
    <div style="display: none">
         {{ form_row(form.date) }}
    </div>

    {{ form_errors(form) }}
    {{ form_rest(form) }}
    <input type="submit" value="Save" class="button confirm big"/>
</form>

contestado el 22 de mayo de 12 a las 21:05

Me gustó la idea, pero ¿hay algún soporte para eso en Symfony2? - dudo

No lo creo... @a.aitboudad tiene una solución alternativa, pero si tiene un estilo que contiene DIV, seguirá siendo visible. También puede extender el tipo de campo predeterminado de Symfony para agregar la opción oculta y extender el bloque de formulario "form_row", para agregar estilo = "mostrar: ninguno" al contener DIV, si usa el diseño DIV. Maciej Pyszyński

Puede controlar la salida del formulario más directamente que esto. Es bastante fácil tematizar campos específicos. Hay dos pasos. Debe asegurarse de que el campo del formulario espera una representación de cadena única de la fecha. Así que configure el widget de fecha en single_text. Luego anule el campo de fecha para generar un campo oculto en lugar de un campo de texto.

Forma

$builder->add('date', 'date', array('widget' => 'single_text'));

Ramita

{% form_theme form _self %}

{# Makes all dates hidden, you can also name your field specifically #}
{% block date_row %}
    {{ block('hidden_widget') }} {# This is normally 'field_widget' #}
{% endblock %}

Vea http://symfony.com/doc/current/cookbook/form/form_customization.html#form-theming

respondido 25 nov., 13:09

Esto aún funciona con Symfony 3.4, pero debes anular el tipo. {%- establecer tipo = 'oculto' -%} - Daniel P

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.