Das automatische Ausfüllen von Feldern basierend auf einem anderen Feld

10

Ich habe eine sehr komplexe Situation, in der ich Rat brauche. Ich habe einen Inhaltstyp my_content, an den ein Feldsammlungsfeld angehängt ist field_mycollection, an das ein Entitätsreferenzfeld verweist, das auf den Benutzer verweist field_my_userreference, ein Telefonfeld field_my_phone, ein Textfeld field_my_textund ein anderes Textfeld field_my_anothertext.

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

Die Benutzerentität hat auch Felder field_my_phone, field_my_textund field_my_yetanothertextdiese hat einen anderen Computernamen.

Was ich tun möchte, wenn in einem my_contentBearbeitungs- / Hinzufügungsformular field_my_userreferenceein Benutzer ausgewählt ist, sollten die anderen Felder automatisch aus den Daten des ausgewählten Benutzers ausgefüllt werden. Die automatisch ausgefüllten Felder sollten weiterhin bearbeitet werden können.

Wie könnte ich dieses Ziel erreichen? Ich würde es gerne tun, wenn möglich, mit etwas Codierung, mit hook_form_FORM_ID_alter().

Елин Й.
quelle
Müssen Sie es live in Form oder beim Speichern tun?
Mołot
Lebe in Form. Ich habe es bereits implementiert, dass beim Speichern die Daten von der Benutzerentität übernommen werden, wenn sie leer bleiben. Aber eigentlich was ich brauche es auf Formular :(
Елин Й.
OK, stellte meine Antwort.
Mołot

Antworten:

11

Wenn Sie möchten, dass dies live geschieht und sich alle Felder bereits im Formular befinden, können Sie hook_form_FORM_ID_alter()einem Formular am sichersten Folgendes hinzufügen:

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

Dann im copy_field_value.jsVerhalten erstellen:

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

Sie können auch Parameter zum Quellfeld hook_form_FORM_ID_alter()hinzufügen , aber es würde Ihr Formular veranlassen, bei jeder Feldkopie einen Server aufzurufen. Wenn Sie die Datenbank tatsächlich abfragen müssen, ist dies der richtige Weg. Es wäre ziemlich weit gefasst, es hier neu zu beschreiben. Sie müssen das Array ändern , um die vom Benutzer angezeigten realen Werte zu aktualisieren. Führen Sie dies in der Formularerstellungsfunktion aus und wickeln Sie es ein , um Hinweise zu vermeiden.#ajax$form_state["input"]isset

Wenn Ihr Formularelement ist $form["something"]["something"]["element"], ist sein Wert in $form_state["input"]["something"]["something"]["element"]- und Sie können es in hook_form_alterOrdnung setzen. Denken Sie daran, beide $formund als $form_stateReferenz zu nehmen .

Hinweis : Die .on()Methode wurde in jQuery 1.7 hinzugefügt, sodass Sie jQuery Update benötigen , um diese Antwort direkt zu verwenden, oder meinen Code für die Verwendung .change()oder .blur()Methode zu übersetzen.

Mołot
quelle
Vielen Dank für die Anleitung! Ich bin nicht sehr gut in Drupals JS-API. Würden Sie erklären, wie ich die Feldwerte von der Benutzerentität erhalte? Wenn beispielsweise ein Benutzer ausgewählt ist, wie kann ich die nächsten Felder mit den Informationen dieses Benutzers füllen?
Елин Й.
1
@ ЕлинЙ. Der Trick hier ist nicht, sich um den PHP-Hintergrund zu kümmern. Identifizieren Sie einfach die ID-Parameter von <input>Tags mit Firebug oder einem ähnlichen Tool für Ihren bevorzugten Browser. Oder verwenden Sie einen anderen jQuery-Selektor. Dies geschieht nur im Browser, sodass Sie das haben, was Sie auf dem Bildschirm haben. Auf der anderen Seite #ajaxist der richtige Weg, wenn Sie tatsächlich eine Datenbank abfragen müssen (anscheinend habe ich das verpasst) . Aber es wäre ziemlich breit. Sie müssen das $form_state["values"]Array ändern , um die vom Benutzer angezeigten realen Werte zu aktualisieren. Führen Sie dies in der Formularerstellungsfunktion aus und wickeln Sie es ein isset, um Hinweise zu vermeiden.
Mołot
Nochmals vielen Dank @ Mołot, ich werde versuchen, es morgen oder vielleicht heute Abend umzusetzen. Es scheint, ich werde ein paar Stunden brauchen, damit es wirklich funktioniert, wenn nicht mehr.
Елин Й.
@ ЕлинЙ. Viel Glück, zögern Sie nicht, mit weiteren Fragen zurückzukehren und sie hier in Kommentaren zu verlinken, wenn sie verbunden sind. Antwort ein bisschen aktualisiert, übrigens.
Mołot
1
Ok, ich werde ein bisschen experimentieren und meine Erfahrungen schreiben.
Елин Й.
4

Sie können dies mit dem berechneten Feldmodul tun

Computed Field ist ein sehr leistungsfähiges CCK-Feldmodul, mit dem Sie Ihren Inhaltstypen benutzerdefinierte "berechnete Felder" hinzufügen können. Diese berechneten Felder werden mit Werten gefüllt, die Sie über PHP-Code definieren. Sie können auf alles zurückgreifen, was Drupal zur Verfügung steht, einschließlich anderer Felder, des aktuellen Benutzers, Datenbanktabellen, wie Sie es nennen. (Fühlen Sie die Kraft schon? :)) Sie können auch wählen, ob Sie Ihre berechneten Feldwerte in der Datenbank mit anderen Inhaltsfeldern speichern oder sie während der Knotenansichten im laufenden Betrieb "berechnen" lassen möchten. (Obwohl Sie beachten sollten, dass für die Verwendung von Ansichten in der Datenbank gespeicherte Werte erforderlich sind.) Dieses Feld ist buchstäblich das Schweizer Taschenmesser für CCK-Felder. Beginnen Sie also damit, Ihre PHP-basierten Werte zu ermitteln!

4Leben
quelle
Danke für die schnelle Antwort. Das klingt sehr vielversprechend. Ich möchte jedoch kein Modul dafür installieren, sondern einfach Code schreiben, da ich eine solche Funktionalität nur in diesem Formular benötige und das eigentliche System bereits zu groß ist und viele Module für verschiedene Funktionen installiert sind.
Елин Й.
Ist es zweitens möglich, mit diesem Modul für den Benutzer, der den Knoten erstellt oder bearbeitet, die automatisch ausgefüllten Felder manuell zu überschreiben und zu speichern? Damit in der Benutzerentität und in my_content unterschiedliche Werte gespeichert werden.
Елин Й.
Das würde von der Art und Weise abhängen, wie es eingerichtet ist
4life
Danke @ 4life, ich werde es auch versuchen, wenn ich es mit Codierung nicht erreichen kann, indem ich die Anweisungen von Mołot verwende.
Елин Й.
2

Ich möchte veröffentlichen, wie ich es dank der großen Hilfe von @ Mołot erreicht habe.

  1. Implementierte den hook_form_FORM_ID_alter () .
  2. Es wurde ein Wrapping-Div um die Feldsammlung hinzugefügt.
  3. Da die my field-Auflistung ein mehrwertiges Feld ist, iterieren Sie darüber und legen Sie die #ajaxEigenschaft für das Feld fest field_my_userreference.
  4. Es wurde eine Rückruffunktion erstellt, die das Feldsammlungselement einfach zurückgibt.
  5. Überprüft in der Implementierung von hook_form_FORM_ID_alter (), ob $ form_state für die Feldsammlung festgelegt ist. Wenn ja, rufen Sie die Werte von der Benutzerentität ab und füllen Sie die Formulareingabefelder mit diesen Werten.

Mein Code sieht aus wie:

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'];
}
Елин Й.
quelle