Выбранные флажки (таксономия) заполняют новый список выбора значениями выбранных полей

7

* вопрос ответил: нужна помощь с hook_node_submit в пользовательском модуле для сохранения данных *


В Drupal 7 у меня есть пользовательский тип контента. В этом есть ссылка для выбора нескольких терминов, чтобы выбрать категории для этого контента.

Теперь мне нужно иметь возможность выбрать одну из ранее выбранных категорий и пометить ее как «основную» категорию.

Допустим, у меня есть поле для выбора нескольких терминов со следующими параметрами:

Apples
Bananas
Pears
Oranges
Grapes
Pineapples

Пользователь выбирает яблоки, груши и виноград. Теперь мне либо нужно:

  1. Программно создайте другое поле для каждого из этих выбранных - возможно, с помощью обратного вызова ajax - и установите переключатели, чтобы я мог выбрать только один из выбранных терминов, который является моей основной категорией.
  2. Создайте радио-поле рядом с отмеченными пунктами - возможно, также с помощью ajax - где я могу выбрать основной из выбранных.

У кого-нибудь есть идеи по этому поводу?

Чтобы быть более понятным, у меня есть много этих списков на один тип контента. Повторять каждый список как единый список значений не вариант.

Я полагаю, что лучше всего использовать hook_form_alter()функцию обратного вызова AJAX с некоторым типом, чтобы создать либо одну радиокнопку рядом с галочкой, которую пользователь только что отметил, либо программно создать новый список радиополей для каждого элемента, отмеченного в указанном списке.

Обновление: Хорошо, я решил, что лучший способ сделать это - создать пользовательский модуль, который использует ajax для создания переключателя для каждого флажка, позволяющего выбрать элемент, который должен использоваться в качестве основного элемента.

Поэтому я использовал hook_form_alter()для добавления #after_buildфункции, поскольку нам нужно дождаться отображения формы, прежде чем мы сможем получить доступ к значениям налогового термина.

Вот мой модуль до сих пор. Я использую много комментариев, поэтому должно быть ясно, что я пытаюсь сделать:

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

Вот как это выглядит в настоящее время перед установкой флажка:

Вот как это выглядит в настоящее время перед установкой флажка

HTML-код представленной формы следующий:

Скриншот

tecjam
источник
Это не совсем ответ как таковой, но попробуйте взглянуть на модуль примеров. В нем есть несколько аккуратных примеров форм ajax, которые могут помочь вам на вашем пути :) drupal.org/project/examples
Chapabu
Привет Чапабу, спасибо за ваш ответ. Я использовал примеры ajax, но моя проблема заключается в том, что мне нужно использовать after_build для добавления своего кода, и теперь я озадачен тем, что он ничего не делает ... Я добавил намного больше кода выше - включая мой прогресс пока что с модулем. Может быть, вы можете увидеть ошибки
Tecjam
хм ... единственное, что я могу (быстро) увидеть по-разному в вашем after_build - это формат. В документации Drupal говорится, что это должно выглядеть так - $ form ['# after_build'] => array ('MYMODULE_after_build');
Чапабу
Я считаю, что $ form ['# after_build'] => array ('MYMODULE_after_build'); аналогично $ form ['# after_build'] [] = 'MYMODULE_after_build'; - Обратите внимание на []
tecjam
Кроме того, функция after_build, кажется, работает нормально, поскольку она оборачивает мои таксономические термины в мой пользовательский div и добавляет мои замещающие div. Просто обратный вызов не работает ..
Tecjam

Ответы:

1

создать элементы как флажки. после того, как они выбраны, покажите выпадающий список с этими элементами или другой переключатель, чтобы выбрать основную категорию. Вы можете скрыть второй раскрывающийся список, используя следующий код, пока не будут установлены первые флажки.

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

добавьте это к элементу, который вы хотите скрыть. Это будет видно только тогда, когда установлен флажок.

изречений
источник
0

Как насчет двух списков, один из которых называется первичным, который занимает один выбор, другой - несколько. Вам все равно придется обратиться ко второму списку или выбору, чтобы устранить дублирование.

штучный камень
источник
Привет и спасибо за ваш ответ. Да, конечно, это будет работать. Тем не менее, у меня есть чертовски много списков на странице создания контента, и иметь их все дважды нельзя. Я просто уточнил вопрос выше для примера.
tecjam