Como definir um campo de tipo de hora programaticamente?

8

Eu crio um tipo de entidade de conteúdo personalizado.

Eu quero um campo para o horário do evento.

Como não há campo de tempo, mas sim um dataTime_type, crio um plug-in para um campo personalizado:

FieldType: TimeItem.php

/**
 * Plugin implementation of the 'time' field type.
 *
 * @FieldType(
 *   id = "time",
 *   label = @Translation("Time Field"),
 *   description = @Translation("Permet la creation d'un champ de type time"),
 *   default_widget = "time_widget",
 *   default_formatter = "time_formatter"
 * )
 */

  /**
   * {@inheritdoc}
   */
  public static function schema(FieldStorageDefinitionInterface $field_definition) {
    return array(
        'columns' => array(
            'value' => array(
                'description' => 'The time value.',
                'type' => 'int',
                'length' => 6,
            ),
        ),

    );
  }

Eu tento alterar o tipo para o tempo (para o mysql), mas o erro do mysql me retorna um nulo para o tipo. Então, eu uso int para armazenar tempo em segundo lugar.

FieldWidget: TimeWIdget.php

/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$value = isset($items[$delta]->value) ? $items[$delta]->value : '';
$element += array(
'#type' => 'time', //HTML5 input
'#default_value' => $value,
'#size' => 4,
'#element_validate' => array(
array($this, 'validate'),
),
);

return $element;
}

Minha entidade:

 $fields['heure_evenement'] = BaseFieldDefinition::create('time')
        ->setLabel(t('test'))
        ->setDescription(t('test'))
        ->setRequired(TRUE)
        ->setDefaultValue('')
        ->setDisplayOptions('view', array(
            'label' => 'above',
            'type' => 'string',
            'weight' => 3,
        ))
        ->setDisplayOptions('form', array(
            'weight' => 3,
        ))
        ->setDisplayConfigurable('form', TRUE)
        ->setDisplayConfigurable('view', TRUE);

Tudo está funcionando, exceto uma coisa, a hora do tipo de entrada HTML5

O Drupal conhece alguma entrada em html5, mas nem todos ... digite tel, email, número, faixa, cor, data, data e hora está ok, mas não o tipo hora sozinho.

Então, eu esperava obtê-lo com um plugin personalizado, mas não ...

Editar 1

A única maneira que encontrei é criar 2 seleções para este tipo:

public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$value = isset($items[$delta]->value) ? $items[$delta]->value : '';

    //heure
    for($i=0;$i<=24;$i++){
        $hour[]=$i;
    }

    //minutes
    for($i=0;$i<=59;$i++){
        $minutes[]=$i;
    }


$element += array('hour'=>array(
    '#title'=>t('Hour'),
    '#type' => 'select',
    '#options'=>$hour,
    '#default_value' => $value,
    '#element_validate' => array(
    array($this, 'validate'),
    ),
)
);

    $element += array('minutes'=>array(
        '#title'=>t('Minutes'),
        '#type' => 'select',
        '#options'=>$minutes,
        '#default_value' => $value,
        '#element_validate' => array(
            array($this, 'validate'),
        ),
    )
    );


return $element;
}

Alguma idéia sobre isso?

Kevin
fonte
Preciso de um tipo de campo como esse. Você pode compartilhar seu código no github ou em outro lugar?
Adrian Cid Almaguer
Você pode usar o módulo drupal.org/project/time_field .
Lost Koder

Respostas:

12

A propriedade do elemento do formulário #typerefere-se a um tipo de elemento, não a um elemento HTML. Não há problema em definir seus próprios tipos de elementos (ou tipos de temas), e você pode fornecer sua própria marcação para isso. Isso pode ser feito implementando um plugin RenderElement .

Atualizar:

Você também pode usar o datetimeelemento render e desativar a parte da data.

$element['#date_date_element'] = 'none';

Atualização 2:

O formulário de comentário tem um exemplo de uma matriz de renderização que usa o datetimetipo Portanto, como orientação,

  $form['time_without_date'] = array(
    '#type' => 'datetime',
    '#title' => $this->t('Time without date'),
    // HTML 5 time element format can be H:i
    '#default_value' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '1970-01-01 20:00', 'UTC'),
    '#size' => 20,
    '#date_date_element' => 'none',
    // This sets html 5 time element use explicitly, probably not necessary.
    '#date_time_element' => 'time',
  );
mradcliffe
fonte
2
Também me lembrei de algo sobre o elemento datetime. Você deve poder definir nonea parte da data e recuperar apenas a parte da hora.
22416 mradcliffe
@mradcliffe Você poderia fornecer instruções detalhadas para este novato? Se eu conseguir fazê-lo funcionar, não hesitaria em dar-lhe a recompensa! Obrigado!
317 Chris Chris
Existe algo em particular em que você está preso? Provavelmente é difícil postar código em um comentário, mas gostaria de garantir que, no seu array de formulários, as propriedades apropriadas do elemento (chaves com '#') estejam definidas. Atualizarei a resposta com alguns exemplos de api.drupal.org daqui a pouco.
precisa saber é o seguinte
11
Ele criou outra pergunta aqui: drupal.stackexchange.com/questions/227029/… , pois sua pergunta era mais específica para o widget de campo do que para os elementos da API do formulário.
21417 mrclclfefe
11
@AdrianCidAlmaguer Sim, compartilhei o código aqui . Vou considerar transformá-lo no Github. Espero que ajude!
31717 Chris Chris