Compilazione automatica dei campi in base a un altro campo


10

Ho una situazione molto complessa in cui ho bisogno di un consiglio. Ho un tipo di contenuto my_content, a cui è collegato un campo di raccolta dei campi field_mycollection, che ha un campo di riferimento dell'entità che fa riferimento all'utente field_my_userreference, un campo del telefono field_my_phone, un campo di testo field_my_texte un altro campo di testo field_my_anothertext.

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

L'entità utente ha anche avere campi field_my_phone, field_my_texte field_my_yetanothertextche quest'ultima ha un nome macchina diversa.

Quello che voglio fare, se in my_contentforma di modifica / aggiunta, in field_my_userreferenceun utente è selezionato, gli altri campi dovrebbero essere compilati automaticamente dai dati dell'utente selezionato. I campi compilati automaticamente dovrebbero essere comunque modificabili.

Come potrei raggiungere questo obiettivo? Mi piacerebbe farlo, se possibile, con un po 'di codice, usando hook_form_FORM_ID_alter().


Hai bisogno che accada dal vivo sul modulo o sul salvataggio?
Mołot,

Live on form. L'ho già implementato nel salvataggio, che i dati verranno presi dall'entità utente se lasciati vuoti. Ma in realtà quello che mi serve sul modulo :(
Елин Й.

OK, ha posto la mia risposta.
Mołot,

Risposte:


11

Se vuoi che accada dal vivo, e tutti i campi sono già nel modulo, il modo più sicuro sarebbe quello hook_form_FORM_ID_alter()di aggiungere il seguente a un modulo:

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

Quindi nel copy_field_value.jscreare un comportamento:

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

È inoltre possibile utilizzare hook_form_FORM_ID_alter()per aggiungere un #ajaxparametro al campo di origine, ma il modulo farebbe chiamare un server su ogni campo di copia. Se devi effettivamente interrogare il database, è la strada da percorrere. Sarebbe piuttosto ampio descriverlo di nuovo qui. È necessario modificare l' $form_state["input"]array per aggiornare i valori reali visualizzati dall'utente. Fallo nella funzione di creazione del modulo, avvolgendolo con issetper evitare avvisi.

Se il tuo elemento form è $form["something"]["something"]["element"], il suo valore sarà in $form_state["input"]["something"]["something"]["element"]- e puoi impostarlo in modo hook_form_altercorretto, ricorda di prendere entrambi $forme come $form_stateriferimento.

Nota : il .on()metodo è stato aggiunto in jQuery 1.7, quindi sarà necessario jQuery Update per utilizzare direttamente questa risposta o tradurre il mio codice da utilizzare .change()o .blur()metodo.


Mille grazie per le istruzioni! Non sto molto bene sull'API JS di Drupal. Spiegheresti come ottengo i valori del campo dall'entità utente? Ad esempio, se viene selezionato un utente, come posso popolare i campi successivi con le informazioni di questo utente?
Елин Й.

1
@ ЕлинЙ. il trucco qui non è preoccuparsi dello sfondo php. Basta identificare i parametri ID dei <input>tag usando Firebug o uno strumento simile per il tuo browser preferito. Oppure usa qualsiasi altro selettore jQuery. Accadrà solo nel browser, quindi hai quello che hai sullo schermo. D'altra parte, se è necessario interrogare effettivamente il database (sembra che mi sia perso), #ajaxè la strada da percorrere. Ma sarebbe piuttosto ampio. È necessario modificare l' $form_state["values"]array per aggiornare i valori reali visualizzati dall'utente. Fallo nella funzione di creazione del modulo, avvolgendolo con issetper evitare avvisi.
Mołot,

Grazie ancora @ Mołot, proverò ad implementarlo domani, o forse stasera. Sembra che avrò bisogno di alcune ore per farlo funzionare davvero, se non di più.
Елин Й.

@ ЕлинЙ. buona fortuna, sentiti libero di tornare con altre domande e collegale qui nei commenti se sono collegati. Risposta aggiornata un po ', a proposito.
Mołot,

1
Ok, lo sperimenterò un po 'e scriverò le mie esperienze.
Елин Й.

4

Puoi farlo usando il modulo di campo calcolato

Il campo calcolato è un modulo di campo CCK molto potente che consente di aggiungere un "campo calcolato" personalizzato ai tipi di contenuto. Questi campi calcolati sono popolati con valori definiti tramite il codice PHP. Puoi attingere a tutto ciò che è disponibile per Drupal, inclusi altri campi, l'utente corrente, le tabelle del database, il nome. (Hai già sentito la potenza? :)) Puoi anche scegliere se archiviare i valori dei campi calcolati nel database con altri campi di contenuto o farli "calcolare" al volo durante le viste dei nodi. (Sebbene si noti che l'utilizzo di Views richiede valori memorizzati nel database.) Questo campo è letteralmente il coltellino svizzero dei campi CCK. Quindi inizia a cucinare i tuoi valori basati su PHP!


Grazie per la risposta rapida. Sembra molto promettente. Tuttavia, non voglio installare un modulo per questo, ma semplicemente scrivere un po 'di codice, poiché ho bisogno di tale funzionalità solo su quel modulo, e il sistema attuale è già troppo grande e molti moduli sono installati per funzionalità diverse.
Елин Й.

In secondo luogo, è possibile utilizzare questo modulo, per l'utente che sta creando o modificando il nodo per sovrascrivere manualmente i campi popolati automaticamente e salvare? In modo che, nell'entità utente e my_content vengano salvati valori diversi.
Елин Й.

Ciò dipende dal modo in cui è installato
4life,

Grazie @ 4life, ci proverò anche se non riesco a raggiungerlo con la codifica, usando le istruzioni di Mołot.
Елин Й.

2

Voglio pubblicare come l'ho realizzato grazie ai grandi aiuti di @ Mołot.

  1. Implementato hook_form_FORM_ID_alter () .
  2. Aggiunto un div avvolgente attorno alla raccolta dei campi.
  3. Poiché la raccolta my field è un campo multi-valore, è stato ripetuto e impostato la #ajaxproprietà per il campo field_my_userreference.
  4. Creata una funzione di richiamata che restituisce semplicemente l'elemento della raccolta di campi.
  5. Controllato nell'implementazione hook_form_FORM_ID_alter (), se $ form_state per la raccolta di campi è impostato. In caso affermativo, ottenere i valori dall'entità utente e popolare i campi di input del modulo con tali valori.

Il mio codice è simile a:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.