Masquage / affichage dynamique des champs de l'API de champ dans Drupal 7

14

J'ai créé une entité avec un formulaire «ajouter un nouveau». L'entité elle-même possède un nombre limité de variables réelles. J'ai ajouté la plupart des données supplémentaires dont j'ai besoin en utilisant des champs personnalisés (c'est-à-dire l'API Field).

À ce stade, je dois pouvoir masquer dynamiquement un champ en fonction de la valeur d'un autre. Par exemple, si un champ déroulant a sa valeur définie sur Non, un autre champ doit être masqué, sinon il doit être affiché.

D'après ce que je peux voir, il est assez facile d'ajouter cette fonctionnalité aux champs créés à l'aide de l'API Form (c'est-à-dire via la propriété AJAX), mais y a-t-il un moyen d'y parvenir en utilisant des champs attachés? Je n'ai aucun problème à utiliser Javascript personnalisé si c'est ce qui est nécessaire pour résoudre ce problème.

NRaf
la source
Je ne sais pas si drupal.org/project/conditional_fields est encore prêt pour le d7, mais cela pourrait valoir la peine d'être examiné
Jukebox

Réponses:

5

jQuery fonctionne bien pour cela:

(function($) {
  $(document).ready(function() {
    $('#select1').change(function() {
      switch ($(this).val()) {
        case '1':
          $('#field2').hide();
          break;
        default:
          $('#field2').show();
          break;
      }
    });
  });
}) (jQuery);
Keithm
la source
Ouais, j'ai fini par utiliser drupal_add_js sur la page du formulaire et j'ai fini par le faire dans jQuery. Je me demandais simplement s'il y avait une façon plus "Drupal" de faire ça.
NRaf
Je mentionnerais que je ne suis pas un grand fan de l'approche Drupal #states de la visibilité, c'est pourquoi je ne l'ai pas suggérée ci-dessus.
Keithm
@keithm Pourriez-vous expliquer pourquoi vous n'êtes pas un fan des États (à partir de 2015, D7). Je travaille sur un projet où nous essayons de prendre la décision d'utiliser #states vs drupal_add_js. Pourquoi pensez-vous que l'un est un meilleur choix que l'autre?
blue928
C'est une question de préférence légitime du programmeur à mon avis; ma justification peut différer de la vôtre. Cela dit, dans la pratique, je n'aime pas avoir recours à une autre syntaxe qui duplique les fonctionnalités trouvées dans Javascript / jQuery. Lorsque j'ai essayé #states, j'ai également trouvé les cas d'utilisation pour lesquels il est apparemment conçu trop limitant. Quand mon problème s'est étendu en dehors de ces cas d'utilisation, j'ai quand même dû réécrire le tout en Javascript.
Keithm
19

Dans Drupal 7, vous pouvez utiliser $ form #statesau lieu d'un script jQuery personnalisé. Exemple:

  $form['student_type'] = array(
    '#type' => 'radios',
    '#options' => array(
      'high_school'   => t('High School'),
      'undergraduate' => t('Undergraduate'),
      'graduate'      => t('Graduate'),
    ),
    '#title' => t('What type of student are you?')
  );

  // High school information.
  $form['high_school']['tests_taken'] = array(
    '#type' => 'checkboxes',
    '#options' => drupal_map_assoc(array(t('SAT'), t('ACT'))),
    '#title' => t('What standardized tests did you take?'),
    // This #states rule says that this checkboxes array will be visible only
    // when $form['student_type'] is set to t('High School').
    // It uses the jQuery selector :input[name=student_type] to choose the
    // element which triggers the behavior, and then defines the "High School"
    // value as the one that triggers visibility.
    '#states' => array(
      'visible' => array(   // action to take.
        ':input[name="student_type"]' => array('value' => 'high_school'),
      ),
    ),
  );

Voici un exemple si vous souhaitez utiliser #statespour la condition de plusieurs valeurs:

 $form['student_type'] = array(
    '#type' => 'checkboxes',
    '#options' => array(
      'high_school'   => t('High School'),
      'undergraduate' => t('Undergraduate'),
      'graduate'      => t('Graduate'),
    ),
    '#title' => t('What type of student are you?')
  );

  // High school information.
  $form['high_school']['tests_taken'] = array(
    '#type' => 'textfield',
    '#title' => t('What standardized tests did you take?'),
    '#states' => array(
      'visible' => array(   // action to take.
        ':input[name="student_type[high_school]"]' => array('checked' => TRUE),
        ':input[name="student_type[undergraduate]"]' => array('checked' => TRUE),
        ':input[name="student_type[graduate]"]' => array('checked' => FALSE),
      ),
    ),
  );

Voir le moduleform_example/form_example_states.inc from examples pour plus de détails et d'exemples.

milkovsky
la source
En parlant de cela #states, je n'ai jamais trouvé de moyen de définir des conditions de visibilité plus complexes, telles que: masquer le contrôle A lorsque la valeur du contrôle B est dans le tableau (x, y, z). Connaissez-vous une syntaxe pour cela?
Artur
1
Voir ma mise à jour ci-dessus
milkovsky
4

Vous devriez essayer les champs conditionnels , je pense que ce module est indispensable pour cette tâche. Vous pouvez définir des dépendances entre les champs sur une interface d'administration conviviale. Par exemple, vous pouvez définir le Achamp pour qu'il soit uniquement visible si le Bchamp a la valeur " 1234 ", ou vous pouvez définir le champ de Ctexte pour qu'il soit visible uniquement lorsque le Dchamp est coché, ou définir le Echamp sur invisible s'il Fest focalisé, etc.

Sur le formulaire de téléchargement, ces dépendances seront définies côté client, sur l'affichage du nœud, ces dépendances seront définies côté serveur.

Vous pouvez définir ces dépendances à admin/structure/types/manage/[YOURCONTENTTYPESMACHINENAME]/dependencies.

Champs conditionnels (Source de l'image: la page du projet )

Sk8erPeter
la source