MooToolsとSqueezeBoxを使って作る問い合わせフォーム

カテゴリ: JavaScript / 公開日: 2009年1月13日(火曜)01:31 / 投稿者: Tom Goodsun

サイトのリニューアルを画策しているのですが、忘れていたコンタクトフォームに手をつけました。どうしようかとも思いましたが、今回はMooToolsとSqueezeBoxを利用して、モーダル式で処理することにしました。

何はともあれ、コンタクトフォームのデザインとコーディングをして、HTMLを完成させておきましょう。その時点で、モーダルのタテ、ヨコのサイズも決めておきます。

まずSqueezeBoxのサイトからJSファイルとCSSファイルをダウンロード。MooToolsのサイトからSqueezeBoxのサイトで指定されているオプションでダウンロードします。すべてのオプションをダウンロードしてもいい気もしますが。

MooTools、SqueezeBoxの順で読み込み、SqueezeBoxのIFRAMEの利用方法で以下のHTML、JavaScriptを呼び出し側のHTMLで指定します。HREFには呼び出すHTMLを指定します。

<a href="contact.htm" class="rollover boxed" rel="{closeBtn:false,handler:'iframe',size:{x:500,y:500}}">問い合わせ</a>

するとひとまず呼び出されますよね。
<%image(blog/20090113001.png|400|330| alt=""title="")%>

 

今回はコンタクトフォームのHTML側にフォームチェックとほかもろもろの処理をさせるJavaScriptを構築しました。その名もContactFormクラス。これの詳細はさておき、問題となった部分をかいつまんで紹介していきます。

まずはモーダル内からのモーダルのクローズ(閉じる)です。いろいろ探ってみましたが、行き着いたのはJoomla!。私も良く知るCMSなのですが、管理画面内でSqueezeBoxを使用しているのです。フォーラムを検索してみるといろいろ出てきました。が、うまくいかない。どうやら呼び出し側で定義されているJavaScriptのSqueezeBoxクラスのclose()メソッドを呼び出すとできるみたいです。「閉じるボタン」にしたい要素のクリックイベントに以下のようなJavaScriptを記述すればうまくいきます。

window.parent.SqueezeBox.close();

 

まだ問題がありまして、閉じるときに確認が必要だと思います。用は不意にESCキーを押してしまったり、elseWhereをクリックしてしまったときのケアですね。これにはSqueezeBox.close()メソッドを書き換えるしかありません。しかし、極力コアファイル(特にJSファイル)はいじりたくないものです。そこで、オーバーライドという手段をとりました。IFRAMEモーダルを初期化するとき、ドキュメントが読み込まれてから、処理を埋め込みます。そこにSqueezeBox.close()メソッドを再定義します。呼び出し側のHTMLで記述したJavaScriptを以下のように変更します。

// Wait for the content ...
window.addEvent('domready', function() {
/* Override SqueezeBox.close() method to customize */
SqueezeBox.close = function(e) {
// Confirm closing the modal if form is changed
// Add id attribute when it is created (ref.Line 369 in SqueezeBox.js)
var iframeObject = document.getElementById("contactform_iframe").contentWindow;
if(iframeObject.ContactForm.getFormChanged()){
if (!confirm(iframeObject.ContactForm.getStatusMessage("close"))){
return this;
}
}
// The following script is the same as the native implementation of SqueezeBox.js
var stoppable = ($type(e) == 'event');
if (stoppable) e.stop();
if (!this.isOpen || (stoppable && !$lambda(this.options.closable).call(this, e))) return this;
this.fx.overlay.start(0).chain(this.toggleOverlay.bind(this));
this.win.setStyle('display', 'none');
this.trash();
this.toggleListeners();
this.isOpen = false;
this.fireEvent('onClose', [this.content]);
return this;
}
/**
* That CSS selector will find all <a> elements with the
* class boxed *
* The example loads the options from the rel attribute
*/
SqueezeBox.assign($$('a.boxed'), {
parse: 'rel'
});
});


モーダル内に読み込まれるHTMLに定義されているContactFormクラスにはフォームの内容が変更された場合、真偽値で変更されたかどうかというフラグを持たせるようにしています。その値を参照してSqueezeBox.close()メソッドをオーバーライドするのですが、さすがにこれはSqueezeBox.jsに1行コードを加えないと対応できない(わけでもないけど)と思い、以下のコードを369行目に追加しました。

id: 'contactform_iframe',


IFRAME内のHTMLにアクセスするにはcontentWindowというプロパティを使うみたいです。これでフォームが変更されている場合は閉じていいかの確認をするようにしました。

以下はテストサイトなので全然何もかも動きませんが、モーダルコンタクトフォームの動きは確認できます。まぁいずれは見れなくなってしまうでしょうが、、、
サンプル