web-dev-qa-db-fra.com

Remplissage automatique des champs basé sur un autre champ

J'ai une situation très complexe où j'ai besoin de quelques conseils. J'ai un type de contenu my_content, Auquel est associé un champ de collecte de champs field_mycollection, Qui a un champ de référence d'entité faisant référence à l'utilisateur field_my_userreference, Un champ de téléphone field_my_phone, Un champ de texte field_my_text Et un autre champ de texte field_my_anothertext.

My Content
|_ field_mycollection
   |_ field_my_userreference
   |_ field_my_phone
   |_ field_my_text
   |_ field_my_anothertext

L'entité utilisateur a également des champs field_my_phone, field_my_text Et field_my_yetanothertext Dont ce dernier a un nom de machine différent.

Ce que je veux faire, si dans my_content Modifier/ajouter un formulaire, dans field_my_userreference Un utilisateur est sélectionné, les autres champs doivent être remplis automatiquement à partir des données de l'utilisateur sélectionné. Les champs remplis automatiquement doivent toujours être modifiables.

Comment pourrais-je atteindre cet objectif? J'aimerais le faire, si possible, avec un peu de codage, en utilisant hook_form_FORM_ID_alter().

10
Елин Й.

Si vous souhaitez que cela se produise en direct et que tous les champs figurent déjà dans le formulaire, le moyen le plus sûr serait d'utiliser hook_form_FORM_ID_alter() pour ajouter les éléments suivants à un formulaire:

$form['#attached']['js'] = array(
  drupal_get_path('module', 'module_name') . '/js/copy_field_value.js',
);

Puis dans copy_field_value.js Créez un comportement:

(function($) {
  Drupal.behaviors.moduleNameCopyFieldValue = {
    attach: function (context, settings) {

      // Repeat this for all fields as needed
      $('#source', context).on('blur', function () { 
        // above you can use change instead of blur if element is not changed by another js
        if (!$('#destination').val() || 0 === $('#destination').val().length) {
          $('#destination').val($(this).val());
          // wrap line above in "if no value" like I did, or other condition you like
        }
      });
      // end of "repeat this"
    }
  };
})(jQuery);

Vous pouvez également utiliser hook_form_FORM_ID_alter() pour ajouter paramètre #ajax au champ source, mais cela rendrait votre formulaire appelant un serveur sur chaque copie de champ. Si vous devez réellement interroger la base de données, c'est la voie à suivre. Il serait assez large de le décrire à nouveau ici. Vous devez modifier le tableau $form_state["input"] Pour mettre à jour les valeurs réelles vues par l'utilisateur. Faites-le dans la fonction de création de formulaire, enveloppez-le avec isset pour éviter les avis.

Si votre élément de formulaire est $form["something"]["something"]["element"], Sa valeur sera dans $form_state["input"]["something"]["something"]["element"] - et vous pouvez le définir dans hook_form_alter, N'oubliez pas de prendre les deux $form et $form_state par référence.

Remarque : .on() La méthode a été ajoutée dans jQuery 1.7, vous aurez donc besoin de jQuery Mettre à jour pour utiliser cette réponse directement, ou traduire mon code pour utiliser la méthode .change() ou .blur() .

11
Mołot

Vous pouvez le faire en utilisant le module de champ calculé

Le champ calculé est un module de champ CCK très puissant qui vous permet d'ajouter des "champs calculés" personnalisés à vos types de contenu. Ces champs calculés sont remplis de valeurs que vous définissez via PHP. Vous pouvez utiliser tout ce qui est disponible pour Drupal, y compris d'autres champs, l'utilisateur actuel, les tables de base de données, vous l'appelez. ( encore? :)) Vous pouvez également choisir de stocker vos valeurs de champ calculées dans la base de données avec d'autres champs de contenu, ou de les faire "calculer" à la volée pendant les vues de nœud. (Bien que vous deviez noter que l'utilisation de Views nécessite des valeurs stockées dans la base de données.) Ce champ est littéralement le couteau suisse des champs CCK. Alors commencez à cuisiner vos valeurs basées sur PHP!

4
4life

Je veux poster comment je l'ai réalisé grâce aux grandes aides de @ Mołot.

  1. Implémenté hook_form_FORM_ID_alter () .
  2. Ajout d'un div enveloppant autour de la collection de champs.
  3. Étant donné que la collection my field est un champ à plusieurs valeurs, parcourez-le et définissez le #ajax propriété pour le champ field_my_userreference.
  4. Création d'une fonction de rappel qui renvoie simplement l'élément de collection de champs.
  5. Vérifié dans l'implémentation hook_form_FORM_ID_alter (), si $ form_state pour la collection de champs est défini. Si oui, récupérez les valeurs de l'entité utilisateur et remplissez les champs de saisie du formulaire avec ces valeurs.

Mon code ressemble à:

function MYMODULE_form_my_content_node_form_alter(&$form, &$form_state, $form_id) {
  $form['field_mycollection']['#prefix'] = '<div id="mycollection-wrapper">';
  $form['field_mycollection']['#suffix'] = '</div>';
  foreach ($form['field_mycollection']['und'] as $key => $fc_mycollection) {
    if (is_numeric($key)) {
      $form['field_mycollection']['und'][$key]['field_my_userreference']['und']['#ajax'] = array(
        'callback' => 'MYMODULE_mycollection_callback',
        'wrapper' => 'mycollection-wrapper',
      );
      if (isset($form_state['values']['field_mycollection']['und'][$key]['field_my_userreference']['und'][0]['target_id'])) {
        $user_wrapper = entity_metadata_wrapper('user', $form_state['values']['field_mycollection']['und'][$key]['field_my_userreference']['und'][0]['target_id']);
        $form_state['input']['field_mycollection']['und'][$key]['field_my_text']['und'][0]['value'] = $user_wrapper->field_my_text->value() ? $user_wrapper->field_my_text->value() : '';
        $form_state['input']['field_mycollection']['und'][$key]['field_my_anothertext']['und'][0]['value'] = $user_wrapper->field_my_text->value() ? $user_wrapper->field_my_yetanothertext->value() : '';
      }
    }
  }
}

function MYMODULE_mycollection_callback($form, &$form_state) {
  return $form['field_mycollection'];
}
2
Елин Й.

Cela peut être un peu tard, mais ce module https://www.drupal.org/project/entityreference_autofill , semble faire ce que vous décrivez. Je l'ai utilisé et il peut aussi vous aider.

0
Moses Sseggembe