web-dev-qa-db-ja.com

モーダルウィンドウにフォームを表示する

フォームがあり、Drupal 7.を使用しています。ユーザーがリンクをクリックしたときに、このフォームをポップアップに表示する必要があります。ユーザーは、ポップアップ内でフォームに入力できるはずです。 Colorbox やモーダルなど、何でも使用できます。Drupalに最適なオプションと、どのオプションがあるかを知りたかっただけです。

21
Hacker

私が現在知っている2つの優れたオプションがあります。iframe(カラーボックスなど)とCToolsです。使用するオプションは状況によって異なります。 CToolsのmodal.htmlファイルで見つけたこの情報が主な違いを引き出していると思います。

CToolsは、フォームを配置するためのポップアップとして使用できるシンプルなモーダルを提供します。通常のモーダルフレームワークとは異なり、iframeを介して機能しません。これは長所と短所の両方です。 iframeは、通常のページをサブブラウザーでレンダリングするだけで、その機能を実行できます。これにより、任意のページとフォームをモーダルに配置することがはるかに簡単になります。ただし、iframeは実際にメインページへの変更を伝達するのがあまり得意ではないため、モーダルを開いて何らかの作業を行ってからページを変更することはできません。

私はこのテーマについてCToolsの個人的な経験がないため、他に何も追加できませんが、いくつかのプロジェクトでiframeメソッドを実装しました。最近のバージョンでは、 Colorbox プラグインを使用して、 Webform モジュールで作成されたいくつかのフォームをポップアップに表示しました。興味がある場合に備えて、ここにサンプルコードを追加します。

フォームへのリンク:

<a class="colorbox_form" href="'.url('node/5').'">'.t('Send message').'</a>

リンクされたアドレスをポップアップで開くJavaScriptコード:

if ($('a.colorbox_form').length > 0) {
  var link = $("a.colorbox_form").attr('href');
  link = link.concat('?colorbox=true');
  // colorbox=true is attached for later use (read below).
  $("a.colorbox_form").attr('href', link);
  $("a.colorbox_form").colorbox({iframe:true, width:500, height:450});
}

テーマテンプレートファイル:

function mytheme_preprocess_page(&$variables) {
  // Different template and additional stylsheet for colorbox content.
  if (isset($_GET['colorbox']) && $_GET['colorbox'] == TRUE) {
    $variables['theme_hook_suggestions'] = array('page__iframe'); // page--iframe.tpl.php
    drupal_add_css(path_to_theme() .'/iframe.css');
    $variables['styles'] = drupal_get_css();
  }
}

JavaScriptを使用してリンクに 'colorbox = true'を添付し、JavaScriptがオフになっているユーザーに通常のテンプレートのフォームが表示されるようにしました。 iframeテンプレートには、メッセージ、タイトル、コンテンツのみが印刷されます。

これは既に機能していますが、Webフォームで問題が発生しました。フォームが送信されたときに 'colorbox = true'が保持されませんでした。それを修正する私の試み:

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  if (isset($_GET['colorbox']) && $_GET['colorbox'] == TRUE) {
    // The id-s of the forms that are possibly shown within a popup.
    $form_ids = array('webform_client_form_2', 'webform_client_form_4');
    if (in_array($form_id, $form_ids)) {
      $form['#submit'][] = 'mymodule_webform_submit';
    }
  }
}

function mymodule_webform_submit(&$form, &$form_state) {
  //drupal_set_message('<pre>'.var_export($form_state['redirect'], TRUE).'</pre>');
  if (!isset($form_state['redirect'])) {
    $form_state['redirect'] = array($_GET['q'], array('query' => array('colorbox' => 'true')));
  }
  else {
    $form_state['redirect'][1]['query'] = array('colorbox' => 'true');
  }
}
10
Madis

ユーザーがリンクをクリックしたときにモーダルにフォームを挿入できる CTools を使用します。

次のチュートリアルを確認してください: CToolsとDrupal 7 を使用してポップアップモーダルにフォームを挿入すると、このプロセスが数ステップで簡単になります。

基本的には、モーダルフォームに対してhook_menu()コールバックを定義する必要があります。

$items['mymodule/%ctools_js'] = array(
  'page callback' => 'mymodule_callback',
  'page arguments' => array(1),
  'access callback' => TRUE,
  'type' => MENU_CALLBACK,
);

次に、HTMLコードを返すリンクジェネレータを作成します。

/**
 * Helper function to make a link.
 */
function _mymodule_make_link($link_text = '') {
  // Set a default value if no text in supplied.
  if (empty($link_text)) {
    $link_text = 'Magical Modal';
  }

  return '<div id="magical-modal-link">' . l($link_text, 'mymodule/nojs', array('attributes' => array('class' => 'ctools-use-modal'))) . '</div>';
}

そのため、ページコールバックで使用できます。例:

/**
 * An example page.
 */
function mymodule_page() {
  // Load the modal library and add the modal javascript.
  ctools_include('modal');
  ctools_modal_add_js();
  return _mymodule_make_link('Magical modal');
}

ユーザーがリンクをクリックすると、/mymodule/ajaxまたは/mymodule/nojsnojsの場合)のいずれかにリクエストが送信されるため、次のコールバックがモーダルの作成を処理します。

/**
 * Ajax menu callback.
 */
function mymodule_callback($ajax) {
  if ($ajax) {
    ctools_include('ajax');
    ctools_include('modal');

    $form_state = array(
      'ajax' => TRUE,
      'title' => t('MyModule Modal Form'),
    );

    // Use ctools to generate ajax instructions for the browser to create
    // a form in a modal popup.
    $output = ctools_modal_form_wrapper('mymodule_form', $form_state);

    // If the form has been submitted, there may be additional instructions
    // such as dismissing the modal popup.
    if (!empty($form_state['ajax_commands'])) {
      $output = $form_state['ajax_commands'];
    }

    // Return the ajax instructions to the browser via ajax_render().
    print ajax_render($output);
    drupal_exit();
  }
  else {
    return drupal_get_form('mymodule_form');
  }
} 

次のように、フォームとその送信ハンドラを作成するだけです。

/**
 * Drupal form to be put in a modal.
 */
function mymodule_form($form, $form_state) {
  $form = array();

  $form['new_link_text'] = array(
    '#type' => 'textfield',
    '#title' => t('Link text'),
  );

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

  return $form;
}

/**
 * Drupal form submit handler.
 */
function mymodule_form_submit(&$form, &$form_state) {
  // Generate the new link using the submitted text value.
  $link = _mymodule_make_link($form_state['values']['new_link_text']);

  // Tell the browser to close the modal.
  $form_state['ajax_commands'][] = ctools_modal_command_dismiss();

  // Tell the browser to replace the old link with the new one.
  $form_state['ajax_commands'][] = ajax_command_replace('#magical-modal-link', $link);
}

これをテストするには、/mymodule/pageに移動します。ここで、「Magical Modal」リンクが表示され、クリックするとモーダルフォームが表示されます。

8
kenorb

Colorboxの代わりに Modal form を検討し始めます。特に、フォームでColorboxを使用すると非常にうまく機能しないために存在します。

モーダルフォームでは、 Ctools はすべての作業をバックグラウンドで実行します。これは、Colorboxに属さないフォーム処理を適切にサポートします。これは、サポートされていないフォームを「モーダル」する必要がある場合、Ctoolsのおかげで背後に切り替えることができる堅固なAPIがあることを常に知っていることも意味します。

新しいフォームのサポートを使用してパッチを作成する場合のボーナスポイント。 ;)

6
Letharion

Simple Dialog は、モーダルでフォームを提供するための優れた方法です。コアにあるjQuery UIを使用する利点があります。

必要なのは、フォームへのリンクをいくつかの追加情報とともに提供することだけです。クラスとrelタグに基づく簡単なメソッド、またはより微調整された制御のためのテーマメソッドを提供します。これは2つの方法で行いました。

  1. 必要なrelおよびclassタグを提供する Menu Attributes モジュール。
  2. theme_menu_link メニューリンクのレンダリング機能をオーバーライドします。
2
Queenvictoria

必要なモジュールは https://drupal.org/project/popup_forms ですが、適用するためにプログラミングを行う必要があります(つまり、管理インターフェイスを介して構成するだけではできません)。

2
Code Your Dream