如何禁用“复选框” FAPI元素中的单个复选框?


31

标题基本上说明了一切,我想禁用复选框类型FAPI元素的单个复选框。

我不想使用JavaScript,也不想将其从复选框更改为多个复选框元素,因为该元素是由另一个模块提供的。

有什么想法吗?


您的问题有错别字:“禁用”
FR6

Answers:


36

Drupal 7中确实存在一种干净的方法!显然,根据这篇文章,它尚未被记录。

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#disabled'] = TRUE; //disables all options
  $form['checkboxes_element'][abc]['#disabled'] = TRUE; //disables option, called abc
}

另一个例子

您还可以将#access功能设置为FALSE,以完全隐藏该复选框。


3
纠正输入错误后,此代码绝对可以在D7中使用。谢谢!
贝丝

1
很棒!很高兴它对你有效。
timofey.com

2
如果使用#access,则如果在#default_values中设置了该复选框,则在提交时不会以表单状态值设置该复选框。
尼克,

这很好。
David Meister 2014年

在视图AFAICT中使用“更好的暴露过滤器”(BEF)的复选框(不能选择多个元素)不起作用。
1kenthomas

22

不幸的是,在FAPI中没有真正干净的方法可以做到这一点。如果确定的话,最好的选择是在checkboxes元素上更改一个附加的#process函数

添加到'checkboxes'类型的元素的默认函数实际上是一个函数(expand_checkboxes())将单个元素拆分为多个'checkbox'类型的元素,然后再合并为一个。如果要搭载第二个处理功能,则可以将其扩展到“复选框”元素的扩展组中,并禁用有问题的功能。

以下代码完全未经测试,因此请注意:

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#process'][] = 'mymodule_disable_element';
}

function mymodule_disable_element($element) {
  foreach (element_children($element) as $key) {
    if ($key == YOUR_CHECK_VALUE) {
      $element[$key]['#disabled'] = TRUE;
      return;
    }
  }
}

听起来比我采用的方法要好,后者是将主题函数附加到元素并preg_replace()在输出上运行a 。
Decipher

您可以添加一个“中断”;除非您希望两次看到相同的元素键,否则在上面的if语句中可以提高效率。
克里斯·科恩

克里斯,很好,我更改了代码段。谢谢!
伊顿

2
与@timofey的回复相比,接受的答案似乎有点过大。
Citricguy

6

这是我的Drupal 7代码,用于在“编辑用户”页面中更改Roles元素。

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#pre_render'][] = 'form_process_checkboxes'; // I had to add this one, or it will return the first role only with my callback bellow
  $form['checkboxes_element']['#pre_render'][] = 'mymodule_disable_element';
}

function mymodule_disable_element(($element) {
  foreach (element_children($element) as $key) {
    if ($key == YOUR_CHECK_VALUE) {
      $element[$key]['#attributes']['disabled'] = 'disabled';
    }
  }
  return $element;
}

3

我使用复选框作为“分配”和“未分配”。客户要求我禁用“未分配”,但是代表“分配”仍然很重要。请记住,DISABLED复选框提交为“ false”,如果处理不当将取消分配,因此我将复选框拆分为“处理这些”和“忽略这些禁用的”。这是如何做:

// Provide LIVE checkboxes only for un-assigned Partners
$form['partner']['partners'] = array(
  '#type' => 'checkboxes',
  '#options' => array_diff($partners, $assignments),
  '#title' => t($partnername),
);
// Provide DISABLED checkboxes for assigned Partners (but with a different variable, so it doesn't get processed as un-assignment)
$form['partner']['partner_assignments'] = array(
  '#type' => 'checkboxes',
  '#options' => $assignments,
  '#default_value' => array_keys($assignments),
  '#disabled' => TRUE,
  '#title' => t($partnername),
);

注意,在我的用例中,“ partner_assignments”是其自己的数组/变量,不会被处理为“ unssign”。感谢您的发布-它使我想到了这个解决方案。


3

D7。在这里,我们必须确保添加一个节点时,某个分类法术语引用选项始终不可选中,并且将始终保存到该节点。因此,我们进入了#after_build并禁用了该特定选项,但是必须确保最后会传递该特定选项。仅由于禁用它的原因会停止该选项到将来的钩子的行进。

// a constant
define('MYTERM', 113);

/**
 * Implements hook_form_alter().
 */
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
    if ($form_id == 'MYCONTENTTYPE_node_form') {
    $form['#after_build'][] = 'MYMODULE_MYCONTENTTYPE_node_form_after_build';
    }
}

/**
 * Implements custom after_build_function()
 */
function MYMODULE_MYCONTENTTYPE_node_form_after_build($form, &$form_state) {
  foreach (element_children($form['field_MYFIELD'][LANGUAGE_NONE]) as $tid) {
    if ($tid == MYTERM) {
      $element = &$form['field_MYFIELD'][LANGUAGE_NONE][$tid];
      $element['#checked'] = TRUE;
      $element['#attributes']['disabled'] = 'disabled';
    }
  }
  // here's ensured the term's travel goes on
  $form['field_MYFIELD'][LANGUAGE_NONE]['#value'] += drupal_map_assoc(array(MYTERM));
  return $form;
}

这就是禁用选项的样子:

在此处输入图片说明


2

我无法得到Eaton的书面答复(#process回调不返回任何内容,并且在复选框展开之前被调用),并且我还希望从禁用的复选框返回值(我希望将其永久检查)。这对我有用(D6)。

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#process'][] = 'mymodule_disable_element';
}

function mymodule_disable_element($element) {
  $expanded = expand_checkboxes($element);
  $checkbox =& $expanded[YOUR_CHECK_VALUE];
  $checkbox['#disabled'] = TRUE;
  $checkbox['#value_callback'] = 'mymodule_element_value_callback';
  return $expanded;
}

function mymodule_element_value_callback($element, $edit = FALSE) {
  // Return whatever value you'd like here, otherwise the element will return
  // FALSE because it's disabled.
  return 'VALUE';
}

如果有人知道更整洁的方式,我很想听听!


Fatal error: Call to undefined function expand_checkboxes()
leymannx 2014年

1
@koivo这是D6的答案,该功能在D7中不再存在
Andy

1

这是我的Drupal 7代码,用于在“编辑用户”页面中更改Roles元素。

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['checkboxes_element']['#pre_render'][] = 'form_process_checkboxes'; // I had to add this one, or it will return the first role only with my callback bellow
  $form['checkboxes_element']['#pre_render'][] = 'mymodule_disable_element';
}

function mymodule_disable_element(($element) {
  foreach (element_children($element) as $key) {
    if ($key == YOUR_CHECK_VALUE) {
      $element[$key]['#attributes']['disabled'] = 'disabled';
      return $element;
    }
  }
  return $element;
}

1

在Drupal 7中,为了禁用可字段实体中的select中的选项,我发现必须安装一个#process函数。不幸的是,这禁用了内置过程功能,form_process_checkboxes因此需要重新添加(或从过程功能中调用)。此外,在禁用已选中的复选框时,我发现form_type_checkboxes_value从输入中检索结果时,内置值回调()会忽略默认值。

$field_lang_form = &$your_form[$field][LANGUAGE_NONE];
$field_lang_form['#process'][] = 'form_process_checkboxes';
$field_lang_form['#process'][] = 'YOURMODULE_YOURFUNCTION_process';
$field_lang_form['#value_callback'] = 'YOURMODULE_form_type_checkboxes_value';

然后是这样的:

function YOURMODULE_YOURFUNCTION_process($element) {
  // Disallow access YOUR REASON, but show as disabled if option is set.
  foreach (element_children($element) as $field) {
    if (REASON TO DISABLE HERE) {
      if (!empty($element[$field]['#default_value'])) {
        $element[$field]['#disabled'] = TRUE;
      } else {
        $element[$club]['#access'] = FALSE;
      }
    }
  }
  return $element;
}

最后:

function YOURMODULE_form_type_checkboxes_value($element, $input = FALSE) {
  if ($input !== FALSE) {
    foreach ($element['#default_value'] as $value) {
      if (THIS OPTION WAS SET AND DISABLED - YOUR BUSINESS LOGIC) {
        // This option was disabled and was not returned by the browser. Set it manually.
        $input[$value] = $value;
      }
    }
  }
  return form_type_checkboxes_value($element, $input);
}

在这种情况下,我没有发现此页面上的其他答案。


1

这是我的示例(使用#after_build):

$form['legal']['legal_accept']['#type'] = 'checkboxes';
$form['legal']['legal_accept']['#options'] = $options;
$form['legal']['legal_accept']['#after_build'][] = '_process_checkboxes';

加上以下函数回调:

function _process_checkboxes($element) {
  foreach (element_children($element) as $key) {
    if ($key == 0) { // value of your checkbox, 0, 1, etc.
      $element[$key]['#attributes'] = array('disabled' => 'disabled');
      // $element[$key]['#theme'] = 'hidden'; // hide completely
    }
  }
  return $element;
}

在Drupal 6上进行了测试,但它也适用于Drupal 7。


Drupal 6

您可以使用以下功能(source):

/*
 * Change options for individual checkbox or radio field in the form
 * You can use this function using form_alter hook.
 * i.e. _set_checkbox_option('field_tier_level', 'associate', array('#disabled' => 'disabled'), $form);
 *
 * @param $field_name (string)
 *    Name of the field in the form
 * @param $checkbox_name (string)
 *    Name of checkbox to change options (if it's null, set to all)
 * @param $options (array)
 *    Custom options to set
 * @param $form (array)
 *    Form to change
 *
 * @author kenorb at gmail.com
 */
function _set_checkbox_option($field_name, $checkbox_name = NULL, $options, &$form) {
    if (isset($form[$field_name]) && is_array($form[$field_name])) {
        foreach ($form[$field_name] as $key => $value) {
            if (isset($form[$field_name][$key]['#type'])) {
                $curr_arr = &$form[$field_name][$key]; // set array as current
                $type = $form[$field_name][$key]['#type'];
                break;
            }
        }
        if (isset($curr_arr) && is_array($curr_arr['#default_value'])) {
            switch ($type) { // changed type from plural to singular
                case 'radios':
                    $type = 'radio';
                    break;
                case 'checkboxes':
                    $type = 'checkbox';
                    break;
            }

            foreach ($curr_arr['#default_value'] as $key => $value) {
                foreach($curr_arr as $old_key => $old_value) { // copy existing options for to current option
                    $new_options[$old_key] = $old_value;
                }
                $new_options['#type'] = $type;  // set type
                $new_options['#title'] = $value;  // set correct title of option
                $curr_arr[$key] = $new_options; // set new options

                if (empty($checkbox_name) || strcasecmp($checkbox_name, $value) == 0) { // check name or set for 
                    foreach($options as $new_key => $new_value) {
                        $curr_arr[$key][$new_key] = $value;
                    }
                }
            }
            unset($curr_arr['#options']); // delete old options settings
        } else {
            return NULL;
        }
    } else {
        return NULL;
    }
}

/*
 * Disable selected field in the form(whatever if it's textfield, checkbox or radio)
 * You can use this function using form_alter hook.
 * i.e. _disable_field('title', $form);
 *
 * @param $field_name (string)
 *    Name of the field in the form
 * @param $form (array)
 *    Form to change
 *
 * @author kenorb at gmail.com
 */
function _disable_field($field_name, &$form) {
    $keyname = '#disabled';

    if (!isset($form[$field_name])) { // case: if field doesn't exists, put keyname in the main array
        $form[$keyname] = TRUE;
    } else if (!isset($form[$field_name]['#type']) && is_array($form[$field_name])) { // case: if type not exist, find type from inside of array
        foreach ($form[$field_name] as $key => $value) {
            if (isset($form[$field_name][$key]['#type'])) {
                $curr_arr = &$form[$field_name][$key]; // set array as current
                break;
            }
        }
    } else {
        $curr_arr = &$form[$field_name]; // set field array as current
    }

    // set the value
    if (isset($curr_arr['#type'])) {
        switch ($curr_arr['#type']) {
            case 'textfield':
            default:
                $curr_arr[$keyname] = TRUE;
        }
    }
}

D7:同样,使用#after_build可以按需工作。同时确认使用#attribute禁用的设置。
SGhosh

0

我在drupal 6上使用以下代码:-

$form['statuses'] = array(
    '#type' => 'checkboxes',
    '#options' => $statuses,
    '#default_value' => $status_val,
    '#after_build' => array('legal_process_checkboxes')
    );

回调函数在这里:

/ ** *根据“功能”处理每个复选框是否已被子域使用。* @param Array $ element数组形式的复选框* /

function legal_process_checkboxes($element) {

  foreach (element_children($element) as $key) {

    $feature_id = $key;
    $res_total = '';

    $total = feature_used($feature_id) ;

    if ($total) {
      $element[$key]['#attributes'] = array('disabled' => 'disabled');
    }
  }
  return $element;
}

欢迎来到drupal.stackexchange.com!请修正您的代码格式。legal_process_checkboxes()函数之前的注释已保留在“代码”格式之外。谢谢。
ermannob 2013年

0

要考虑的重要一件事是禁用的复选框不会提交,因此您可能会发现您也需要强制#value选中该复选框。例如:

$element['child1']['#disabled'] = TRUE;
$element['child1']['#value'] = 'child1';

在我的情况下,如果没有此选项,$form_state['values']则不包含我的复选框值(默认情况下处于启用状态,但处于禁用状态)。


0

挂钩文本框,并使用数据库中的信息创建一个动态文本框

1°上升。来自数据库的数组,例如

$blah = array('test1' => 'Choose for test1', 'test2' => 'Choose for test2', ...)

2°机具 hook_form_alter()

/ ** *实现hook_form_alter()。*表格ID =观看次数曝光的表格* /

function test_form_alter(&$form, &$form_state, $form_id)
{
  //only for this particular form
  if ($form['#id'] == "views-exposed-form-advanced-search-page-2")
    {
       $form['phases'] = array(
           '#type' => 'checkboxes',
           '#options' => $blah,
      );
    }
}

3°多个字段将是可检查的!


0

如果要构建自己的表单,则无需通过单独的form_alter /#process /#pre_render函数运行,而只需从“复选框”切换为生成单个“复选框”元素即可。

$options = array(
   1 => t('Option one'),
   2 => t('Option two'),
);

// Standard 'checkboxes' method:
$form['my_element'] = array(
  '#type' => 'checkboxes',
  '#title' => t('Some checkboxes'),
  '#options' => $options,
);

// Individual 'checkbox' method:
$form['my_element'] = array(
  '#type' => 'container',
  '#attributes' => array('class' => array('form-checkboxes')),
  '#tree' => TRUE,
  'label' => array('#markup' => '<label>' . t('Some checkboxes') . '</label>',
);
foreach ($options as $key => $label) {
  $form['my_element'][$key] = array(
    '#type' => 'checkbox',
    '#title' => $label,
    '#return_value' => $key,
  );
}
// Set whatever #disabled (etc) properties you need.
$form['my_element'][1]['#disabled'] = TRUE;

'#tree' => TRUE当$ form_state ['values']数组到达验证/提交/重建时,为您提供与复选框版本相同的树结构。如果由于某种原因您不能或不想使用#tree,请为每个复选框提供一个'#parents' => array('my_element', $key)属性,以明确设置其在values结构中的位置。

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.