Comment définir un champ de type de temps par programme?

8

Je crée un type d'entité de contenu personnalisé.

Je veux un champ pour l'heure de l'événement.

Puisqu'il n'y a pas de champ horaire, mais un dataTime_type, je crée un plugin pour un champ personnalisé:

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,
            ),
        ),

    );
  }

J'essaye de changer le type en temps (pour mysql) mais l'erreur mysql me renvoie un null pour le type. J'utilise donc int pour stocker le temps en seconde.

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;
}

Mon entité:

 $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);

Tout fonctionne sauf une chose, l' heure du type d'entrée HTML5

Drupal connaît certaines entrées en html5 mais pas toutes ... le type tel, email, numéro, plage, couleur, date, datetime est correct mais pas le type heure seul.

J'espérais donc l'obtenir avec un plugin personnalisé, mais non ...

Modifier 1

La seule façon que j'ai trouvée est de créer 2 select pour ce type:

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;
}

Une idée à ce sujet?

Kevin
la source
J'ai besoin d'un type de champ comme celui-ci, pouvez-vous partager votre code dans github ou ailleurs?
Adrian Cid Almaguer
Vous pouvez utiliser le module drupal.org/project/time_field .
Lost Koder

Réponses:

12

La propriété d'élément de formulaire #typefait référence à un type d'élément, pas à un élément HTML. Il est correct de définir vos propres types d'éléments (ou types de thèmes), et vous pouvez fournir votre propre balisage pour cela. Cela peut être fait en implémentant un plugin RenderElement .

Mise à jour:

Vous pouvez également utiliser l' datetimeélément de rendu et désactiver la partie date.

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

Mise à jour 2:

Le formulaire de commentaire contient un exemple de tableau de rendu qui utilise le datetimetype. Donc, étant donné que comme ligne directrice,

  $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
la source
2
Je me suis également souvenu de quelque chose sur l'élément datetime. Vous devriez pouvoir définir nonela partie date et récupérer uniquement la partie heure.
mradcliffe
@mradcliffe Pourriez-vous fournir des instructions détaillées pour ce débutant? Si je suis en mesure de le faire fonctionner, je n'hésiterais pas à vous donner la prime! Merci!
Chris Happy
Y a-t-il quelque chose de particulier sur lequel vous êtes coincé? Il est probablement difficile de publier du code dans un commentaire, mais je m'assurerais que dans votre tableau de formulaire les propriétés d'élément appropriées (clés avec '#') sont définies. Je mettrai à jour la réponse avec quelques exemples d'api.drupal.org dans un peu.
mradcliffe
1
Il a créé une autre question ici: drupal.stackexchange.com/questions/227029/… , car sa question était plus spécifique au widget de champ plutôt qu'aux éléments d'API de formulaire.
mradcliffe
1
@AdrianCidAlmaguer Oui, j'ai partagé le code ici . Je vais envisager de le transformer en Github. J'espère que cela aide!
Chris Happy