form(フォーム)の状態を保存しておいて、次回ロード時に復元する。ブログの編集中にブラウザが落ちてもこれで大丈夫、てな用途に便利と注目を集めたこともあった模様。
そんなjQueryのプラグインがjQuery autosave plug-inだ。jquery.autosave.js。
プログラムでこれを使いたくていろいろ試行錯誤。(追記:以下は試行錯誤中のメモ。たぶんいっぱい間違っています。)
ロード時に前回の内容を復元できないかと思ったのだ。参考にしたのはこのエントリー。
「フォームの内容を自動保存するjQueryプラグイン – [Mi]みたいなもの」
これによると、「最低でも「復元する」ボタンが必要です(ページを開いたときに自動的にcookieから読み出してフォームに読込むようにはなっていません)。」と、あるので、目的の動作はできないのかな? と思ったのだけど、ソースを読むと、
$(‘form *’).autosave.restore();
みたいな感じで、「$(‘form *’).autosave();」の次あたりに書いておくとOKの模様。ボタンのクリックでOKなら、その関数(?)がどっかにあるはず、と思ったらビンゴ!
しかし、これだけではうまくいかない。Firefoxでは思ったとおりの挙動になるのだけど、IEではエラーが出てだめ。
さらに見ていくと、Firefoxでもロード時にエラーが出てる。エラーが出てもその後の処理が行われるため、思ったとおりの動作になっている、というわけだった。
ということで、エラーメッセージを元にソースをさらに見ていく。191行目だ。
var cookiecheck = $.cookie(‘autosave_’+u+’_check’).split(‘,’);
ここで「$.cookie(‘autosave_’+u+’_check’)」のオブジェクトが存在しないかnullと言われるのだ。そこで、これがあるかどうかをチェックすればいいと思いこんなふうに。
if(typeof(!$.cookie(‘autosave_’+u+’_check’))){
cookiecheck = null
} else {
var cookiecheck = $.cookie(‘autosave_’+u+’_check’).split(‘,’);
}
これでOK! ナイス、オレ。
もう1つ問題。上記とは別になるのだけど、このformの状態を、別のパスでも共通で保存・復元したいと思ったのだった。作成しているのは、どのページに行っても同じformで設定できるオプションがあるというサービス。ページが変わっても同じ状態のほうがベスト。ということで、$.cookie()にパスのオプションを一個一個書いていく。第3引数に「path:’/’」を加えるだけだ。参照してるだけのところは不要、ということで見ていけば数もさほどなく、別に面倒なことはなかった。
と、ここまでやったのだけど、プラグインに手をいれちゃうのはどうだろう? 保守性とかの面で。とか思い、さらに別の方法を模索。以下はプラグインへの修正をしない方向で再度検討した結果。
最初にクッキーがない状態でクッキーを参照しているのが問題なんだろうというわけで、はじめてロードした際にクッキーの存在を確認して、それがない場合は現在の状態をセーブしてしまえばいいんじゃね? と、思い、追加したのがこれ。
if($.cookie(‘autosave__radio’) == null){$(‘form#formOptions input’).autosave.go();}
対象となるformが複数ある場合は違ってくるかもだけど、1つだけならこれでOKっぽい。
次。複数のページで設定を共有したい、というか、ページが移ってもformの要素の状態を再現したい。そこでautosaveプラグインのオプションを調べるとuniqueというのを発見。これか?
$(‘form#formOptions input’).autosave({‘unique’: ‘n’});
こんな感じか。ページが移っても前の状態を保持する、というよりも、各ページごとに状態を保存・復元する感じ。とはいえ、ページAからはじめてページBに移るとページAと同じ状態になる、ページBで設定を変更してページAに移ってもAはそのまま、またページBに戻るとページBは先ほど設定したまんま、という挙動になる。ちょっと違うけど、そんなに変えたりしないからいいんじゃね? と妥協。クッキー増えまくるけど。(追記:この部分違ってた。あとで検証する)
で、これとは別にまだエラーが出る。今回作っているのは、formにradio(ラジオボタン)しか存在しない。それなのにcheckboxの状態を取得しようとしていうのが問題の模様。そういえば、もう一個設定値を保存しておきたいのがあったんだよなあ。それはチェックボックスでやっておくのがいいわけだよなあ。と、いうことでチェックボックスを1個追加。
これでOK! ナイス!
ここまではなんとかうまくいった。ページ移っても大丈夫。
しかし、これ、ブラウザ閉じると設定が消えちゃうみたいなんだけど。
autosaveプラグインには、cookieExpiryLengthっていうオプションもある。これでクッキーの保存時間を設定できる模様。しかし、これがうまく動作してくれない。うーん。参った。一番カンタンそうな問題が解決できない。どっか単純なミスをしてそうなんだけどなあ。
ということで現状のメモでした。たぶんいろいろ間違っているので、まだ続きます。ちなみに今回の機能を実現するのにググってて最初に見つけたのは「ブラウザが落ちてもフォーム内容が消えないようにするjQueryプラグイン「jQuery autosave」:phpspot開発日誌」。こちらは情報があまりなく(この人、実際に動かしてはいないですよね、きっと。サンプルサイト見て書いてると思う)途方にくれていたのですが、次に見つけたエントリー(上記)がとても参考になりました。ありがとうございました。
あと、開発環境構築に関してはXAMPPを使ってるのですが、今回の作業と前後してXAMPPでVirtualServerを設定する方法を最近発見。複数サイトを並行して作業するのが格段に便利になりました。なんでいままでちゃんと調べておかなかったんだろうと激しく後悔。「パーフェクトPHP」という書籍で知りましたよ。詳しくはあとで書くかも。
(追記)
どうもオプションがうまく渡ってない。cookieExpiryLengthどころか、intervalも。なんか根本的に間違っている気がしてきた。
ということで、上記のuniqueとかもぜんぜん違います。続く。
いま、気づいたんだけど、これ、バージョンの問題か。jQuery 1.4は対応してないからか。がっくし。やっぱり自分でごりごり書くか。
(追記)
書いた。というか、autosaveプラグインを結局修正する方向で。
関数呼び出し時にオプションを指定できないので、optionsとある部分に直接書く。cookieプラグインによる書き込み部分のすべてにexpiresの指定を入れる(元のソースにはなぜかこれがない)。ついでにオプションにパスの指定を追加(こちらもoptionsに記述)。それが反映されるよう、cookieプラグインの書き込み部分に同様に追加。
関数呼び出し時のオプション指定がうまくいかないのはextendがうまくいってないからの模様。バージョンアップで変更があったからではないかと思っているのだけど。
これにより、呼び出し側は
$(‘form#formOptions input’).autosave();
if($.cookie(‘autosave__radio’) == null){$(‘form#formOptions input’).autosave.go();}
$(‘form#formOptions input’).autosave.restore();
となった。
もう少し調べてから反映させることにしよう。テスト中にFirefoxが落ちることがあったので、なんかまだ問題がありそうな気もする。
ところで、FirefoxとChromeはcookieの削除が非常にラク。消したいものだけ消せるので、面倒がない。IEだとファイルが見つからないので全部消すはめに。なんかうまい方法がないものか。
(追記)
関数呼び出し時(何度も使っているが、この呼び方で合っているかわからない)にオプションを指定できるようになった。
12行目(?)にある
var opts = $.extend({}, $.fn.autosave.options, options);
を
$.extend($.fn.autosave.options, options);
書き換え。これでプラグイン内に記述されたオプションの値を、関数呼び出し時に上書きできるようになった。
これで、今後も使いまわすことが容易になるはず。まあ、そんな機会があるかどうかわかりませんが。一応、メモ。
こんなにはまるのならjQuery関連の書籍とかで最初からきちんと勉強したほうがいいかもしれない。これまですべてWebで拾った知識だけでやってきたので。どういうのがいいんだろうか。Amazonで人気があるのはこのへん?
Web制作の現場で使う jQueryデザイン入門 (WEB PROFESSIONAL)
jQueryで作る Ajaxアプリケーション
jQueryクックブック
jQuery ポケットリファレンス (POCKET REFERENCE)
jQuery+JavaScript実践リファレンス―Webデザインを強化するための
jQueryプログラミング入門―Ajaxにも使えるJavaScriptライブラリ
新人プログラマのためのjQuery Webアプリケーション開発講座
jQuery入門―魔法のJavaScriptリファレンス&サンプル
jQuery UI+厳選プラグイン41 実践サンプル集
jQueryプラグインブック―「軽量」「高機能」 JavaScriptライブラリの導入と活用! (I・O BOOKS)
Posted with fun9.net
(追記 2012/09/21)
チェックボックスの状態がリストアできないことが判明(上記ではダミーとしてしか使ってなかった)。console.logで見ると、クッキーの値は保持されている。しかし、それを反映する方法が違っていた模様。これはjQueryのバージョンによる違いなのか? とりあえず、attr()のみで書かれていたのを、removeAttr()と併用することに。
コメント