You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drupal hook_form_user_register_form_alter设置#required不生效问题

Drupal注册表单字段required属性设置不生效的原因及解决方案

1. 字段Widget层级设置错误(最常见原因)

Drupal字段的$form['field_name']['widget']只是widget的外层容器,实际承载用户输入的表单元素在其下的子层级,直接给容器加#required属性不会生效。

  • 单值普通文本类字段:实际表单元素路径为 $form['field_district']['widget'][0]['value']
  • 单值实体引用类字段:实际表单元素路径为 $form['field_district']['widget'][0]['target_id']
  • 多值字段:需要给每个delta(数值键)对应的子元素都设置required属性

你可以先安装Devel模块,通过dpm($form['field_district']['widget'])打印数组结构确认实际的表单元素路径,单值字段的修正代码示例:

function bncreports_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id)
{
  $form['account']['mail']['#attributes'] = ['onblur' => "getElementById('edit-name').value=this.value.toLowerCase();"];
  $form['account']['name']['#description'] = 'Use Email address as your username';
  $form['account']['name']['#attributes'] = ['onblur' => 'this.value=this.value.toLowerCase();'];
  // 修正层级后设置required
  $form['field_district']['widget'][0]['value']['#required'] = TRUE;
}

如果需要兼容多值字段,可以遍历子元素:

use Drupal\Core\Render\Element;

function bncreports_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id)
{
  // 原有其他代码不变
  foreach (Element::children($form['field_district']['widget']) as $delta) {
    // 按实际字段类型调整value为对应的键名,比如实体引用改为target_id
    $form['field_district']['widget'][$delta]['value']['#required'] = TRUE;
  }
}

2. Widget自带的#process回调覆盖设置

部分特殊字段(比如层级选择器、地址字段、第三方模块提供的字段)自带的#process回调会在你的form_alter执行后重新渲染元素,覆盖你设置的#required属性。
这种情况可以给widget追加一个自定义后置process回调,在widget原生处理逻辑执行完后再设置required:

// 在form_alter中追加process回调
$form['field_district']['widget']['#process'][] = 'bncreports_set_district_required';

// 自定义回调函数
function bncreports_set_district_required($element, FormStateInterface $form_state, $complete_form) {
  foreach (Element::children($element) as $delta) {
    $element[$delta]['value']['#required'] = TRUE;
  }
  return $element;
}

3. 其他模块的form alter优先级更高

如果有其他模块也修改了该字段的属性,且模块权重比你的bncreports模块高,你的修改会被后续执行的其他模块alter逻辑覆盖。可以调整你的模块权重,让它最后执行:

  • 直接修改数据库system表中bncreports对应的weight字段值,设置为大于其他表单修改模块的权重即可。
  • 或者通过hook_module_implements_alter调整hook的执行顺序。

4. 字段在表单显示配置中为隐藏状态

先进入后台「账户设置 >> 管理表单显示 >> 注册表单」,确认field_district字段没有被设置为隐藏,隐藏状态的字段即使设置了required也不会生效。

内容的提问来源于stack exchange,提问作者user4202824

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 13:24:07