プロが教える店舗&オフィスのセキュリティ対策術

複数行のチェックボックスの値をそのまま
書き込みたいのですが・・・

.datファイル↓

1234,1

5678,0 

3456,1

7890,0

上記をHTMLとして出力。

1→checkedで出力されるとします。

チェックを入れて、
7890,0

7890,1

にするとそれを1行として保存されるようにしたい
です。

チェックボックスは同じ名前のためform('check')
などで値を取り出したとしても最後の値しか
値を取り出せないでしょう。

画面に複数出た行を全部.datファイルに書き込むには
どうすればよいのでしょうか?

http://www.futomi.com/lecture/form/cgi-pm.html

↑を参照しましたが、チェックの値は@配列で
取れるような気がしましたが、1行を書き込む
方法がわからないので詳しく教えていただければ
幸いです。

言葉だけよりソースがあるとわかりやすいですm(__)m

A 回答 (4件)

複数行(複数個のことかな?)のチェックボックスを含むフォームデータを受け取って、それぞれの値とチェック状態を取得する方法、というご質問でしょうか?


その場合、オフのエレメントはフォーム送信されないということを判別すれば良いですが、ただ「それを1行として保存されるようにしたい」の意味が解らず…。

もっと具体的に、「こういうHTMLフォームを受け取って、こういうデータを取得したい」というようなサンプルがあれば、ご質問の意味が解りやすいと思うのですが、
質問者さんの言葉を借りれば、言葉だけよりソースがあるとわかりやすいです。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
またわかりづらく失礼しましたm(__)m

データ(HTMLとして出力されると)
ID  名前 時間 予約状況
1234 今井 2/26  □
1234 今井 3/20  ■
5678 前田 2/27  □
5678 前田 2/28  □
1234 今井 2/27  □


ソースで抜粋↓データをHTMLとして出力する部分

foreach (@txt) {
($tonum, $c_date, $c_status, $chkbox) = split(/,/, $_);
$name = &num_to_name($tonum);

    $html .= "<tr><td>$tonum</td><td>$name</td><td>$c_date</td><td>$c_status</td><td><input type=checkbox name=chkbox value=\"$chkbox\"></td></tr>";
}

<form action=\"$thisurl\" method=\"$method\">
<table>
<tr><td>ID</td><td width = 100>お名前</td><td width = 100>日付</td><td width = 40>時間</td><td width = 80>予\約状況</td></tr>
$html
<tr><td></td><td></td><td></td><td></td><td>
<INPUT TYPE=HIDDEN NAME=mycmd VALUE=yoyaku_check2>
<INPUT TYPE=HIDDEN NAME=mynum VALUE=$tonum>
<input type="submit" value="送信"></td></tr>
</table>
</form>


□、■はチェックON、OFFになっており、
この値を“行ごと”記述したいです。

送信ボタンが押された次のルーチンはyoyaku_check2です。

以上で想像つきますでしょうか?

お礼日時:2006/09/16 17:48

最初のご質問では「書き込みたい」とのことでしたが、そうではなく「HTMLを出力したい」ということでしょうか。

以下そのように仮定しています。

ようするにカンマ区切りのテキストファイルを読み込んで、HTML出力するということですね。
ただ $c_status が何にあたるのか、名前からして「予約状況」だと思ったのですがtableの並びを見ると「時間」なのですね(後で迷わないように $re_time など解りやすい名前にすることをおすすめします)。

で、まとめると、以下のようなテキストファイルがあり、
--------------------------
1234,2/26,13:30,0
1234,3/20,11:30,1
5678,2/27,20:00,0
5678,2/28,9:30,0
1234,2/27,10:00,0
--------------------------

これを読み込んで、以下のようなHTMLを出力したい、

--------------------------
ID  お名前 日付 時間 予約状況
1234  今井  2/26 13:30  □
1234  今井  3/20 11:30  ■
5678  前田  2/27 20:00  □
5678  前田  2/28 9:30   □
1234  今井  2/27 10:00  □
--------------------------

と理解してよろしいでしょうか。

その場合のサンプルコードです。

--------------------------
my $table_file = './table.dat'; # テキストファイルのパス
open(FILE, $table_file) or &error; # エラー処理
my @lines = <FILE>;
close(FILE);

foreach (@lines) {
  chomp;
  ($tonum, $c_date, $c_status, $chkbox) = split(/,/);
  $name = &num_to_name($tonum);
  my $enabled = $chkbox ? ' checked' : '';
  $html .= qq{<tr><td>$tonum</td><td>$name</td><td>$c_date</td><td>$c_status</td>}
   . qq{<td><input type=checkbox name=chkbox value="1"$enabled></td></tr>\n};

}

print <<"EOM";
Content-type: text/html

<html>
<body>
<form method="post" action="$ENV{'REQUEST_URI'}">
<table border="1">
<tr><td>ID</td><td>お名前</td><td>日付</td><td>時間</td><td>予約状況</td></tr>
$html
<tr><td colspan="5" align="right"><input type="submit" value="送信"></td></tr>
</table>
</form>
EOM

exit;
--------------------------

ただこれにはデータ設計自体に問題があります。
レコードにIDがないので、これでは後続処理でフォームデータを受け取ったときに判別がつきません。
ご存知かもしれませんが、フォームデータの各データは、どういう順番で送られるか保障されません。つまり3つある「1234 今井~」のうちどれなのか、わかるようにIDを付けておいて、それをチェックボックスのname(上記の「chkbox」になっている部分)にあてると良いと思います。

この回答への補足

再回答ありがとうございました。

>そうではなく「HTMLを出力したい」ということでしょうか。

いえ、「書き込み」の処理であっています。

ただ、読み込みの表示法で、

> qq{<td><input type=checkbox name=chkbox value="1"$enabled></td></tr>\n};

という部分は参考になりました。

あとは、チェックボックスのところを変えたものを1行づつテキストファイルに書き込みたいと思います。

テキストファイルには、

1234,今井,2/26,13:30,
1234,今井,3/20,11:30,1
5678,前田,2/27,20:00,
5678,前田,2/28,9:30,
1234,今井,2/27,10:00,





以上のレコードがHTMLとして出力されます。

ID  お名前 日付 時間 予約状況
1234  今井  2/26 13:30  □
1234  今井  3/20 11:30  ■
5678  前田  2/27 20:00  □
5678  前田  2/28 9:30   □
1234  今井  2/27 10:00  □

チェックボックスのところだけ変えます。

それでテキストファイルに書き込む処理に
困惑しています。

単なる読み書きならできるのですが、チェックボック
スはむずかしいですね。

補足日時:2006/09/16 21:26
    • good
    • 0

> チェックボックスはむずかしいですね。



いえいえ、そんなことはないですよ。他のフォームエレメントと取得方法はまったく変わりません。

一応確認ですが、フォームデータには「名前」や「日時」などは含まれていないということは、フォームデータを受け取ってテキストファイルを“更新”したい、ということですよね?

その場合、単にフォームデータを取得しておいて、テキストファイルを読み込み、マッチングさせて更新するだけの処理ですみます。

以下がサンプルコードです。
下にも書いたようにレコードにIDを追加し、それをname属性にしておきます。そのIDをキーにしたハッシュに格納しておくのが簡単でしょう。
なお、「名前」をどう扱っているのか解りませんので、適宜変更してください。
----------------------------
my $buffer;
if ($ENV{'REQUEST_METHOD'} eq 'POST') { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); }
 elsif ($ENV{'REQUEST_METHOD'} eq 'GET') { $buffer = $ENV{'QUERY_STRING'}; }
my @pairs = split(/&/, $buffer);
foreach (@pairs) {
  my ($name, $value) = split(/=/);
  if (!$name) { next; }
  $value =~ tr/+/ /;
  $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('H2', $1)/eg;
  $FORM{$name} = $value;
}

# ファイルロックなど...

# ファイル入力
my $table_file = './table.dat';
open(FILE, $table_file) or &error; # エラー処理...
my @lines = <FILE>;
close(FILE);

foreach (@lines) {
  chomp;
  my ($rec_id, $tonum, $c_date, $c_status, $chkbox) = split(/,/);
  $chkbox = $FORM{$rec_id} * 1;
  $_ = join(',', ($rec_id, $tonum, $c_date, $c_status, $chkbox)) . "\n";
}

# ファイル出力
open(FILE, ">$table_file") or &error; # エラー処理...
print FILE @lines;
close(FILE);

# ファイルアンロックなど...

exit;
----------------------------

「$FORM{$rec_id} * 1」とすることで、もしデータがない、つまりチェックボックスがオフの場合は、ゼロが格納されます。

この回答への補足

回答ありがとうございました。

検証済みました。気付いてくれればうれしいです。

ちゃんと値は拾えるようになりました。

$FORM{$rec_id} * 1で$rec_idを使うことに疑問でした。

データはこんな感じで保存されるであっているでしょうか?

4,1020,2006/9/13,A
3,1020,2006/9/13,D →チェックされていない
2,1020,2006/9/13,E,2→最後の2がチェックされた印
1,1020,2006/9/13,B,1

チェックされていないときは後ろに0をつけるのをやめました。

次に問題なのはまたチェックする画面に戻ってチェックを外して更新してもデータは変わらない点です。

チェックを外したら、↓のように保存したいです。

4,1020,2006/9/13,A
3,1020,2006/9/13,D →チェックされていない
2,1020,2006/9/13,E, →チェックを外して保存し直し
1,1020,2006/9/13,B,1

教えてくださったロジックではそこまでできないのでしょうか?できるような気がするのですが・・・。

補足日時:2006/09/21 02:51
    • good
    • 0
この回答へのお礼

お礼おそくなりすみません。いま検証中なのでしばらくお待ちください。

お礼日時:2006/09/20 00:55

> $FORM{$rec_id} * 1で$rec_idを使うことに疑問でした。



HTMLの
<input type="checkbox" name="XXX" value="1">
の「XXX」という値が $rec_id に入っているからです。
ようするに、これで「どのチェックボックスなのか」がわかるようになります。

> データはこんな感じで保存されるであっているでしょうか?
> 4,1020,2006/9/13,A
> 3,1020,2006/9/13,D →チェックされていない
> 2,1020,2006/9/13,E,2→最後の2がチェックされた印
> 1,1020,2006/9/13,B,1

「2,1020,2006/9/13,E,2」ではなくて「2,1020,2006/9/13,E,1」です。
(※ちなみにA,D,E,Bというのは「時間」ですか?)
なぜ2ではなくて1なのかというと、HTMLの
<input type="checkbox" name="XXX" value="YYY">
の「YYY」という値が $FORM{$rec_id} に入っているからです。
ソースでは
<input type="checkbox" name="XXX" value="1">
ですから、1が入ります。
また、レコードIDの2を入れる意味はありません。

> チェックされていないときは後ろに0をつけるのをやめました。

それなら
$chkbox = $FORM{$rec_id} * 1;
の「*1」を消すだけです。

> 次に問題なのはまたチェックする画面に戻ってチェックを外して更新してもデータは変わらない点です。

ソースを見ないと原因が解りません。できれば省略せずにソースを見せていただけると、より解りやすいです。



ちなみに、私が下に書いたコード、
-----------------
  my $enabled = $chkbox ? ' checked' : '';
  $html .= qq{<tr><td>$tonum</td><td>$name</td><td>$c_date</td><td>$c_status</td>}
   . qq{<td><input type=checkbox name=chkbox value="1"$enabled></td></tr>\n};
-----------------
の部分、このように書いていますか?
これは、ファイルから読み込んだ$chkboxが「1だったらチェックボックスをオンにする」という処理です。チェックボックスは「checked」を付けないとオンにならないので、$enabledに「checked」を入れる、または入れない、というように処理します。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

チェックボックスにIDをつけそれをチェックボックスのname="×××"に設定するところまでできたのですが、その後すべてのチェック項目がチェックされる事態に陥りました。また、質問を立てますので複数のチェックボックスを更新する作業で問題点がわかるようでしたら回答願いますm(__)m

お礼日時:2006/09/30 23:03

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!