bootstrap-モーダル-データの受け渡し

bootstrap-モーダル-データの受け渡しの参考例です。

サンプル(1)

モーダルを呼び出す

呼び出しボタンは button タグでも、a タグでも OK

data-targetで、呼び出すモーダルを指定している
モーダル側は、class="modal"div に、data-target と同じ id をつける

<!-- 呼び出しボタン aタグでもOK -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#sampleModal">
	モーダル・ダイアログ開く
</button>
<!-- モーダル・ダイアログ -->
<div class="modal fade" id="sampleModal" tabindex="-1">
	<div class="modal-dialog">
		<div class="modal-content">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
				<h4 class="modal-title">タイトル</h4>
			</div>
			<div class="modal-body">
				本文
			</div>
			<div class="modal-footer">
				<button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button>
				<button type="button" class="btn btn-primary">ボタン</button>
			</div>
		</div>
	</div>
</div>

data-targetで、呼び出すモーダルを指定している
モーダル側は、class=”modal”のdiv に、data-target と同じ id をつける

背景の設定

背景に関する設定は、 backdrop オプションで行う

data-backdrop背景背景クリック時
true半透明モーダル閉じる
falseそのままモーダル閉じない
static半透明モーダル閉じない

エスケープキー押下時の設定

エスケープキー押下時、モーダルを閉じるかの設定は keyboard オプションで行う

data-keyboard="true" : モーダル閉じる
data-keyboard="false" : モーダル閉じない

データの受け渡し

モーダル呼び出しボタンに、 data-** という属性を作ってモーダルにデータを渡すことができる
data-hoge1 data-hoge2 のように書けば複数のデータを渡すことも可能です。

See the Pen Bootstrap3 Modal データ渡す by AgoPeanuts (@AgoPeanuts) on CodePen.

このサンプルでは、モーダル呼び出しボタンに、data-watasu="ほげホゲ" という属性を作り、属性の値“ほげホゲ”をモーダルで受け取り、モーダル本文の中 ( span id="morau" ) に出力している。

<button type="button" class="btn btn-info modalBtn" data-toggle="modal" data-target="#sampleModal" data-watasu="ほげホゲ">モーダルにデータ渡す</button>
<p id="re"></p>
<!-- モーダル・ダイアログ -->
<div class="modal" id="sampleModal" tabindex="-1">
	<div class="modal-dialog modal-lg">
		<div class="modal-content">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
				<h4 class="modal-title">タイトル</h4>
			</div>
			<div class="modal-body">
				<label><span id="morau"></span>の好きな食べ物:<input type="text" id="food"></label>
			</div>
			<div class="modal-footer">
				<button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button>
				<button type="button" id="btn1" class="btn btn-primary">ボタン1</button>
			</div>
		</div>
	</div>
</div>

モーダル本文中の「の好きな食べ物:」に入力された値は、jQuery で取得し、親画面に出力している

$('#sampleModal').on('show.bs.modal', function (event) {
    //モーダルを開いたボタンを取得
    var button = $(event.relatedTarget);
    //data-watasuの値取得
    var watasuVal = button.data('watasu');
    //モーダルを取得
    var modal = $(this);
    //受け取った値をspanタグのとこに表示
    modal.find('.modal-body span#morau').text(watasuVal+'の');
});
// モーダルの中の「ボタン1」を押した時の処理
$("#btn1").on('click', function() {
  // モーダル閉じる
  $('#sampleModal').modal('hide');
  var foodVal = $('#food').val();
  $('#re').text(foodVal);
});

モーダル開く・閉じる

/* モーダルが開いていれば閉じ、閉じていれば開く */
$(セレクター).modal('toggle');
/* モーダル閉じる */
$(セレクター).modal('hide');
/* モーダル開く */
$(セレクター).modal('show');

モーダルのアクションイベント

こう書いてイベント拾う

$('#sampleModal').on('show.bs.modal', function (event) {
  .....
});

拾えるイベント

show.bs.modal : モーダルが開くとき (showメソッドを呼び出し時)
shown.bs.modal : モーダルが完全に表示されたとき
hide.bs.modal : モーダルが閉じるとき (hideメソッドを呼び出し時)
hidden.bs.modal : モーダルが完全に閉じたとき

例えば、何かを入力してからモーダルを閉じると、再度モーダルを開いたときに元のデータが入力されたままになるので、モーダルを閉じたら入力データをクリアする場合。
(「データの受け渡し」の項のサンプルも、モーダルに入力後、再度開くと元のデータが残っていることが確認できる。)

$('#sampleModal').on('hidden.bs.modal', function (event) {
    // モーダルが非表示になったら id="food" の値をクリアする
    $('#food').val('');
});

サンプル(2)「data-*」属性でデータを渡す

概要

Bootstrapのモーダル起動ボタン.png
矢印.png
JavaScript_·_Bootstrap.png

同じモーダルに、そのモーダル起動ボタンによって異なる情報を表示させることが出来ます。

方法

ボタン部分

<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@mdo">Open modal for @mdo</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@fat">Open modal for @fat</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" data-whatever="@getbootstrap">Open modal for @getbootstrap</button>
...more buttons...

<button>の data-togglemodaldata-targetは、起動させたいモーダルのIDを指定することは変わりません。

ここで、 モーダルに渡したい情報も data-* 属性で渡すことが出来ます 。

モーダル部分

先ほどの、<button>data-targetの#idと、モーダルの<div>idは、同じものにしてください。

もっと言うと、labelledbyの値がどうこう、と、いろいろ設定する値がありますが、それがこの記事の本題では無いので割愛します。

<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="exampleModalLabel">New message</h4>
      </div>
      <div class="modal-body">
        <form>
          <div class="form-group">
            <label for="recipient-name" class="control-label">Recipient:</label>
            <input type="text" class="form-control" id="recipient-name">
          </div>
          <div class="form-group">
            <label for="message-text" class="control-label">Message:</label>
            <textarea class="form-control" id="message-text"></textarea>
          </div>
        </form>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Send message</button>
      </div>
    </div>
  </div>
</div>

今回、モーダルのタイトルと、 recipient-name 部分に、ボタン側の data-whatever の値を表示させます。

スクリプト

$('#exampleModal').on('show.bs.modal', function (event) {
  var button = $(event.relatedTarget) //モーダルを呼び出すときに使われたボタンを取得
  var recipient = button.data('whatever') //data-whatever の値を取得

  //Ajaxの処理はここに

  var modal = $(this)  //モーダルを取得
  modal.find('.modal-title').text('New message to ' + recipient) //モーダルのタイトルに値を表示
  modal.find('.modal-body input#recipient-name').val(recipient) //inputタグにも表示
})

参考

サンプル(3)モーダルからFormをSubmitする (Ajaxあり・なし)

Bootstrap のモーダルダイアログの中にフォームを作って、モーダル内に入力されたデータをサブミットする方法。
submit ボタンを使って普通にサブミットすることも、 Ajax を使って非同期でサブミットすることもできる。親画面からデータを引き継ぐこともできる。

基本的なモーダルの使い方は、サンプル(1) を参照してください。

必要なライブラリ

Bootstrap3 を使うために必要な css , js ファイルを用意する。
以下サンプルは CDN を使ってロードしている。Bootstrap3 の CDN , jQuery の CDN ( Google 提供のもの)

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

本サンプルではカレンダー表示のために datepicker を使っているので、同様に使いたい場合は jQuery UI が必要です。

<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

普通にサブミット (Ajaxなし)

モーダル内に form タグと、 submit ボタンを置く。
親画面に別の form と submit ボタンが書いてあっても OK。ただし、この場合は、モーダルを開くためのボタンには、明示的に type="button" を書いて置かないとモーダルが開かない。

HTML

モーダル開くボタンが複数あっても、モーダル用のコードは 1 つで OKです。

<!-- モーダル開くボタン -->   
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#modalForm" data-cusno=1 data-visitday="2019-07-01">
    Open1
</button>
   
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#modalForm" data-cusno=2 data-visitday="2019-07-11">
    Open2
</button>
   
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#modalForm" data-cusno=3 data-visitday="2019-08-21">
    Open3
</button>
<!-- Modal の中身 -->
<div class="modal fade" id="modalForm" role="dialog">
  <div class="modal-dialog">
    <div class="modal-content">
      <!-- Modal ヘッダー -->
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">
          <span aria-hidden="true">×</span>
          <span class="sr-only">閉じる</span>
        </button>
      </div>
      <form role="form" id="form1" action="" method="POST">
        <!-- Modal ボディー -->
        <div class="modal-body">
          <div class="form-group">
            <label for="cusno">会員No</label>
            <input type="text" name="cusno" id="cusno" readonly>  
            <label for="oldday">来店日</label>
            <input type="text" name="oldday" id="oldday" readonly>
          </div>
          <div class="form-group">
            <label for="newday">新しい来店日</label>
            <input type="text" class="form-control" id="newday" name="newday" autocomplete="off"/>
          </div>
        </div>
        <!-- Modal フッター -->
        <div class="modal-footer">
          <button type="button" class="btn btn-default pull-left" data-dismiss="modal">閉じる</button>
          <button type="submit" class="btn btn-primary" id="chgDateSub" name="xxx" value="dateup">変更</button>
        </div>
      </form>
    </div>
  </div>
</div>

JavaScript (jQuery)

// カレンダー表示 (モーダルとは関係ないコード)
$('#newday').datepicker({
    dateFormat: 'yy-mm-dd',
});
// モーダルが開いた時の処理
$('#modalForm').on('show.bs.modal', function (event) {
    //モーダルを開いたボタンを取得
    var button = $(event.relatedTarget);
    //モーダル自身を取得
    var modal = $(this);
    //data-cusnoの値取得
    var cusnoVal = button.data('cusno');
    // input 欄に値セット
    modal.find('.modal-body input#cusno').val(cusnoVal);
    //data-visitdayの値取得
    var visitdayVal = button.data('visitday');
    modal.find('.modal-body input#oldday').val(visitdayVal);
});

PHP

// 「変更」ボタンが押されたとき
if (filter_input(INPUT_POST, "xxx") === "dateup") {
	$oldday = filter_input(INPUT_POST, "oldday");
	$newday = filter_input(INPUT_POST, "newday");
	$cusno = filter_input(INPUT_POST, "cusno");
	// DB 更新とか、何らかの処理
	...
	echo '会員No '.$cusno.' 様の来店日を '.$oldday.' から '.$newday.' に変更しました。';
}

Ajax でサブミット

HTML と PHP の処理はほぼ同じなのだが(ちょっとだけ変わっている)、コピペできるよう全コード書いておく。

HTML

<!-- 更新完了時に表示するメッセージ欄 -->
<p class='text-center bg-info' id="mess"></p>
<!-- モーダル開くボタン -->   
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#modalForm" data-cusno=1 data-visitday="2019-07-01">
    Open1
</button>  
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#modalForm" data-cusno=2 data-visitday="2019-07-11">
    Open2
</button>   
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#modalForm" data-cusno=3 data-visitday="2019-08-21">
    Open3
</button>
<!-- Modal の中身 -->
<div class="modal fade" id="modalForm" role="dialog">
  <div class="modal-dialog">
    <div class="modal-content">
      <!-- Modal ヘッダー -->
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">
          <span aria-hidden="true">×</span>
          <span class="sr-only">Close</span>
        </button>
      </div>
      <form role="form" id="form1">
        <!-- Modal ボディー -->
        <div class="modal-body">
          <div class="form-group">
            <label for="cusno">会員No</label>
            <input type="text" name="cusno" id="cusno" readonly>  
            <label for="oldday">来店日</label>
            <input type="text" name="oldday" id="oldday" readonly>
          </div>
          <div class="form-group">
            <label for="newday">新しい来店日</label>
            <input type="text" class="form-control" id="newday" name="newday" autocomplete="off"/>
          </div>
        </div>
        <!-- Modal フッター -->
        <div class="modal-footer">
          <button type="button" class="btn btn-default pull-left" data-dismiss="modal">Close
          </button>
          <button type="button" class="btn btn-primary" id="chgDateSub">変更
          </button>
        </div>
      </form>
    </div>
  </div>
</div>

JavaScript (jQuery)

Ajax の処理を追加した。

// カレンダー表示
$('#newday').datepicker({
	dateFormat: 'yy-mm-dd',
});
$('#modalForm').on('show.bs.modal', function(event) {
	//モーダルを開いたボタンを取得
	var button = $(event.relatedTarget);
	//モーダル自身を取得
	var modal = $(this);
	//data-cusnoの値取得
	var cusnoVal = button.data('cusno');
	// input 欄に値セット
	modal.find('.modal-body input#cusno').val(cusnoVal);
	//data-visitdayの値取得
	var visitdayVal = button.data('visitday');
	modal.find('.modal-body input#oldday').val(visitdayVal);
	// 非同期のため、newday にデータが残るのでクリアする
	modal.find('.modal-body input#newday').val('');
});
// 「変更」ボタンをクリックしたとき
$('#chgDateSub').on('click', function() {
	console.log('click');
	var cusno = $('#cusno').val();
	var oldday = $('#oldday').val();
	var newday = $('#newday').val();
	$.ajax({
		url: "", // 送信先 URL
		type: "POST", // GET,POSTとか
		dataType: "text",
		data: { // 送信するデータ
			xxx: 'dateup',
			oldday: oldday,
			newday: newday,
			cusno: cusno
		}
	}).done(function(data) {
		// 通信成功時の処理
		// PHP から返ってきた値(メッセージ)を p タグにセット
		$('#mess').text(data);
	}).fail(function(data) {
		// 通信失敗時の処理
		console.dir(data);
	}).always(function(data) {
		// 常に実行する処理
		$("#modalForm").modal('hide'); // モーダルを閉じる
	});
});

続けてモーダルを開くと「新しい来店日」に前のデータが残るので、モーダルを開くたびにクリアする。
Ajax 通信後モーダルを閉じる処理を追加した。
PHP からはテキストメッセージしか返さないので、 dataType: "text" としている。返ってきたメッセージを p タグにセットして画面に表示している。

PHP

// 「変更」ボタンが押されたとき
if (filter_input(INPUT_POST, "xxx") === "dateup") {
	$oldday = filter_input(INPUT_POST, "oldday");
	$newday = filter_input(INPUT_POST, "newday");
	$cusno = filter_input(INPUT_POST, "cusno");
	// DB 更新とか、何らかの処理
	...
	echo '会員No '.$cusno.' 様の来店日を '.$oldday.' から '.$newday.' に変更しました。';
	exit;
}