web-dev-qa-db-ja.com

カスタムフォームに「別のアイテムを追加」を実装する方法

基本的に2つのエンドポイント間の関係を作成するフォームであるモジュールを書いています。

ユーザーが複数の関係を一度に作成できるようにしたい。設定で無制限を選択したときのフィールドと同じように、「別のアイテムを追加する」というボタンを追加したいと思います。

カスタムフォームにもこれを行う方法はありますか?

9
Jayaram

これを行う1つの方法は、for関数内でフォームフィールド/フィールドセットを設定することです。たとえば、送信ボタンのコールバックを介して値をインクリメントする別の関数を作成し、インクリメント後にフォームを再構築します。

for($x=1; $x<=$variabletoincrement; $x++){
(insert form fields/field sets )
}

以下は、動的フィールドの作成方法に関する情報を示すform_example_tutorial_9のコードです。この情報は、私の説明よりもはるかに詳細です。

http://api.drupal.org/api/examples/form_example!form_example_tutorial.inc/function/form_example_tutorial_9_add_name/7

http://api.drupal.org/api/examples/form_example%21form_example_tutorial.inc/function/form_example_tutorial_9/7

12

簡単で実用的なコード例を作成するには:

function MYMODULE_MYFORM($form, &$form_state) {

  // #tree will ensure the HTML elements get named distinctively.
  // Not just name=[name] but name=[container][123][name].
  $form['#tree'] = TRUE;

  if (empty($form_state['number_names'])) {
    $form_state['number_names'] = 1;
  }

  for ($i = 1; $i <= $form_state['number_names']; $i++) {

    $form['container'][$i] = array(
      '#type' => 'container',
    );
    $form['container'][$i]['name'] = array(
      '#type' => 'textfield',
      '#attributes' =>array('placeholder' => t('Name')),
      '#size' => 20,
      '#required' => TRUE,
    );
  }

  $form['add_item'] = array(
    '#type' => 'submit',
    '#value' => t('Add another name'),
    '#submit' => array('MYMODULE_MYFORM_add_item'),
  );

  if ($form_state['number_names'] > 1) {

    $form['remove_item'] = array(
      '#type' => 'submit',
      '#value' => t('Remove latest name'),
      '#submit' => array('MYMODULE_MYFORM_remove_item'),
      // Since we are removing a name, don't validate until later.
      '#limit_validation_errors' => array(),
    );
  }

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

  return $form;
}

function MYMODULE_MYFORM_add_item($form, &$form_state) {

  // All we need is to increase the number used in our for loop above ...
  $form_state['number_names']++;
  // ... and rebuild our form.
  $form_state['rebuild'] = TRUE;
}

function MYMODULE_MYFORM_remove_item($form, &$form_state) {

  // Just the other way around until only one item is left ...
  if ($form_state['number_names'] > 1) {
    $form_state['number_names']--;
  }
  // ... and form rebuild again.
  $form_state['rebuild'] = TRUE;
}

Drupal 8

サンプルモジュールの AjaxAddMore.php (小さな[ソースの表示]リンクをクリックします)。

8
leymannx