[Bootstrap3] モーダルからFormをSubmitする (Ajaxあり・なし)
Bootstrap のモーダルダイアログの中にフォームを作って、モーダル内に入力されたデータをサブミットする方法。
submit ボタンを使って普通にサブミットすることも、 Ajax を使って非同期でサブミットすることもできる。親画面からデータを引き継ぐこともできる。
基本的なモーダルの使い方は、[Bootstrap3] モーダル・ダイアログの使い方 を参照してください。
必要なライブラリ
Bootstrap3 を使うために必要な css , js ファイルを用意する。
以下サンプルは CDN を使ってロードしている。
<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>
普通のサブミットと変わったところは、更新完了時にメッセージを表示するために p
タグを追加、 form
タグから余計なものをとった(別にあっても構わない)、モーダル内の「変更」ボタンを type="button"
にして余計なものを取った。そのため、 js で onクリックとか使ってボタンのアクションをひろう。
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;
}
最後に exit;
を追加。
json
で返したいなら json エンコードが必要。
必要に応じて header()
関数を使って Content-Type
を指定する。
以上