Ajaxなチャットを作ってみた

サンプルはここ→http://www.gan2.65rpm.com/lab/ajax-chat.html
デザインは全然何もいじってない。
とりあえず、これから色々作っていくものの雛形って感じ。
ファイルは、HTMLとJavaScriptCGIスクリプト(Ruby)の3つに分けてある。
JavaScriptのライブラリはprototype.jsを使用。
以下はソース。

ajax-chat.html
<html>
  <head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <title>Ajaxなチャット</title>
    <script type="text/javascript" src="lib/prototype.js"></script>
    <script type="text/javascript" src="ajax-chat.js"></script>
  </head>
  <body>
    <h1>Ajaxなチャット</h1>
    <form method="get" id="form" onsubmit="saveData(); return false;">
      <input type="text" id="name" value="名前" size="16" />
      <input type="text" id="text" value="ここに書き込んで!" size="64" />
      <input type="submit" value="保存"><br />
    </form>
    <div id="result"></div>
  </body>
</html>

prototype.jsには、
入力フォームの値を参照する便利なショートカット$F()があるのだけど、
これは、$F('id')のように id を指定してやらなくちゃいけない。
最初、inputタグには id を書いてなくて、変わりに name を書いていた。
それで何でこれで動かないんだろうとしばらく悩んだ。
単純なミスだけど、prototype.jsを使うときは、
name じゃなくて id を使うように、普段から心がけておいた方がよさそうだ。

ajax-chat.js
function saveData(){
    var name = $F('name');
    var text = $F('text');
    text = text.replace(/&/g, "&");

    var url = 'ajax-chat.cgi';
    var pars = 'name=' + name + '&text=' + text;

    var myAjax = new Ajax.Request(
				  url,
				  {
				      method: 'get',
				      parameters: pars,
				      onComplete: showResult
				  });
}

function showResult(originalRequest){
    $('result').innerHTML = originalRequest.responseText;
    $('text').value = '';
}

Ajax.Requestをnewしているところのインデントがちょっと気に入らない。
javascript.elを使っているんだけど、これはちょっと凹み過ぎな気がします!
最後の方にある $('text').value = ''; で、
フォームのテキストフィールドが空にすることができる。

ajax-chat.cgi
#!/usr/local/bin/ruby
require 'cgi'
require 'kconv'
print "Content-Type: text/html\n\n"

class BBS
  def initialize(log_filename = 'ajax-chat.log')
    @cgi = CGI.new
    @log_filename = log_filename
    @MAX_LOG = 20
    @log = []
  end
  
  # ログファイルの読み込み
  def read_log_file
    open(@log_filename){|f|
      f.each{|l|
        @log << l.toutf8
        break if @log.size == @MAX_LOG
      }
    }
  end

  # ログファイルへの書き込み
  def write_log_file
    name = @cgi['name'].toutf8
    text = @cgi['text'].toutf8
    return unless name.size > 0 or text.size > 0
    time = Time.now.strftime("%Y/%m/%d-%X")
    
    @log.unshift "#{time}  [#{name}] #{lf2br(text)}<br />"
    
    open(@log_filename, 'w'){|f|
      c = 0
      @log.each{|l|
        l.chomp!
        f.puts lf2br(l)
        c += 1
        break if c == @MAX_LOG
      }
    }
  end

  def lf2br(str)
    str.gsub!(/\r\n/, '<br />')
    str.gsub!(/\r/, '<br />')
    str.gsub!(/\n/, '<br />')

    str
  end

  def output_result
    @log.each{|l|
      puts l
    }
  end
end


log_filename = 'ajax-chat.log'
bbs = BBS.new(log_filename)

bbs.read_log_file
bbs.write_log_file
bbs.output_result

Ajaxなチャットと言っておきながら、RubyのクラスはBBSだったりする。
でもログを読んだり書いたりする部分は、
チャットでも掲示板でも同じだと思うので、名前については特に気にしない。


この3つのファイル以外に、
空っぽの ajax-chat.log ファイルと、
lib フォルダ以下に prototype.js を用意し、
CGIの実行権限を755にしてやれば、Rubyの動くサーバならどこでも動くと思う。
あ、あとshebang(#!から始まる一行目)も変更が必要かもしれない。