宿題15

表示サブルーチンのテンプレート化

add_record3.cgi

show_list.htmlというHTMLファイルを作成し、これをテンプレートとして、add_record.cgiのshow_listサブルーチンの表示結果に反映さえるように改造しよう。これによって、CGIスクリプトは変更せずに、表示結果のデザインを変えることができるようになる。

そのために、add_record.cgiを改造して、add_record3.cgiという名前のCGIスクリプト・ファイルとし、show_listサブルーチンを次のように書き換える。

[show_list.html]

<html><head>
<title>CGI sample</title>
<link href="homework.css" rel="stylesheet"  type="text/css">
</head>
<body>
<h2>リストの表示</h2>
<table border="1">
<!--TABLE_LIST-->
</table>
<a href="edit_record3.html">入力フォーム</a>

</body>
</html>


[add_record3.cgi]
#! /usr/bin/perl

#use strict;

my $top_page = "index.html";
my $filename = "list.txt";
my $show_list_tmpl = "show_list.html";

my %param;
my @data;

%param = get_param();

if( $param{NUMBER} ne "" || $param{NAME} ne "" ){
    @data =();	# @dataを初期化
    read_records();
    update_data($param{NUMBER}, $param{NAME}, $param{GENDER});
}

@data =();	# @dataを初期化
read_records();
show_list();
exit;


################### subroutines ##################
sub update_data
{
	my $Number =$_[0];
	$Number =~ s/\s+//g;	# 空白は削除
	$Number =~ s/\D+//g;	# 数字以外は削除
	my $Name = $_[1];
	my $Gender = $_[2];
	
	my $flag = 0;
	
	foreach (@data){
		if( $_->{number} eq $Number ){
			$flag = 1;
			$_->{name} = $Name;
			$_->{gender} = $Gender;
			if( $Name eq "" ){
				delete $_->{number};
				delete $_->{name};
				delete $_->{gender};
			}
		}
	}
	if($flag == 0 && $Number ne "" && $Name ne "" && $Gender ne ""){
		push  @data, { 'number'=>$Number, 'name'=>$Name, 'gender' =>$Gender };
	
	}

	# 書き込みモードでファイルを開く
	open(OUT, ">$filename") || &error("Cannot open $filename: $!");

	foreach (@data){
		if($_->{number} eq ""){ next;}	# データがNULLの場合は書き出さない。
		print OUT "$_->{number},$_->{name},$_->{gender}\n";
	}
	# ファイルを閉じる
	close(OUT);
}


sub read_records
{
	my( $number, $name, $gender);

	# 読み取りモードでファイルを開く
	open(IN, "<$filename") || &error("Cannot read $filename: $!");

	while(<IN>){
		chomp;
		( $number, $name, $gender) = split(/,/, $_);
		# 無名ハッシュを配列にする
		push  @data, 
		{ 
			'number'=>$number, 
			'name'=>$name, 
			'gender' =>$gender
		};
	}
	# ファイルを閉じる
	close(IN);

}


sub show_list
{
	my $table_list;
	
	foreach (@data){
		$table_list .=  "<tr><td>$_->{number}</td><td>$_->{name}</td><td>$_->{gender}</td></tr>\n";
	}

	# 読み取りモードでファイルを開く
	open(IN, "<$show_list_tmpl") || &error("Cannot read $show_list_tmpl: $!");

	print "Content-Type: text/html;charset=Shift_JIS;\n\n";
	
	while(<IN>){
		s/<!--TABLE_LIST-->/$table_list/;
		print $_;
	}
}


# 入力データの取得
sub get_param
{
	my($query, $key, $value, %param);

	if($ENV{REQUEST_METHOD} eq "GET"){
		$query = $ENV{QUERY_STRING};
	}else{
		read(STDIN, $query, $ENV{CONTENT_LENGTH});
	}


	foreach(split(/&/, $query)){
		($key, $value) = split(/=/, $_);
		$value =~ s/\+/ /g;
		$value =~ s/%([\da-f][\da-f])/pack("C", hex($1))/egi;
##		&jcode'convert($value, 'euc');
		$value =~ s/\r//g;
		$param{$key} = $value;
	}
	return %param;
}


# エラー表示
sub error
{
	print "Content-Type: text/html\n\n";
	print <<"---EOF---";
<html><head><title>Information</title></head>
<body>
<span sylte="color: red;"> $_[0]</span>
<form method="GET" action="$top_page">
<input type=SUBMIT value="最初のページに戻る">
</form>
</body></html>
---EOF---
	exit;
}

[edit_record3.html]

<html>
<head>
<title>レコードの編集</title>
</head>
<body>
<form  method="POST" action="add_record3.cgi" >
番号:<input type="text" name="NUMBER"><br>
名前:<input type="text" name="NAME">(空欄にすると、そのデータは削除されます)<br>
性別:
<label><input type="radio" name="GENDER" value="男">男性 </label>
<label><input type="radio" name="GENDER" value="女">女性</label>
<br>
<input type="submit" value="送信">
</form>
</body>
</html>

Javascriptで入力エラーチェック

check_record.html

edit_record.htmlを改造して、check_record.htmlという名前のHTMLファイルとして作成し、入力のチェックができるようにしよう。このチェックはJavascriptを使って、クライアント側で行うことにする。

サンプル

[check_record.html]
<html>
<head>
<title>レコードの編集</title>
<script type="text/javascript"> 
<!-- 

function check(){

	var error_msg = "";

	if(! document.form1.NUMBER.value.match(/^[0-9]{7}$/) ){ // 「番号」が7ケタの数字かチェック
		error_msg += "番号が正しくありません。";
	}else if(document.form1.NAME.value == ""){ // 「名前」の入力をチェック
		error_msg += "名前が未入力です。";
	}
	
	
	var flag = 0;
	for(i = 0; i < document.form1.GENDER.length; i++){
		if(document.form1.GENDER[i].checked){
			flag = 1;
		}
	}
	if( flag == 0 ){
		error_msg += "性別が選択されていません。";
	}

	if(error_msg != ""){
		alert(error_msg); // 入力漏れがあれば警告ダイアログを表示
		return false; // 送信を中止
	}else{
		return true; // 送信を実行
	}
}

// -->
</script>
</head>
<body>
<form  method="POST" action="add_record.cgi" name="form1" onSubmit="return check();">
番号:<input type="text" name="NUMBER"><br>
名前:<input type="text" name="NAME"><br>
性別:
<label><input type="radio" name="GENDER" value="男">男性 </label>
<label><input type="radio" name="GENDER" value="女">女性</label>
<br>
<input type="submit" value="送信">
</form>
</body>
</html>

戻る