在Drupal7中创建动态表单字段

时间:2020-03-05 15:25:30  来源:igfitidea点击:

Drupal的表单API帮助开发人员用最少的代码构建复杂的、可扩展的表单,还提供了使表单字段成为动态的选项。
它意味着根据另一个字段的给定值更改/创建表单字段。
在drupal中创建动态字段有一个很酷的技巧。
通常我们使用#states元素来更改其他字段的值,根据字段的给定值显示/隐藏。
我认为不可能给出动态值(例如,根据字段的给定值从数据库中给出值)。
但我们可以用ajax元素来实现。
让我们用一个例子来看看这个技巧。
我想使用复选框字段列出特定选定类的所有学生。
如果我们在选择框中更改任何类,那么当前类的学生应该显示在复选框中。

/**
 * Implementation of hook_form().
 */
function theitroad_dynamic_form($form, $form_state) {
  $class = array(0 => 'Select', 1 => 'Class 1', 2 => 'Class 2');
  $form['class_from'] = array(
    '#type' => 'select',
    '#title' => t('Class'),
    '#description' => t('Select any one of the class from the list.'),
    '#options' => $class,
    '#default_value' => $class[1],
    '#ajax' => array(
      'callback' => 'theitroad_migrate_student_list', //Callback will replace the students field with new values.
      'wrapper' => 'migrate-students-list',
      'method' => 'replace',
      'event' => 'change',
    ),
  );
  //Students checkboxes field container.
  $form['students'] = array(
    '#type' => 'container',
    '#tree' => TRUE,
    '#prefix' => '<div id="migrate-students-list">',
    '#suffix' => '</div>',
  );
  //Create default checkboxes field with default selected class's students options.
  $form['students']['list'] = array(
    '#type' => 'checkboxes',
    '#options' => _theitroad_get_student_list_options($class[1]),
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Migrate'),
  );
  return $form;
}

在上面的表单中,我们使用了带有change event的#ajax元素。
这意味着如果我们更改选择框的值,它将触发"theitroad_migrate_student_list"回调,回调将用新选择的类的students替换student字段选项值。
查看回调代码,

/**
* Custom callback to build form fields.
*/
function theitroad_migrate_student_list($form, &$form_state) {
  $values = $form_state['values'];
  //Overwrite the student list fields with new options value.
  $form['students']['list'] = array(
    '#type' => 'checkboxes',
    '#options' => _theitroad_get_student_list_options($values['class_from']), //Api will return the class students list as array.
  );
  $form['students']['list'] = form_process_checkboxes($form['students']['list']); //Process the checkboxes fields.
  return $form['students']; //return full students field container.
}
/**
* API to return class's students list.
*/
function _theitroad_get_student_list_options($class) {
  $students = db_query('SELECT etid FROM {og_membership} WHERE entity_type = :entity_type AND gid = :gid', array(':entity_type' => 'user', 'gid' => $class))->fetchAll();
  $students_list = array();
  foreach ($students as $student) {
    $user = user_load($student->etid);
    If (in_array('student', $user->roles)) {
      $students_list[$user->uid] = $user->name; //Make array to fit with checkboxes options.
    }
  }
  return $students_list;
}