2012-02-13 13 views
1

私はフォームで編集して削除できる項目があります。これで、すべてのitmsがフィールドセットとしてリストに表示されます。そして、フォームは、この機能を使用して作成されDrupalデータベース内の間違った行を削除/更新する

$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; 

}

そして提出ハンドラの1つ:

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

フィールドセットは、このメソッドを使用して作成されていますさて、問題は、どの会場の削除ボタンを押しても、Drupalは常に最初のものを削除することですリストのもののうちの1つ。 $form['#venueid']は何らかの理由で、送信ハンドラのリストの最初の会場に常に設定されていますが、フォームの生成時にメッセージを印刷すると、それぞれのフォームに異なるIDが割り当てられます。

誰もこの問題を以前に持っていましたか? (大手

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

これは単に「作ら」形式のプロパティに値を代入します。

+0

どこから来たのですか?あなたは元気? – SpaceBeers

+0

vidは、すべての会場の詳細を取得するデータベースクエリから来る会場IDです。次に、foreachループを使用してすべての結果を調べ、drupal_get_form( 'venue_editor_form'、$ venue-> vid ...) – KerrM

+0

質問を読み返して、複数のフィールドセットと複数のSubmit /削除ボタン(会場ごとに1つのフィールドセット)? –

答えて

1

私の同僚の1人は数週間前にこれに遭遇しました。この問題が発生する理由は、異なるデータを使用して同じフォームを1ページに複数回ロードしようとしているためです。これはうまくいくはずですが、すべてのフォームが同じトークン/ IDで終わるためではありません。各フォームを提出すると、システムが実際にクリックしたものがわからず、適切な処置をとることができません。

この問題を解決するための2つのアプローチがあります。

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の問題を解決する方法を示すページがあります。私はこのコードをテストしたhaventは、これは基本的な考え方であると同じ手法に

を適用することができるはずです。

一意のIDを使用するように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; 
} 

そして、フォームのsubmitパラメータを変更して、すべて同じ送信ハンドラにルーティングされるようにしなければならないと思います。あなたはボタンごとに異なる提出を追加しているように見えんが、あなたはそこに何もあなたはまた、検証機能と同じことをする必要がある場合があります

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

を行う必要がない場合がありますので。

それはそれを行う必要があります。

+0

ありがとう、それは問題を修正しました。 Drupalは同じフォームIDを持つ投稿と、間違った場所を削除した理由を区別できません。再度、感謝します。 – KerrM

0

私はこの問題は、あなたが明示的な値フィールドを使用せずに、フォームの処理によりvenueid値を渡すしようということだと思います'#')、通常は存在しません。代わりに、明示的な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が解釈しようとするフォーム(およびフォーム要素)のプロパティを示し、 '#venueid'は定義済みのプロパティではありません。

+1

カスタムFAPIプロパティを使用することは、非常に標準的な方法です(例えば、Dateの '#date_format 'キーなど、寄せられたモジュールが何十種類もあります)。配列の '#' 'dプロパティを使う唯一の問題は、既存の名前付きプロパティとの衝突の可能性です。これは、プロパティの名前の前にそれを実装するモジュールの名前を付けることで避けることができます。 '#mymodule_venueid'。それ以外の点では、この方法は100%有効であり、記述された問題の原因にはなりません。 – Clive

+2

@Clive:そうです、多くのコントリビュータモジュールがこれをやりますが、私はそれを「標準的な練習」と呼んでいません。このようなFAPIプロパティを使用すると、公式で文書化され推奨されている代替( '#value'型要素の形式)ではなく、文書化されていない機能(いつでも変更可能)に依存することを意味します。だから、私の提案は、最初に「正常な」方法を試すことを目指し、文書化されていない「機能」の問題を探し求めました。 –

+1

@Clive:誤解を避けるために、「文書化されていない」とは、カスタムFAPIプロパティの概念自体を意味するものではありません。カスタムモジュールからFAPI機能を拡張したい場合、例えば、新しい要素型を提供することで、必要に応じて(dateモジュールが '#date_format'で行うように)カスタムプロパティを使うことができます。しかし、このプロパティの使用法は、フォームの機能を提出するための値を渡すのではなく、フォームのライフタイム中のフォーム要素の処理/処理を目的としています。 –

関連する問題