根据其他字段自动填充字段


10

我的情况非常复杂,需要一些建议。我有一个内容类型my_content,它具有一个附加的字段收集字段field_mycollection,它具有一个引用用户的实体引用字段field_my_userreference,一个电话字段field_my_phone,一个文本字段field_my_text和另一个文本字段field_my_anothertext

My Content
|_ field_mycollection
   |_ field_my_userreference
   |_ field_my_phone
   |_ field_my_text
   |_ field_my_anothertext

该用户实体也有字段field_my_phonefield_my_text并且field_my_yetanothertext其中后者具有不同的机器名。

如果要my_contentfield_my_userreference用户中选择“ 编辑/添加”形式,我要执行的操作应从所选用户的数据中自动填充其他字段。自动填充的字段仍应可编辑。

我怎样才能实现这个目标?如果可能的话,我想使用进行一些编码hook_form_FORM_ID_alter()


您需要它在表单上还是保存时进行?
Mołot

活在表格上。我已经实现了保存,如果保留为空,数据将从用户实体获取。但实际上我需要它的形式:(
ЕлинЙ.

好,请回答我。
Mołot

Answers:


11

如果您希望它实时发生,并且所有字段都已经在表单上,​​那么最安全的方法是使用hook_form_FORM_ID_alter()在表单上添加以下内容:

$form['#attached']['js'] = array(
  drupal_get_path('module', 'module_name') . '/js/copy_field_value.js',
);

然后在copy_field_value.js创建行为中:

(function($) {
  Drupal.behaviors.moduleNameCopyFieldValue = {
    attach: function (context, settings) {

      // Repeat this for all fields as needed
      $('#source', context).on('blur', function () { 
        // above you can use change instead of blur if element is not changed by another js
        if (!$('#destination').val() || 0 === $('#destination').val().length) {
          $('#destination').val($(this).val());
          // wrap line above in "if no value" like I did, or other condition you like
        }
      });
      // end of "repeat this"
    }
  };
})(jQuery);

您还可以使用hook_form_FORM_ID_alter()向源字段添加#ajax参数,但这会使您的表单在每个字段副本上调用服务器。如果您需要实际查询数据库,那是一种方法。在这里重新进行描述将是相当广泛的。您需要更改$form_state["input"]数组以更新用户看到的实际值。在表单创建函数中执行此操作,并用它包装起来isset以避免产生通知。

如果你的表单元素$form["something"]["something"]["element"],它的价值将是$form_state["input"]["something"]["something"]["element"]-你可以将它设置在hook_form_alter没事,只是记得要既$form$form_state引用。

注意.on()方法是在jQuery 1.7中添加的,因此您需要jQuery Update才能直接使用此答案,或者翻译我的代码以使用.change().blur()方法。


非常感谢您的指示!我对Drupal的JS API不太满意。您能否解释一下如何从用户实体获取字段值?例如,如果选择了一个用户,如何用该用户的信息填充下一个字段?
ЕлинЙ.

1
@ЕлинЙ。这里的技巧不是在乎php背景。只需<input>使用Firebug或您喜欢的浏览器的类似工具识别标签的ID参数即可。或使用任何其他jQuery选择器。它只会在浏览器中发生,因此您可以在屏幕上看到所有内容。另一方面,如果您需要实际查询数据库(似乎我错过了这一点),#ajax则是一种方法。但这将是非常广泛的。您需要更改$form_state["values"]数组以更新用户看到的实际值。在表单创建函数中执行此操作,并用它包装起来isset以避免产生通知。
Mołot

再次感谢@Mołot,我将在明天或今天晚上尝试实施。似乎我需要几个小时才能使其真正发挥作用,甚至还需要更多时间。
ЕлинЙ.

@ЕлинЙ。祝您好运,如果有更多问题,请随时返回并在评论中将其链接到此处。更新的答案,顺便说一句。
Mołot

1
好的,我会做一些实验,然后写我的经验。
ЕлинЙ.

4

您可以使用计算字段模块执行此操作

计算字段是功能非常强大的CCK字段模块,可让您向内容类型添加自定义“计算字段”。这些计算字段将填充您通过PHP代码定义的值。您可以使用Drupal可用的任何东西,包括其他字段,当前用户,数据库表,只要您为它命名即可。(感觉还强大吗?:))您还可以选择将计算的字段值与其他内容字段一起存储在数据库中,还是在节点视图期间即时“计算”它们。(尽管您应该注意,使用Views需要数据库存储值。)此字段实际上是CCK字段的瑞士军刀。因此,开始准备基于PHP的值!


感谢您及时的回复。听起来很有希望。但是,我不想为此安装模块,而只是编写一些代码,因为我只需要在该表单上就需要这样的功能,而实际的系统已经太大了,并且为各种功能安装了许多模块。
ЕлинЙ.

其次,对于正在创建或编辑节点的用户,是否可以使用此模块手动覆盖自动填充的字段并保存?这样,在用户实体和my_content中保存了不同的值。
ЕлинЙ.

那将取决于它的设置方式
4life

感谢@ 4life,如果不能使用Mołot的编码进行编码,我也会尝试一下。
ЕлинЙ.

2

感谢@Mołot的大力帮助,我想发表一下我是如何实现的。

  1. 实现了hook_form_FORM_ID_alter()
  2. 在字段集合周围添加了一个包装div。
  3. 由于my字段集合是一个多值字段,因此对其进行迭代并设置#ajaxfield 的属性field_my_userreference
  4. 创建了一个回调函数,该函数仅将字段集合项返回。
  5. 在hook_form_FORM_ID_alter()实现中检查是否为字段集合设置了$ form_state。如果是,请从用户实体获取值,然后使用这些值填充表单输入字段。

我的代码如下:

function MYMODULE_form_my_content_node_form_alter(&$form, &$form_state, $form_id) {
  $form['field_mycollection']['#prefix'] = '<div id="mycollection-wrapper">';
  $form['field_mycollection']['#suffix'] = '</div>';
  foreach ($form['field_mycollection']['und'] as $key => $fc_mycollection) {
    if (is_numeric($key)) {
      $form['field_mycollection']['und'][$key]['field_my_userreference']['und']['#ajax'] = array(
        'callback' => 'MYMODULE_mycollection_callback',
        'wrapper' => 'mycollection-wrapper',
      );
      if (isset($form_state['values']['field_mycollection']['und'][$key]['field_my_userreference']['und'][0]['target_id'])) {
        $user_wrapper = entity_metadata_wrapper('user', $form_state['values']['field_mycollection']['und'][$key]['field_my_userreference']['und'][0]['target_id']);
        $form_state['input']['field_mycollection']['und'][$key]['field_my_text']['und'][0]['value'] = $user_wrapper->field_my_text->value() ? $user_wrapper->field_my_text->value() : '';
        $form_state['input']['field_mycollection']['und'][$key]['field_my_anothertext']['und'][0]['value'] = $user_wrapper->field_my_text->value() ? $user_wrapper->field_my_yetanothertext->value() : '';
      }
    }
  }
}

function MYMODULE_mycollection_callback($form, &$form_state) {
  return $form['field_mycollection'];
}

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.