Les cases à cocher sélectionnées (taxonomie) remplissent une nouvelle liste de sélection avec les valeurs des cases sélectionnées

7

* réponse à la question: Besoin d'aide avec hook_node_submit dans le module personnalisé pour enregistrer les données *


Dans Drupal 7, j'ai un type de contenu personnalisé. Dans ce document, il existe une référence de termes à sélection multiple pour sélectionner des catégories pour ce contenu.

Je dois maintenant pouvoir en sélectionner un dans la catégorie précédemment sélectionnée et le marquer en quelque sorte comme catégorie «principale».

Disons que j'ai un champ de référence de termes à sélection multiple avec les options suivantes:

Apples
Bananas
Pears
Oranges
Grapes
Pineapples

L'utilisateur sélectionne des pommes, des poires et des raisins. Maintenant, je dois soit:

  1. Créer par programme un autre champ pour chacun de ces éléments sélectionnés - peut-être avec un rappel ajax - et avoir des boutons radio pour que je ne puisse sélectionner que l'un des termes sélectionnés, lequel est ma catégorie principale.
  2. Créez un champ radio à côté des éléments cochés - peut-être aussi avec ajax - où je peux sélectionner le principal parmi ceux sélectionnés.

Quelqu'un at-il des idées à ce sujet?

Pour être plus clair, j'ai beaucoup de ces listes sur un type de contenu. Répéter chaque liste en tant que liste de valeurs unique n'est pas une option.

Je suppose que mon meilleur pari est d'utiliser le hook_form_alter()avec une sorte de rappel AJAX pour créer soit un seul bouton radio à côté de la case à cocher que l'utilisateur vient de cocher, soit créer par programmation une nouvelle liste de champs radio pour chaque élément coché dans la liste spécifiée.

Mise à jour: Ok, j'ai décidé que la meilleure façon de le faire serait de créer un module personnalisé qui utilise ajax pour créer un bouton radio pour chaque case cochée, permettant de sélectionner l'élément qui devrait être utilisé comme élément principal.

J'ai donc l'habitude hook_form_alter()d'ajouter une #after_buildfonction car nous devons attendre que le formulaire soit rendu avant de pouvoir accéder aux valeurs des termes fiscaux.

Voici mon module jusqu'à présent. J'utilise beaucoup de commentaires, il devrait donc être clair ce que j'essaie de faire:

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

Voici à quoi il ressemble actuellement avant de cocher une case:

Voici à quoi il ressemble actuellement avant de cocher une case

Le code HTML du formulaire rendu est le suivant:

capture d'écran

tecjam
la source
Ce n'est pas vraiment une réponse en tant que telle, mais essayez de jeter un œil au module Exemples. Il a quelques exemples de formulaires ajax soignés qui pourraient vous aider tout au long de votre chemin :) drupal.org/project/examples
Chapabu
Salut Chapabu, merci pour ta réponse. J'ai utilisé les exemples ajax, mais mon problème réside dans le fait que je dois utiliser after_build pour ajouter mon code et maintenant je suis perplexe quant à ce qu'il ne fait rien ... J'ai ajouté beaucoup plus de code ci-dessus - y compris mes progrès jusqu'à présent avec le module. Vous pouvez peut-être voir les erreurs
tecjam
hmm..la seule chose que je peux (rapidement) voir différente dans votre after_build est le format. Dans les documents Drupal, il dit que cela devrait ressembler à ceci - $ form ['# after_build'] => array ('MYMODULE_after_build');
Chapabu
Je crois que $ form ['# after_build'] => array ('MYMODULE_after_build'); est identique à $ form ['# after_build'] [] = 'MYMODULE_after_build'; - Notez le []
tecjam
En outre, la fonction after_build semble fonctionner correctement car elle encapsule mes termes de taxonomie dans mon div personnalisé et ajoute mes remplaçants. Juste le rappel ne fonctionne pas ..
tecjam

Réponses:

1

créez les éléments sous forme de cases à cocher. après leur sélection, affichez une liste déroulante avec ces éléments ou un autre bouton radio pour sélectionner la catégorie principale. vous pouvez masquer la deuxième liste déroulante à l'aide du code suivant jusqu'à ce que les premières cases à cocher soient sélectionnées.

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

ajoutez-le à l'élément que vous souhaitez masquer. Cela ne sera visible que si la case est cochée.

ana
la source
0

Que diriez-vous de deux listes, l'une intitulée principale qui prend une sélection, l'autre multiple. Vous devrez toujours traiter la deuxième liste ou sélection pour éliminer les doublons.

Pierre de taille
la source
Salut et merci pour votre réponse. Oui, bien sûr, cela fonctionnerait. Cependant, j'ai beaucoup de listes sur la page de création de contenu et les avoir toutes deux fois n'est pas une option. J'ai simplement répondu à la question ci-dessus à titre d'exemple.
tecjam