Drupal删除/更新数据库中的错误行

时间:2012-02-13 22:41:52

标签: php mysql forms drupal drupal-7

我有一组可以使用表单编辑和删除的项目。现在,所有itms都显示在列表中作为fieldsets。使用此方法创建字段集:

 $venues = db_query('SELECT vid, name, address, postcode, city FROM venues v WHERE v.uid = :uid', array(':uid' => $user->uid));
 if($venues->rowCount() != 0) {
   foreach($venues as $venue) {
     $page['venue_editing_form'][] = drupal_get_form('venue_editor_form', $venue->vid, $venue->name, $venue->address, $venue->postcode, $venue->city); 
   }
 }

然后使用此函数创建表单:

function venue_editor_form($form, &$form_state, $vid, $vname, $vadd, $vpostc, $vcity) {
$form['#prefix'] = '<div class="vedit">';
$form['#suffix'] = '</div>';
$form['edit_fieldset_'.$vname] = array(
  '#type' => 'fieldset',
  '#title' => t($vname),
  '#collapsible' => TRUE,
  '#collapsed' => TRUE,
  '#attributes' => array('class' => array('venue-edit')),
);
$form['edit_fieldset_'.$vname]['venue_name'] = array(
  '#type' => 'textfield',
  '#title' => t('Venue name:'),
  '#description' => t('Enter the venue name.'),
  '#default_value' => $vname,
  '#attributes' => array('onfocus' => 'this.value=""')
);
$form['edit_fieldset_'.$vname]['address'] = array(
  '#type' => 'textfield',
  '#title' => t('Address:'),
  '#description' => t('The address of this venue.'),
  '#default_value' => $vadd,
  '#attributes' => array('onfocus' => 'this.value=""')
);
$form['edit_fieldset_'.$vname]['postcode'] = array(
  '#type' => 'textfield',
  '#title' => t('Postcode'),
  '#description' => t('Enter the postcode for this event, so planB can position it on the map'),
  '#default_value' => $vpostc,
  '#attributes' => array('onfocus' => 'this.value=""', 'onblur' => 'getLatLong(this)')
);
$form['edit_fieldset_'.$vname]['city'] = array(
  '#type' => 'textfield',
  '#title' => t('City'),
  '#description' => t('The city this venue is in.'),
  '#default_value' => $vcity,
  '#attributes' => array('onfocus' => 'this.value=""')
);
$form['edit_fieldset_'.$vname]['edit_submit'] = array(
  '#type' => 'submit',
  '#value' => t('Submit changes'),
  '#validate' => array('venue_creation_form_validate')
);
$form['edit_fieldset_'.$vname]['delete_venue'] = array(
  '#type' => 'submit',
  '#value' => t('Delete venue'),
  '#submit' => array('venue_form_delete')
);
$form['edit_fieldset_'.$vname]['venueid'] = array(
  '#type' => 'value',
  '#value' => $vid
);
return $form;

}

其中一个提交处理程序:

function venue_form_delete($form, &$form_state) {
  $deleted = db_delete('venues')
    ->condition('vid', $form['#venueid'], '=')
    ->execute();
    drupal_set_message('Venue deleted successfully.');
}

现在,问题在于无论我按哪个场所的删除按钮,Drupal总是会删除列表中的第一个。由于某种原因,$form['#venueid']始终设置为提交处理程序列表中的第一个位置,但是如果我在生成表单时打印一条消息,则每个表单都有不同的ID,因为它应该是

以前有没有人遇到这个问题?

2 个答案:

答案 0 :(得分:1)

几个星期前,我的一位同事遇到了这个问题。您遇到此问题的原因是您尝试在具有不同数据的一个页面上多次加载相同的表单。看起来这应该可以工作,但事实并非如此,因为所有表单都以相同的令牌/ ID结尾。当您提交每个表单时,系统不知道您真正点击了哪个表单,并且无法采取适当的操作。

有两种方法可以解决这个问题:

1)重做表单,使其全部由1个表单而不是多个

处理

2)使用hook_forms(...)创建“基本表单”,然后为每个映射到“基本表单”的场所生成唯一表单。这将确保每个表单都获得唯一的ID,而无需为每个表单编写表单。

我没有drupal 7示例,但这里是一个页面,显示如何使用hook_forms http://www.computerminds.co.uk/drupal-6-multiple-instances-same-form-one-page解决drupal 6的问题。您应该可以应用相同的技术

我没有测试过这段代码,但这是基本的想法:

修改您的get_form以使用唯一ID

foreach($venues as $venue) {
     $page['venue_editing_form'][] = drupal_get_form('venue_editor_form_'. $venue->vid, $venue->vid, $venue->name, $venue->address, $venue->postcode, $venue->city); 
   }

Impliment hook_forms

function MODULENAME_forms($form_id) {
  $forms = array();
  if (preg_match('/venue_editor_form_/', $form_id) {
    $forms[$form_id] = array(
      'callback' => 'venue_editor_form',
    );
  }
  return $forms;
}

然后我认为你必须修改你的表单的提交参数,以确保它们都被路由到同一个提交处理程序。虽然看起来你每个按钮都添加了不同的提交,所以你可能不需要做任何事情

$form['#submit'] => array('venue_editing_form_submit');

您可能还必须对验证功能执行相同操作。

应该这样做。

答案 1 :(得分:0)

我想问题是你尝试在不使用显式值字段的情况下通过表单处理传递sceneid值:

$form['#venueid'] = $vid;

这只是为'made up'表单属性(前导'#')赋值,通常不存在。请尝试使用明确的value field type代替:

$form['venueid'] = array(
    '#type' => 'value',
    '#value' => $node->vid
);

有了这个,vid应该在提交函数中可用,就像任何其他表单值一样,即$form_state['values']

function venue_form_delete($form, &$form_state) {
  $deleted = db_delete('venues')
    ->condition('vid', $form_state['values']['venueid'], '=')
    ->execute();
    drupal_set_message('Venue deleted successfully.');
}

注意删除'#'字符 - 前导'#'表示表单(和表单元素)属性,Drupal将在表单处理过程中尝试解释,'#revenueid'不是已定义的属性。