Perlを中心とした技術系の話などをつらつら

2006年05月23日

JSON::Syckで改行を含むデータをダンプすると改行の後にスペースが2個入る

Ajaxる時のサーバとのデータ交換フォーマットとして、JSONを使う時、perlでサーバ側を実装する際にはJSONとかJSON::Syckというモジュールを使うとperlのデータ構造をJSONフォーマットに変換してくれるので便利です。

昨日これを使って、サーバからデータを取得し、textareaに取得したデータを入れるということをしたところ、改行を含んだテキストだと、改行の後にスペースが2個入ってしまうという現象に遭遇しました。

要はこうなってほしいところが、

こうなってしまうんです。

調べてみると、クライアントで受け取ったJSONデータをevalした段階ですでにスペースを含んでいたので、サーバ側でJSONデータを作成するところに問題がありそうだということがわかりました。

そこで以下のようなスクリプトを書いて、JSON,JSON::SyckがどんなJSONデータを吐き出すか見てみました。

#!/usr/bin/env perl
use strict;
use JSON::Syck;
use JSON;
my $data = {
    key => "foo\nbar\nbaz\n"
};
print "# Dumped by JSON::Syck $JSON::Syck::VERSION:\n";
print JSON::Syck::Dump($data), "\n";
print "# Dumped by JSON $JSON::VERSION:\n";
print objToJson($data), "\n";

結果は以下のとおり。

# Dumped by JSON::Syck 0.12:
{"key":"foo\n\
  bar\n\
  baz\n"}
# Dumped by JSON 1.05:
{"key":"foo\nbar\nbaz\n"}

どうやらJSON::Syckを使ってダンプしたデータは、整形のため、改行の後に、スペースが2個入っているようです。それでこれをJavaScriptでevalするとこのスペースもデータとして含まれてしまうため、上記のような現象が起きたみたいです。

そもそも改行後にスペースが入ってしまうのが問題なのか、スペースが入るのは問題なくて、クライアント側のJavaScriptでのパースに問題があるのかわかってませんが、試した限りだと、IEとFirefoxでスペースつきのデータの扱い方が異なるようで、挙動が変わってしまい、困りました。

とりあえず、サーバ側で改行コードを[BR]とかに変換しておいて、クライアント側でそれを改行コードとか、<br />に変換するという風にして対処しましたが、ちょっと付け焼刃的ですかねー。

Posted by horiuchi at 09:58 | Permalink | Comments (0) | TrackBack (1)

2006年05月21日

OOなJavaScriptの勉強がてら、ボタンの2度押し禁止機能を簡単に実現するライブラリを作ってみました

ちょっと時代に乗り遅れている気もしますが、最近prototype.jsをつかったOOなJavaScriptを書くのにはまっています。

今日はbindとbindAsEbentListenerの勉強がてら、これまたかなり昔話題になった「2度押し禁止ボタン」を実現するコードを書いてみました。

input.js

使い方はこんな感じです。

 // prototype.jsとinput.jsをロードします。
 <script type="text/javascript" src="/path/to/prototype.js"></script>
 <script type="text/javascript" src="/path/to/input.js"></script>
 <script type="text/javascript"><!--
 // windoのロード時に2度押し禁止機能を有効にします。
 Event.observe(window, 'load', function(){
     // ボタンのIDか要素のオブジェクトを渡せばクリックすると押せなくなります。
     new Input.DisableAfterClick('myButton');
 }, false);
  --></script>

ボタンのテキストを変えたい場合は2番目の引数に代替テキストを渡します。

画像の場合は代替画像のURLを渡します。

    new Input.DisableAfterClick('mySubmitButton2', '送信中です');
    new Input.DisableAfterClick('myImageButton2', '/path/to/image2.gif');

一定時間経過後にボタンを再度有効にしたい場合は、3番目の引数に有効にするまでの時間をミリ秒単位で渡します。

    new Input.DisableAfterClick('myButton', '1秒後にまた有効になります', 1000);

サンプルページにサンプルがあります。

また、input.jsの中身はこんな感じです。画像ボタンの扱いはもっといい方法があるのかなーとも思うんですが、おかしなところがあったら突っ込んでください。

var Input = new Object();
Input.DisableAfterClick = Class.create();
Input.DisableAfterClick.prototype = {
    initialize : function(input, alt, timer){
        this.input = $(input);
        this.alt   = alt;
        this.timer = timer;
        this.org   = this.input.type == 'image'
                   ? this.input.src
                   : this.input.value;
        this.stopEvent = this._stopEvent.bindAsEventListener(this);
        Event.observe(this.input, 'click', this.disable.bind(this));
    },
    disable : function() {
        this.input.blur();
        if (this.input.type == 'image'){
            if ( this.alt )
                this.input.src = this.alt;
            Event.observe(this.input, 'click', this.stopEvent);
        } else {
            if ( this.alt )
                this.input.value = this.alt;
            this.input.disabled = true;
        }
        if (this.timer)
            setTimeout(this.enable.bind(this), this.timer);
    },
    enable : function() {
        if (this.input.type == 'image'){
            if ( this.alt )
                this.input.src = this.org;
            Event.stopObserving(this.input, 'click', this.stopEvent);
        } else {
            if ( this.alt )
                this.input.value = this.org;
            this.input.disabled = '';
        }
    },
    _stopEvent : function (evt) {
        evt.stop();
        return false;
    }
};

Posted by horiuchi at 02:37 | Permalink | Comments (3) | TrackBack (1)

2006年05月18日

CentOS4.3なローカル開発環境がでけた

もう2週間も前になりますが、なかなか時間がなくて作れなかったローカルな開発環境をゴールデンウィークを利用して構築しました。Vmware Player上でCentOS4.3を動かしてます。

CentOSのデフォルトのロケールがja_JP.UTF-8なので、UTF-8な環境の構築も行いました。

さらに、今までbashを使ってたんですが、zshに変更しました。

それにしても環境構築まで長かった。。

最初、colinuxにCentOS4.3を入れようと思って「coLinux 用 インストーラ」を使って、はじめたんですが、OSのインストールに時間がかかるかかる。。最初はスムースに行くんですが、ちょっとすると、真っ青な画面になって、まったく動かなくなりました。固まっちゃったのかなと、何度かインストールをやり直してみましたが、やっぱり、青い画面でとまるので、そのまま放置して寝てみることに。

8時間くらい寝て、起きた後、画面を見てみると、ちょっとインストールが進んでいました。とまっているわけではないのだなと、さらに放置しておいたのですが、なかなか終わる気配がありません。。結局インストール完了するまでに、2日くらいかかりました。。ここまで我慢してがんばってきたんですが、起動してみるとネットワークカードを認識しない。。いろいろ試してみたんですが、うまくいかなかったので、Vmwareでも試してみるかとなりました。

Vmwareへのインストールはすんなりいって、今までの苦労はナンだったんだという感じですが現在が快適なのでよしとします。

Posted by horiuchi at 12:49 | Permalink | Comments (0) | TrackBack (1)