グリッド直接編集時にレスポンスで判断する

今までのサンプルでは、編集時に問題がないことを想定していたが、実際のウェブアプリケーションでは何かしらエラーが発生するもので、その時の対応。

前準備

OK.txt ファイルと NG.txt ファイルを作成する

  • OK.txt の中身


OK

  • NG.txtの中身


NG

ソースの説明

  1. 編集する行を選択する
  2. 編集ボタンを押す
    1. 保存(OK)ボタンを押せば、その内容でグリッドデータも更新される。編集状態は解除される。
    2. 保存(NG)ボタンを押せば、エラーメッセージが表示される。グリッドの編集内容は破棄され、編集状態も解除される。
    3. 保存(NO_FILE)ボタンを押せば、エラー内容とともにメッセージが表示される。編集状態のまま


保存(NG)ボタンを押した時に編集状態が解除されるのは非常に納得いかない。さっきまで何を入力したか覚えてないし、長文のテキストを入力していたらかなりげんなりする。

なので、エラーの場合はHTTP 403 など、エラーステータスコードを返すといいかもしれない。
もしくは、jqGridのソース(grid.inlinedit.js)を修正して、編集状態が解除されないようにするしかない。


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>グリッド直接編集時のクエリパラメータ追加サンプル</title>
  
<link rel="stylesheet" type="text/css" media="screen" href="css/jquery-ui-1.7.2.custom.css" />
<link rel="stylesheet" type="text/css" media="screen" href="css/ui.jqgrid.css" />

<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="js/i18n/grid.locale-jp.js"></script>
<script type="text/javascript" src="js/jquery.jqGrid.min.js"></script>

<script type="text/javascript">
function begin_edit()
{
	// 保存ボタンを押せるようにし、編集ボタンを押せないようにする
	$("#btn1").attr("disabled",true);
	$("#btn2").attr("disabled",false);
	$("#btn3").attr("disabled",false);
	$("#btn4").attr("disabled",false);
}

function end_edit()
{
	// 保存ボタンを押せないようにし、編集ボタンを押せるようにする
	$("#btn1").attr("disabled",false);
	$("#btn2").attr("disabled",true);
	$("#btn3").attr("disabled",true);
	$("#btn4").attr("disabled",true);
}

jQuery(document).ready(function()
{
	jQuery("#list").jqGrid({
		datatype: "local",
		colNames:['従業員番号', '名前'],
		colModel:[
			{name:'employee_no', editable:true},
			{name:'name'       , editable:true},
		],
		caption: 'グリッドを直接編集時にパラメータを追加する'
	});

	var mydata = [
		{employee_no:"1",name:"test1"},
		{employee_no:"2",name:"test2"},
		{employee_no:"3",name:"test3"},
	];

	for(var i=0;i<=mydata.length;i++)
		jQuery("#list").addRowData(undefined,mydata[i]);

	// 編集中の行ID
	var editting_id = null;

	// 選択した行データを編集状態にする
	jQuery("#btn1").click( function()
	{
		var grid = jQuery("#list");
		editting_id = grid.getGridParam("selrow");
		if( !editting_id )
		{
			alert("選択されてません");
			return;
		}

		grid.editRow(editting_id); 
		begin_edit();
	});

	// 行編集を保存した際に、サーバ通信成功時に呼ばれる関数
	// true を返すと編集成功とみなす
	// res : XMLHttpRequest オブジェクト
	var response_complete_func = function(res)
	{
		if( res.responseText.indexOf("OK") == 0 )
		{
			return true;
		}
		else
		{
			alert("更新に失敗しました");
			return false;
		}
	}

	// 行編集を保存した際に、サーバ通信失敗時に呼ばれる関数
	// rowid : 失敗した行番号
	// res   : XMLHttpRequest オブジェクト
	// stat  : 通信エラー内容
	var response_error_func = function(rowid, res, stat)
	{
		var s = "行番号(" + rowid + ")でエラーが発生しました\n"
		      + "エラー内容:" + res.status + ", " + res.statusText + "\n"
		      + "status:" + stat;
		alert(s);
	}

	// 編集を保存する(成功)
	$("#btn2").click( function()
	{
		if( !editting_id ) return;

		jQuery("#list").saveRow(editting_id,
		                        response_complete_func,
		                        "OK.txt",
		                        null,
		                        null,
		                        response_error_func);
		editting_id = null;
		end_edit();
	});

	// 編集を保存する(サーバ側でエラー発生)
	$("#btn3").click( function()
	{
		if( !editting_id ) return;

		jQuery("#list").saveRow(editting_id,
		                        response_complete_func,
		                        "NG.txt",
		                        null,
		                        null,
		                        response_error_func);
		editting_id = null;
		end_edit();
	});

	// 編集を保存する(通信エラー)
	$("#btn4").click( function()
	{
		if( !editting_id ) return;

		jQuery("#list").saveRow(editting_id,
		                        response_complete_func,
		                        "NO_FILE.txt",
		                        null,
		                        null,
		                        response_error_func);
	});

	end_edit();
});
</script>
</head>
<body>

<table id="list" class="scroll" cellpadding="0" cellspacing="0"></table>

<p><button id="btn1">選択中の行を編集する</button></p>
<p><button id="btn2">保存(OK.txt)</button></p>
<p><button id="btn3">保存(NG.txt)</button></p>
<p><button id="btn4">保存(NO_FILE.txt)</button></p>

</body>
</html>