Drupal 8.7.6中hook_form_alter修改字段部件保存报错求助
解决Drupal 8.7.6中hook_form_alter修改文本字段为Select时的NestedArray错误
老哥,你遇到的这个Cannot create references to/from string offsets错误,本质是直接修改纯文本字段的widget类型时,没适配原字段的表单数据结构导致的。
纯文本字段默认的widget是多值嵌套结构,['widget'][0]下面是包含value子元素的数组,用来存储文本内容。你直接把['widget'][0]['#type']改成select后,破坏了这个结构的一致性——Drupal在处理表单提交时,还是按照原文本字段的逻辑去嵌套数组里找值,结果发现某个本该是数组的位置变成了字符串,自然就抛出错误了。
给你调整一下代码,替换整个widget结构来适配select类型,这样就能解决问题:
function mymodule_form_node_article_edit_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) { // 获取当前编辑的节点对象,拿到字段现有值 $node = $form_state->getFormObject()->getEntity(); $current_value = $node->get('field_testdrop')->value; $options = [ 'test1' => 'AAA', 'test2' => 'BBB', 'test3' => 'CCC', 'test4' => 'DDD', ]; // 完全替换widget,改成单值select的结构 $form['field_testdrop']['widget'] = [ '#type' => 'select', '#options' => $options, // 用现有值作为默认值,为空则选第一个选项 '#default_value' => $current_value ?: key($options), // 保留原字段的标题和必填设置 '#title' => $form['field_testdrop']['#title'], '#required' => $form['field_testdrop']['#required'], ]; }
为啥要这么改?
- 原来的文本字段widget是多值嵌套结构,我们直接把整个
widget换成单值的select元素,避免了嵌套数组和字符串偏移的冲突。 - 读取现有节点的字段值作为默认值,保证编辑时能正确显示已选内容。
- 保留原字段的标题、必填属性,保证表单体验和原来一致。
另外提一句:如果只是临时需求用hook修改还好,要是长期需要这个select部件,建议直接把字段类型改成列表(文本),在字段管理界面就能操作,这才是Drupal的最佳实践,比用hook维护要省心多了。
内容的提问来源于stack exchange,提问作者jmux
相关产品推荐
相关产品推荐

