Drupal удаление / обновление неправильной строки в базе данных - PullRequest
1 голос
/ 14 февраля 2012

У меня есть набор элементов, которые я могу редактировать и удалять с помощью формы.Теперь все itms отображаются в списке как наборы полей.Наборы полей создаются с помощью этого метода:

 $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'] всегда устанавливается на первое место в списке в обработчике отправки, но если я распечатываю сообщение при создании форм, у каждой из форм свой идентификатор, как и должно быть.

Кто-нибудь имел эту проблему раньше?

Ответы [ 2 ]

1 голос
/ 17 февраля 2012

Один из моих сотрудников столкнулся с этим несколько недель назад. Причиной возникновения этой проблемы является то, что вы пытаетесь загрузить одну и ту же форму несколько раз на одной странице с разными данными. Кажется, что это должно работать, но это не так, потому что все формы имеют одинаковый токен / ID. Когда вы отправляете каждую форму, система не знает, на какую из них вы действительно нажали, и не может предпринять соответствующие действия.

Существует 2 подхода для решения этой проблемы:

1) Переработайте ваши формы так, чтобы они обрабатывались 1 формой вместо нескольких

2) используйте hook_forms (...) , чтобы создать «базовую форму», а затем сгенерировать уникальные формы для каждого объекта, которые сопоставляются с «базовой формой». Это позволит каждой форме получить уникальный идентификатор без необходимости писать формы для каждой.

У меня нет примера с drupal 7, но вот страница, которая показывает, как решить вашу проблему с drupal 6 с помощью hook_forms http://www.computerminds.co.uk/drupal-6-multiple-instances-same-form-one-page. Вы должны быть в состоянии применить ту же технику

Я не проверял этот код, но это основная идея:

Измените вашу get_form, чтобы использовать уникальный идентификатор

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');

Возможно, вам придется сделать то же самое с функциями проверки.

Это должно сделать это.

0 голосов
/ 14 февраля 2012

Полагаю, проблема в том, что вы пытаетесь передать значение venueid через обработку формы без использования явного поля значения:

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

Это просто присваивает значение «составленному» свойству формы (ведущее «#»), которое обычно не существует. Попробуйте вместо этого использовать явное значение поля типа :

$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 будет пытаться интерпретировать во время обработки формы, а '#venueid' не является определенным свойством.

...