drupal 7 textfield重建表单后忽略#default_value

时间:2013-10-09 13:53:49

标签: php ajax drupal-7

注意:我是一个drupal新手。我正在开发一个基于ajax示例的模块:add_more和autocomplete。我的想法是有一个表单,我可以在访问中添加访问者,使用ajax在LDAP连接填充的texfield中输入的人员。这很好。

问题在于我希望能够删除我想要的任何访问者(而不仅仅是最后一个访问者)。

我有一个添加访问者按钮,可以为此访问者添加一个包含访问者姓名文本字段的字段集和一个抑制按钮(抱歉,没有图像,我的声誉太低)。这意味着3个访问者,3个带有“抑制”按钮的字段集

当用户点击访问者的抑制按钮时,我将其删除,并要求重建表单,但随后,Drupal会一直显示名字,就像我压缩了最后一个名字一样。

function gaz_edit_visit_form($form, &$form_state) {
    [...]
  // Build the fieldset with the proper number of names. We'll use
  // $form_state['num_names'] to determine the number of textfields to build.
  if (empty($form_state['num_names'])) {
    $form_state['num_names'] = 1;

    $form['visitors_fieldset']['name'][0] = array(
      '#type' => 'fieldset',
      '#title' => 'Visiteur 1'
    );

    $form['visitors_fieldset']['name'][0]['visitor'] = array(
      '#type' => 'textfield',
      '#title' => t('Nom du visiteur'),
      '#autocomplete_path' => 'gaz/visit/edit_visit_autocomplete_callback',
    );

    $form['visitors_fieldset']['add_name'] = array(
      '#type' => 'submit',
      '#value' => t('Ajouter un visiteur'),
      '#submit' => array('ajax_example_add_more_add_one2'),
      '#ajax' => array(
        'callback' => 'ajax_example_add_more_callback2',
        'wrapper' => 'visitors-fieldset-wrapper',
      ),
    );
  }
  else {
    for ($i = 0; $i < $form_state['num_names']; $i++) {
      $form['visitors_fieldset']['name'][$i] = array(
        '#type' => 'fieldset',
        '#title' => 'Visiteur ' . ($i + 1),
      );

      $form['visitors_fieldset']['name'][$i]['visitor'] = array(
        '#type' => 'textfield',
        '#title' => t('Nom du visiteur'),
        '#autocomplete_path' => 'gaz/visit/edit_visit_autocomplete_callback',
        '#default_value' => $form_state['values']['visitors_fieldset']['name'][$i]['visitor'],
      );

      if ($form_state['num_names'] > 1) {
        $form['visitors_fieldset']['name'][$i]['remove_visitor' . $i] = array(
          '#type' => 'submit',
          '#value' => t('Supprimer'),
          '#submit' => array('gaz_visitors_remove'),
          '#ajax' => array(
            'callback' => 'ajax_example_add_more_callback2',
            'wrapper' => 'visitors-fieldset-wrapper',
          ),
          '#gaz_visitor_index' => $i,
        );
      }

      $form['visitors_fieldset']['add_name'] = array(
        '#type' => 'submit',
        '#value' => t('Ajouter un visiteur'),
        '#submit' => array('ajax_example_add_more_add_one2'),
        '#ajax' => array(
          'callback' => 'ajax_example_add_more_callback2',
          'wrapper' => 'visitors-fieldset-wrapper',
        ),
      );
    }
  }

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Confirm'),
  );

  return $form;
}

以下是删除列表中特定用户的功能。

function gaz_visitors_remove($form, &$form_state) {
  array_splice($form_state['values']['visitors_fieldset']['name'], $form_state['triggering_element']['#gaz_visitor_index'], 1);
  if ($form_state['num_names'] > 1) {
    $form_state['num_names']--;
  }
  $form_state['rebuild'] = TRUE;
}

重建过程结束时的$ form(即gaz_edit_visit_form函数的结尾)似乎没问题,包括textfields的default_values,但是drupal用其他值填充它们。如果我有3个访问者,然后删​​除访问者2,我希望看到1和3的名称,但我看到1和2的名称。再次,$ form ...看起来很好,并且没有用户2的痕迹了。

我想我错过了眼前的巨大大象,但我看不到它!

2 个答案:

答案 0 :(得分:0)

尝试并仔细阅读本教程https://drupal.org/node/717722。您创建表单的方式是错误的,这就是为什么不删除您想要的内容。

答案 1 :(得分:0)

当Drupal进行AJAX重建时,其执行顺序为:

  • 在您提交的状态下构建表单
  • 验证表格内容
  • 执行东西(调用你的#submit处理程序 - 我认为)
  • 重建要显示的表单
  • 返回输出(调用你的ajax #callback)

$ form_state ['values']是在第一步中构建的。如果你想在第4步中使用它,就像你那样......那很好,但是你需要牢记这一点。

它解释了为什么您删除的访问者数据仍在那里。您在$ form_state ['values']

中有(num + 1)个访问者

如何解决这个问题?这取决于您希望如何更改代码,这取决于您。一种方法是有两个计数器,其中第二个与$ i相同,但在一个点上它可以增加1个额外的,以跳过删除的值: (未经测试的代码)

$i2 = -1;
for (...) {
  $i2++;
  if (!empty($form_state['#triggering_element']) && $form_state['#triggering_element']['#value'] == t('Supprimer') && $form_state['#triggering_element']['#gaz_visitor_index'] == $i) {
    // OK, we pressed this button to delete a visitor, this one has been deleted so skip it.
    $i2++
  }
  ...
    '#default_value' => $form_state['values']['visitors_fieldset']['name'][$i2]['visitor']
  ...