选定复选框(分类法)使用选定框的值填充新的选择列表


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如下:

屏幕截图


这样并不是一个真正的答案,但是请尝试看一下“示例”模块。它有一些简洁的Ajax表单示例,可能会帮助您:) drupal.org/project/examples
Chapabu 2011年

您好Chapabu,谢谢您的回答。我使用过ajax示例,但是我的问题在于我需要使用after_build添加我的代码,现在我很困惑,因为它什么都不做...我在上面添加了很多代码-包括我的进度到目前为止,与模块有关。也许您可以看到错误
tecjam 2011年

嗯..我唯一能(很快)在after_build中看到不同的是格式。在Drupal文档中,它说应该看起来像这样-$ form ['#after_build'] => array('MYMODULE_after_build');
Chapabu 2011年

我相信$ form ['#after_build'] => array('MYMODULE_after_build'); 与$ form ['#after_build'] [] ='MYMODULE_after_build'相同;-注意[]
tecjam 2011年

另外,after_build函数似乎可以正常工作,因为它确实将我的分类法术语包装在了我的自定义div中,并添加了我的replace div。只是回调不起作用..
tecjam 2011年

Answers:


1

创建项目作为复选框。选择它们之后,显示一个包含这些项目的下拉列表或另一个单选按钮以选择主要类别。您可以使用以下代码隐藏第二个下拉菜单,直到选中第一个复选框。

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

将其添加到要隐藏的元素。只有在选中此复选框后,该元素才会可见。


0

两个列表怎么样?一个列表的标题是主选项,一个选项是另一个选项。您仍然需要解决第二个列表或选择,以消除重复。


嗨,谢谢您的回答。是的,那当然可以。但是,我在内容创建页面上遇到了很多列表,因此无法将它们全部都包含两次。为了示例,我简单地解决了上面的问题。
tecjam 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.