[Force.comでWeb制作]Visualforceページでlightboxの実装

By |11月 22, 2009|Force.comでWeb制作, Javascript, |


Visualforceページ内で簡単にlightboxを設置できる便利なAppExchangeを見つけました。

Lightbox

lightboxっていうのは、こういうふうににゅーいんと開くウィンドウのことです。よく画像表示なんかでみかけますね。

内容

このlightboxはVisualforceコンポーネント化されていて、以下のような内容になっています。

[html]
<!– Jonathan Hersh – jhersh@salesforce.com – 7/13/2009 –>

<apex:component selfclosing="true">
<apex:attribute name="function" description="This is the name of the JS function to call."
type="String" required="true"/>
<apex:attribute name="title" description="This is the title displayed in the lightbox."
type="String" required="true"/>
<apex:attribute name="content" description="This is the HTML content of the lightbox."
type="String" required="true"/>
<apex:attribute name="width" description="This is the width, in pixels, of the lightbox."
type="Integer" required="true"/>
<apex:attribute name="duration" description="This is the duration, in ms, to show the box before it autohides (i.e. 2000ms = 2 sec), or 0 for an untimed box."
type="Integer" required="true"/>

<script type="text/javascript">
function {!function}() {
var box = new parent.SimpleDialog("hersh"+Math.random(), true);
parent.box = box;

box.setTitle("{!title}");

box.createDialog();
box.setWidth({!width});

box.setContentInnerHTML("<a href=\"#\" onclick=\"box.hide();\">Close</a><br /><br /><p>{!content}</p>");

box.setupDefaultButtons();

box.show();

if( {!duration} > 0 )
setTimeout("box.hide();",{!duration});
}
</script>
</apex:component>

[/html]

ソースをみるとYahoo! UI LibrarySimpleDialogを呼び出す仕組みのようですので、SimpleDialogをきちんと理解すればもっとカスタマイズできそうです。

実際にVisualforceページに実装するときには、以下のように書きます。

[html]
//コンポーネント呼び出し
<c:lightbox function="lbconfirm" width="500" title="TwitterForce" content="Changes saved successfully." duration="2000" />
—————————————————-
//リンクやボタンにlightbox実装(oncomplete時の関数がコンポーネントのfunction属性と結びつく)
<apex:commandbutton oncomplete="lbconfirm();" value="Save" action="{!doSave}" />
[/html]

コンポーネントの各パラメータは以下の意味を持ちます。

  • FUNCTION = JavaScriptのfunction名。ここで定義した名前をボタンやリンクのイベントハンドラと結びつける。
  • WIDTH = lightboxの横サイズ。
  • TITLE = lightboxに表示されるタイトル。
  • CONTENT = lightboxに表示されるHTML内容
  • DURATION = lightboxが表示される時間をミリセコンドで指定。0を指定すると無制限で表示。

lightbox内で表示する内容

lightbox内に表示されるHTML内容は、コンポーネントタブの1パラメータ内に直接HTMLを書くという仕様になっています。簡単なメッセージを表示する程度ならいいのですが、AppExchangeのスクリーンショットにあるようにこういうふうに入力画面を実装したい場合にはどうしたらいいんだろう?フォーム入力のVisualforceソースを直接パラメータに書くのか?けどそれだとめちゃくちゃなタグ構造になりそうだしちゃんと解釈されるんだろうか?と思って調べてみました。

サンプル画面はTwitterforceアプリの画面のようなので、まずはTwitterforceをインストールして、それっぽいページを探す。TwitterForce – SetupというタブのページがそれっぽいのでこのページのVisualforceソースを見てみる。tfsetupというページがそれっぽい。ソースはかなり長いので、コンポーネントタグ使用部だけを抜粋すると、

[html]
<c:lightbox function="lbconfirm" width="500" title="{!appname}" content="Changes saved successfully." duration="1500" />
<c:lightbox function="lbfail" width="500" title="{!appname}" content="Invalid username/password, or Twitter is down." duration="0" />
<c:lightbox function="initSetup" width="500" title="{!appname}" content="<iframe src=’/apex/twitterforceInitialSetup’ style=’border: 0; width:460px; min-height: 470px’ ></iframe>" duration="0" />
<c:lightbox function="newAcct" width="500" title="{!appname}" content="<iframe src=’/apex/twitterforceInitialSetup?newAcct=1′ style=’border: 0; width:460px; min-height: 170px’ ></iframe>" duration="0" />

[/html]

こんな感じ。なるほど、iframeで入力画面を呼び出してるのか。

応用

よく遭遇するlightboxの使い方として、まず何かが一覧表示されていて(カレンダーとか)そこの1マスをクリックすると入力画面が表示されて入力完了するとlightboxが閉じて最初の一覧表示画面も更新される、っていうシーンに遭遇するのでこのアプリベースで試してみました。

http://abeuhuru-developer-edition.na2.force.com/lightboxsample

こんな感じ。いい感じ。