どのボタンがクリックされたかを知るにはどうすればよいですか?


12

「送信」ボタンと「キャンセル」ボタンがあるフォームがあります。ではhook_submit()、どのボタンがクリックされたかをどのようにして知ることができますか?


あなたは話しているのですhook_submit()か、それともフォーム送信ハンドラですか?フォーム送信ハンドラはの実装ではありませんhook_submit()
キアムルノ

回答:


23

triggering_elementから使用する必要があります$form_state['triggering_element']

ベストプラクティスは#name、ボタンの属性を定義することです。そのため、でこの値を使用できますtriggering_element

例えば:

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

この属性triggering_elementを定義しない場合、ボタンの#value(ユーザーが読み取れるテキスト)が保持されますが、他のモジュールがこの値を変更したり、ローカライズによって変更されたりする可能性があるため、これは推奨されません。

使用することもできます$form_state['clicked_button']が、これは非推奨です

詳細については、drupal_build_form関数のドキュメントページをご覧ください。


7

$form_state['clicked_button']['#value'] フォームでクリックされたボタンがわかります。


$form_state['clicked_button']['#value']:)
user1359

1
フォームに必須フィールドがあり、入力されていない場合、Drupalはフォーム検証エラーをスローします(form_submitはform_validateの後に呼び出されます)。このような何かをする必要がありますdevengineering.com/best-practices/drupal/…
iStryker

それは良い点です!
user1359

5
「clicked_button」は引き続き機能しますが、D7では非推奨になり、代わりに「triggering_element」を使用することをお勧めします。「clicked_button」を使用するコードにのみ影響を与える#ajaxバグがあったことを思い出します。それが「triggering_element」を使用するもう1つの理由です。そして、結局のところ、これは$ form_stateの単なる別のキーです。
ボヤンジバノビッチ

1
このアプローチは機能しますが、非推奨であり、問​​題が発生しやすいです。これを行う正しいDrupal 7の方法については、チュニックの回答を参照してください。
アリスヒートン

3

$form_stateDrupal 6で行ってきたこれらの値を比較してください。Drupal7でも同じです

if($form_state['values']['ok'] == $form_state]['clicked_button']['#value']){
    //Process if OK is pressed
}else if($form_state['values']['cancel'] == $form_state]['clicked_button']['#value']) {
    //Process if Cancel is pressed
}

正しいDrupal 6を覚えていれば、$ form_state] ['X']はDrupal 7の$ form_state ['X']になりました
iStryker

なぜこれら2つの値を比較する必要があるのですか?
iStryker

フォームに複数の送信ボタンが含まれる場合。この比較は、単一の送信ハンドラーでフォームを送信するために使用されるボタンを区別するのに役立ちます。$ form_state ['clicked_button'] ['#value'] = t( 'Yes')は、多言語セットアップで異なる値になります。
Shoaib Nawaz

多言語セットアップですべての言語比較を避けるには、単一の比較が最適です。:)
Shoaib Nawaz

1
@iStryker最初のコメントの意味がわかりません。
kiamlaluno

3

次の#nameように、属性にボタンの名前を付けます。

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

次に使用します:

$values = $form_state['input'];
if (isset($values['delete'])) // 'delete' button was pressed.

したがって、次のような2つの送信ボタンを持つフォームの場合:$ form ['submit'] = array( '#type' => 'submit'、 '#name' => 'submit-1'、 '#value' => t ( 'Submit1')、); $ form ['submit2'] = array( '#type' => 'submit'、 '#name' => 'submit-2'、 '#value' => t( 'Submit2')、); submitForm()関数で$ form_state-> getTriggeringElement()['#name']を確認するだけですか?
ガイウス

3

2016年のDrupal 8のアップデート

まだトリガーされたイベントにアクセスする方法を見つけようとしている人のために、Drupal 8ソリューションがあります。

$form_state->getTriggeringElement()

これは、トリガーとなる送信要素の配列を返します。というマークアップを追加する#nameと、次の方法でアクセスできます。

$button_clicked = $form_state->getTriggeringElement()['#name']

この変更の理由はそれですFormStateInterface、今でreadOnly拡張するクラスだけがいるファイルFormStateInterfaceの変数にアクセスすることができます。そのgetTriggeringElement()ため、変数にアクセスするためのようなアクセサメソッドを使用する必要があります。


2018年にDrupal 8.4.4の更新があります:drupal.stackexchange.com/a/256112/1441
user1359

0

Drupal 8.4.4では$form_state->getTriggeringElement()['#name'];、の値を提供しますop。フォーム状態の値の配列でそのキーを探す#valueと、ボタンフォーム要素のキー、つまり、エンドユーザーがページのボタンに表示する文字列を取得します。

$form_state->getValues()['op']すべてのフォームに共通するかどうかはわかりませんが、モジュールのフォームにハードコーディングしています。


0

Drupal 8.6.7

以下のようなボタンを作成します。

$form['my_button'] = [
    '#type' => 'button',
    '#value' => t('Custom Button'),
    '#name' => t('customButton'),
    '#weight' => 0,
    '#attributes' => [
      'class' => ['populate-bib-button', 'btn', 'btn-primary'],
    ],
  ];

送信関数で、以下のコードのようなボタン名を取得します。

$input = $form_state->getUserInput();
print $input['_triggering_element_name']; // customButton

比較は次のように行うことができます

if ($input['_triggering_element_name'] == 'customButton') {
  // Do something.
}

#Drupal8

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.