業務アプリ開発講座

モーダルウィンドウ・スタッフ編集

続いて、スタッフ編集のモーダルウィンドウです。

下記ファイルを作成します。

<div class="modal-dialog">
	<div class="modal-content">
		<form id="UpdateForm" class="form-horizontal">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal">×</button>
				<h4 class="modal-title">スタッフを編集します。</h4>
			</div>
			<div class="modal-body">
				<div class="row">
					<div class="col-md-1"> </div>
					<div class="col-md-10">
	
	<div class="form-group">
		<label class="col-md-5 control-label">ID</label>
		<div class="col-md-7">
			<label id="StaffId" class="control-label optional"></label>
		</div>
	</div>
	<div class="form-group">
		<label class="col-md-5 control-label">氏名</label>
		<div class="col-md-7">
			<input id="StaffName" name="StaffName" type="text" class="form-control required">
		</div>
	</div>
	<div class="form-group">
		<label class="col-md-5 control-label">メールアドレス</label>
		<div class="col-md-7">
			<input id="StaffMail" name="StaffMail" type="text" class="form-control email required">
		</div>
	</div>
	<div class="form-group">
		<label class="col-md-5 control-label">スタッフ区分</label>
		<div class="col-md-7">
			<select id="StaffType" name="StaffType" class="form-control required">
				<option value="0">社員</option>
				<option value="1">アルバイト</option>
			</select>
		</div>
	</div>
	<div class="form-group">
		<label class="col-md-5 control-label">管理区分</label>
		<div class="col-md-7">
			<select id="JobType" name="JobType" class="form-control required">
				<option value="0">管理者</option>
				<option value="1">管理補佐</option>
				<option value="2">レジ</option>
			</select>
		</div>
	</div>
	<div class="form-group">
		<label class="col-md-5 control-label">有効</label>
		<div class="col-md-7">
			<select id="ValidType" name="ValidType" class="form-control required">
				<option value="1">有効</option>
				<option value="0">無効</option>
			</select>
		</div>
	</div>
	<div class="form-group">
		<label class="col-md-5 control-label">採用日</label>
		<div class="col-md-7">
			<input id="HireDate" name="HireDate" type="date" class="form-control date required">
		</div>
	</div>
	<div class="form-group">
		<label class="col-md-5 control-label">退社日</label>
		<div class="col-md-7">
			<input id="LeaveDate" name="LeaveDate" type="date" class="form-control date optional">
		</div>
	</div>

					</div>
					<div class="col-md-1"> </div>
				</div>
			</div>
			<div class="modal-footer">
				<div class="row">

	<div class="col-xs-6 text-left">
		<a href="#" class="btn btn-warning btn-repass">パスワード再発行</a>
	</div>
	<div class="col-xs-6 btn-update-block">
		<div class='btn-group'>
			<a href="#" class="btn btn-default" data-dismiss="modal">閉じる</a>
			<a href="#" class="btn btn-primary btn-update">更新</a>
		</div>
	</div>

				</div>
			</div>
		</form>
	</div>
</div>

スタッフ一覧のスタッフ名をクリックすると上記ファイルを読み込んで、スタッフ編集モーダルウィンドウを開きます。

まず、staff-list.phpに以下のソースを追記します。場所は、前回作成した。追加モーダルウィンドウを当てはめるタグの下です。

<!-- Update Staff Modal Window -->
<div class="staff-modal-update modal fade"></div>
<!-- /Update Staff Modal Window -->

続けて、以下のソースをstaff-list.php$(function(){}) エリアに追記します。

//一覧のスタッフ名をクリック
$('.staff-name').on('click', function () {
	openUpdateModal(this);
	return false;
});
//編集モーダルウィンドウが閉じられた
$(".staff-modal-update").on('hidden.bs.modal', function(){
	$(this).children().remove();
});
$('.staff-name').on('click', function () {}

classstaff-nameはスタッフ一覧の各行の氏名linkに付加してあります。ですのでこの命令文は、氏名Linkをクリックしたら、openUpdateModal(this)を呼び出すイベントを登録しています。

ところで、ここにthisという引数があります。thisは自分自身を指すオブジェクトのことで、この場合、$('.staff-name')のことを指し、classstaff-nameはスタッフ名の<a>タグに書かれてれていいますので、詰まることろ、

this = <a href="#" class="staff-name">スタッフ名</a>

となります。

なぜここでthisを引数としているかというと、この<a>を起点に行に書かれているその他の情報であるメールアドレスやIDを取得するためなのです。

例えば、$(this).text()とすれば、スタッフ名が取得できます。

追加モーダルウィンドウと同じで、編集モーダルウィンドウを閉じた時の命令です。

続いて、下記関数も追記します。

//スタッフ編集モーダルウィンドウを開く
function openUpdateModal(obj){
	var modalWin;
	$.ajaxSetup({async:false});
	modalWin	= $(".staff-modal-update");
	modalWin.load("../assets/template/staff/modal-update.html");
	modalWin.modal('show');
	appendUpdateStaffInfo(obj);
	$('.btn-update').on('click', function(){
		updateStaff(this);
		return false;
	});
	$('.btn-repass').confirmation({
		trigger:'click',
		title:"ログインパスワードを再発行します。\nよろしいですか?",
		popout:true,
		onConfirm:function(){
			var block = $(this).parent();
			block.text("パスワードを再発行しました。");
			block.css("color", "#00D");
			$(this).css("display", "none");
		}
	});
	appendFormCaption();
}
//開いた編集モーダルウィンドウのフォームへ一覧上から取得した各値をセット
function appendUpdateStaffInfo(obj){
	var current	= $(obj);
	var modal	= $(".staff-modal-update");
	var form	= $("#UpdateForm");
	var row	= current.parent().parent();
	var idCell	= $("td:first-child", row);
	$("#StaffId",	form).text(current.attr('data'));
	$("#StaffName",	form).val($("td:nth-child(2)", row).text());
	$("#StaffMail",	form).val($("td:nth-child(3)", row).text());
	$("#StaffType",	form).val($("td:nth-child(4)", row).attr("data"));
	$("#JobType",	form).val($("td:nth-child(5)", row).attr("data"));
	$("#ValidType",	form).val($("td:nth-child(6)", row).attr("data"));
	$("#HireDate",	form).val(idCell.attr('hireDate'));
	$("#LeaveDate",	form).val(idCell.attr('LeaveDate'));
	$(".modal-title", modal).text($("td:nth-child(2)", row).text() + "さんを編集します。");
}
//更新ボタンをクリックした際の処理
function updateStaff(obj){
	if(!$("#UpdateForm").valid())	return false;

	var	modalTitle	= $(".staff-modal-update .modal-title");
	modalTitle.text(modalTitle.text().replace('す', 'した'));
	modalTitle.css("color", "#00D");
	$('.btn-update').attr("disabled", "disabled");
}

openUpdateModal(obj)

この中で、追加処理と違う、注目すべきところは、

$.ajaxSetup({async:false});
$('.btn-repass').confirmation({});

の2箇所ですね。

$.ajaxSetup({async:false});

modalWin.load()ajaxを使用して外部HTMLファイルを読み込んで、staff-modal-updateに当てはめています。ajaxというのは、非同期通信であるということを以前書きました。通常のプログラミングでは、一つの命令が完了してから次の命令へ移ります。これが同期です。非同期は、一つの命令が完了することを待たずに、次の命令へ処理が移ることを言います。
この関数では、外部HTMLを読み込み、それをstaff-modal-updateに当てはめ、生成されたモーダルウィンドウの各フォームに行の値をセットするのですが、非同期ですと、モーダルウィンドウのオブジェクトが生成される前に、次の命令へ移ってしまって、モーダルウィンドウの各フォームに値をセットしようとした時に。まだモーダルウィンドウオブジェクトが存在しないことが起きるわけです。それを避けるためにajaxasync:falseを設定しています。だたこのasync:falseは副作用がありまして、読み込み処理が完了するまで、画面が固まってその間一切の操作ができなくなります。と言っても軽い処理ならば、ほんの一瞬ですので人がその副作用に気づくほどの影響はありません。しかし、ajaxでの処理が重そうな場合は、避けるべきでしょう。

$(‘.btn-repass’).confirmation({});

「パスワード再発行」ボタンにconfirmation()イベントを登録します。「パスワード再発行」ボタンをクリックすると下記のように表示されます。

stock-1

trigger
イベントの種類を設定します。ここでは「click」です。
title
Confirmウィンドウのタイトルを設定します。初期値は「Are you sure?」となっています。特に指定しなければ「Are you sure?」と表示されます。
popout
このConfirmウィンドウ以外の領域をクリックした際に、Confirm画面を閉じるかを設定します。[false]を設定すると、[No]ボタンをクリックしないと閉じなくなります。
onComfirm
[Yes]ボタンをクリックした際の処理をここに書きます。ここでは、「パスワード再発行」ボタンを非表示にし代わりに送信完了メッセージを表示しています。

jquery.confirmationはその他にもボタン名を変えたり細かくカスタマイズすることができます。色々と試してみることをお勧めします。

再発行完了画面イメージです。

stock-1

appendUpdateStaffInfo(obj)

モーダルウィンドウが用意された次に実行される関数です。クリックされた行のその他のテキストを取得して、モーダルウィンドウ上の各フォームに値をセットします。幾つかのソースを説明します。

var current = $(obj);
引数のobjは一覧上の氏名列の<a>オブジェクトのことです。
var modal = $(“.staff-modal-update”);
編集モーダルウィンドウオブジェクトです。
var form = $(“#UpdateForm”);
編集モーダルウィンドウ内のformオブジェクトです。
var row = current.parent().parent();
氏名<a>オブジェクトの親の親、つまりtrオブジェクとのことです。ここから子要素のtdのテキスト等を取得し、対応するフォームに値をセットします。
var idCell = $(“td:first-child”, row);
var row = で取得したtrオブジェクの、最初の子要素のtdオブジェクを取得します。
$(“#StaffId”, form).text(current.attr(‘data’));
モーダルウィンドウのform内のid="StaffId"ラベルにcurrentオブジェクとの属性dataの値をセットします。
$(“#StaffName”, form).val($(“td:nth-child(2)”, row).text());
StaffIdと同じように、rowオブジェクとの2番目のtdオブジェクトのテキストをStaffNameテキストフォームにセットします。

以下、同じように行上のデータを対応するフォームにセットします。

updateStaff(obj)

ここでは、追加登録の時と同じように、入力チェック、モーダルウィンドウのタイトルの変更、「変更」ボタンを無効化を行っています。