Ausgewählte Kontrollkästchen (Taxonomie) füllen eine neue Auswahlliste mit Werten ausgewählter Kontrollkästchen

7

* Frage beantwortet: Hilfe mit hook_node_submit im benutzerdefinierten Modul zum Speichern von Daten erforderlich *


In Drupal 7 habe ich einen benutzerdefinierten Inhaltstyp. In diesem Abschnitt gibt es eine Mehrfachauswahlbegriffsreferenz, um Kategorien für diesen Inhalt auszuwählen.

Ich muss jetzt in der Lage sein, eine aus der zuvor ausgewählten Kategorie auszuwählen und sie irgendwie als 'Haupt'-Kategorie zu markieren.

Nehmen wir an, ich habe ein Referenzfeld für mehrere ausgewählte Begriffe mit den folgenden Optionen:

Apples
Bananas
Pears
Oranges
Grapes
Pineapples

Der Benutzer wählt Äpfel, Birnen und Trauben aus. Jetzt muss ich entweder:

  1. Erstellen Sie programmgesteuert ein weiteres Feld für jedes dieser ausgewählten Felder - möglicherweise mit einem Ajax-Rückruf - und verfügen Sie über Optionsfelder, damit ich nur einen der ausgewählten Begriffe auswählen kann, der meine Hauptkategorie ist.
  2. Erstellen Sie ein Radiofeld neben den angekreuzten Elementen - möglicherweise auch mit Ajax -, in dem ich das Hauptfeld aus den ausgewählten auswählen kann.

Hat jemand irgendwelche Ideen dazu?

Um es klarer zu machen, ich habe viele dieser Listen zu einem Inhaltstyp. Das Wiederholen jeder Liste als einzelne Werteliste ist keine Option.

Ich denke, meine beste Wette ist es, hook_form_alter()mit einem AJAX-Rückruf entweder ein einzelnes Optionsfeld neben dem Kontrollkästchen zu erstellen, das der Benutzer gerade angekreuzt hat, oder programmgesteuert eine neue Optionsfeldliste für jedes in der angegebenen Liste aktivierte Element zu erstellen.

Update: Ok, ich habe beschlossen, dass der beste Weg, dies zu tun, darin besteht, ein benutzerdefiniertes Modul zu erstellen, das Ajax verwendet, um ein Optionsfeld für jedes aktivierte Kontrollkästchen zu erstellen, mit dem das Element ausgewählt werden kann, das als Hauptelement verwendet werden soll.

Daher habe ich hook_form_alter()eine #after_buildFunktion hinzugefügt , da wir warten müssen, bis das Formular gerendert ist, bevor wir auf die Steuerbegriffswerte zugreifen können.

Hier ist mein Modul bisher. Ich verwende viele Kommentare, daher sollte klar sein, was ich versuche:

MYMODULE.module

/**
 * Implementation of HOOK_form_alter()
 * Do the ajax form alteration
 */
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {

  // 1.CONTENT FORM
  // I created a custom content type 'content' and added a term
  // reference to it 
  if($form_id == 'content_node_form') {

    // tax term ref is the main part, so let us
    // remove title and body fields
    unset($form['body']);
    unset($form['title']);

    // do our stuff after the form has been rendered ...
    $form['#after_build'][] = 'MYMODULE_after_build';

  }
}

/**
 * after_build function for content_node_form
 */
function MYMODULE_after_build(&$form, &$form_state) {

    dsm($form);  

    // In the after_build call we can now actually use the 
    // element_children function to grab the values of the fields that
    // don't start with a hash tag #
    // in this test case 1,2,3,4 and 5

    // wrap each of the elements rendered ...
    foreach(element_children($form['field_taxonomy']['und']) as $key) {

      $form['field_taxonomy']['und'][$key] += array(

        // this is added before the element and then replaced by our callback ..
        // we use the $key value in the id so that we know which div to replace 
        // depending on which checkbox is checked ...
        '#prefix' => '<div class="taxonomy_term_wrapper">
                        <div id="callback_replace_'.$key.'">Replace Me ' . $key . '</div>',

        // this is added after the element so we basically wrap around it ..
        '#suffix' => '</div>',

        // add some ajax stuff here ...
        '#ajax' => array(
          // name of the callback function to call upon change
          'callback' => 'MYMODULE_callback',
          // the id of the element that will be replaced
          'wrapper' => 'callback_replace_'.$key,
          // replace the wrapper
          'method' => 'replace',
          // what kind of effect do we want ...
          'effect' => 'fade',
          // show progress on callback
          'progress' => array('type' => 'throbber'),
        ),
      ); 



      if (!empty($form_state['values']['field_taxonomy']['und'][$key])) {
        // the form to show upon change ...
        $form['field_taxonomy']['und']['main_cat'] = array(
          // we want a radio button
          '#type' => 'radio',
          '#title' => t('Test Title'),
          '#description' => t('Test Description ...'),
          '#default_value' => empty($form_state['values']['field_taxonomy']['und'][$key]) ?
                              $form_state['values']['field_taxonomy']['und'][$key] :
                              $form_state['values']['field_taxonomy']['und'][$key],
        );
      }

    }

  return $form;
} 

function MYMODULE_callback($form, $form_state) {
 return $form['field_taxonomy']['und']['main_cat'];
}

So sieht es derzeit aus, bevor ein Kontrollkästchen aktiviert wird:

So sieht es derzeit aus, bevor ein Kontrollkästchen aktiviert wird

Der HTML-Code des gerenderten Formulars ist der folgende:

Bildschirmfoto

Tecjam
quelle
Es ist nicht wirklich eine Antwort als solche, aber schauen Sie sich das Beispielmodul an. Es hat einige nette Ajax-
Formbeispiele
Hallo Chapabu, danke für deine Antwort. Ich habe die Ajax-Beispiele verwendet, aber mein Problem liegt in der Tatsache, dass ich after_build verwenden muss, um meinen Code hinzuzufügen, und jetzt bin ich ratlos darüber, ob es nichts bewirkt ... Ich habe oben viel mehr Code hinzugefügt - einschließlich meines Fortschritts soweit mit dem modul. Vielleicht können Sie die Fehler sehen
Tecjam
hmm..das einzige was ich (schnell) in deinem after_build anders sehen kann ist das Format. In den Drupal-Dokumenten heißt es, dass es so aussehen sollte - $ form ['# after_build'] => array ('MYMODULE_after_build');
Chapabu
Ich glaube $ form ['# after_build'] => array ('MYMODULE_after_build'); ist dasselbe wie $ form ['# after_build'] [] = 'MYMODULE_after_build'; - Beachten Sie die []
Tecjam
Außerdem scheint die Funktion after_build einwandfrei zu funktionieren, da sie meine Taxonomiebegriffe in mein benutzerdefiniertes Div einschließt und meine Ersetzungsdivs hinzufügt. Nur der Rückruf funktioniert nicht ..
Tecjam

Antworten:

1

Erstellen Sie die Elemente als Kontrollkästchen. Zeigen Sie nach der Auswahl eine Dropdown-Liste mit diesen Elementen oder ein anderes Optionsfeld an, um die primäre Kategorie auszuwählen. Sie können das zweite Dropdown-Menü mit dem folgenden Code ausblenden, bis die ersten Kontrollkästchen aktiviert sind.

'#states' => array(
'visible' => array(
':input[name="your checkbox"]' => array('checked' => TRUE),
 ),
)

Fügen Sie dies zu dem Element hinzu, das Sie ausblenden möchten. Dies ist nur sichtbar, wenn das Kontrollkästchen aktiviert ist.

ana
quelle
0

Wie wäre es mit zwei Listen, eine mit dem Titel "Primär", die eine Auswahl trifft, die andere mit mehreren. Sie müssen sich noch mit der zweiten Liste oder Auswahl befassen, um Doppelspurigkeiten zu vermeiden.

Quader
quelle
Hallo und danke für deine Antwort. Ja, das würde natürlich funktionieren. Ich habe jedoch verdammt viele Listen auf der Seite zum Erstellen von Inhalten, und es ist keine Option, sie alle zweimal zu haben. Ich habe die obige Frage nur als Beispiel angeführt.
Tecjam