Home [HDML Language] > [アクティビティの活用]

HDML Language

アクティビティの活用

HDMLの世界に足を踏み入れ、少しタグの記述に慣れた頃、この「アクティビティ」という概念にとまどう方が多いと思います。
しかし、この「アクティビティ」を使いこなすことが出来れば、HTMLでは JavaScript 等を使用しない限り出来ないことが、HDMLではタグの記述次第で可能となります。
「アクティビティ」を理解し、活用していただければ、HDMLの機能を最大限に生かすことができます。

「アクティビティとは何か?」から始めると、返ってとっつきにくくなりますので、ここでは、「どうやって活用するのか」、「どう書けばよいのか」に絞って記述しています。
まずは、このページを読み、自分でタグを書き、シミュレータ等でその動作を見て、そこから「アクティビティ」について理解を深めてください。

HDML自体、まだチンプンカンプンという方は、ますます混乱することになるかもしれませんので、ある程度、タグを組めるようになってからお読みになることをお奨めします。

なお、ここでは、現在のアクティビティを「カレントアクティビティ」と呼ぶことにします。
カレントアクティビティから、起動された新しいアクティビティのことを、「サブアクティビティ」と表現することにします。また、サブアクティビティ側から見た、呼び出し元アクティビティのことを、「元アクティビティ」とします。


  1. サブアクティビティの起動
  2. 元アクティビティへの戻り方
  3. アクティビティ間の変数
    1. サブアクティビティへ変数を渡す
    2. 元アクティビティへ変数を渡す
    3. 3-2の改良版
    4. 変数の受け渡しとNEXTオプション
  4. FRIEND=TRUE
    1. 入力データをリセットする
    2. NEXT/CANCELを無効にする
  5. アクティビティの履歴スタック

1.サブアクティビティの起動

「サブアクティビティ」を起動するには、<ACTION>,<A>〜</A>,<CE>タグ内で、TASK=GOSUB を指定します。
TASK=GOTASK=GOSUB の違いは、サブアクティビティを起動するか否か、これだけです。
目に見える動作としては、何も変わりません。

TASK=GOSUBアクションがあれば、そこから先は、サブアクティビティです。
サブアクティビティから、さらに新しいサブアクティビティを起動することもできます。

[sub]でサブアクティビティを起動



  sub
ここはサブアクティビティ




  戻る
<HDML VERSION=3.0 TTL=0>

 <DISPLAY>
  <ACTION TYPE=ACCEPT TASK=GOSUB DEST=#card2 LABEL="sub">
  [sub]でサブアクティビティを起動
 </DISPLAY>

 <DISPLAY NAME=card2>
  <ACTION TYPE=ACCEPT TASK=RETURN LABEL="戻る">
  ここはサブアクティビティ
 </DISPLAY>

</HDML>

上の例で、最初のDISPLAY カードのTASKTASK=GOであったとしても、表示される画面は同じです。

2つ目のDISPLAYカードの<ACTION>に注目してください。
TASK=RETURN となっており、DESTオプションがありません。
これは、自分(#card2)を呼び出した元アクティビティに戻りなさいという指定です。
DESTオプションが無くても、ブラウザが元アクティビティを記憶していて、そこへ戻ることが出来ます。
この場合は、元アクティビティは、最初のDISPLAYカードですから、そこへ戻ります。

新しいアクティビティを次々とネストして起動した場合でも、ブラウザは、カレントアクティビティを呼び出した元アクティビティを覚えていて、確実に呼び出し元に戻ります。

「元アクティビティに戻る」動作は、携帯電話内のキャッシュを使用しますので、通信が発生しません。
iモードやJ-SKYでは、「戻る」リンクが用意されていても、実質的にはEZwebで言うところのTASK=GO動作ですので、通信が発生します。
アクティビティの最大の利点はここにあります。

1つ目のDISPLAYカードから2つ目のDISPLAYカードにTASK=GOで移動した場合、もし、2つ目のカードの<ACTION>TASK=RETURNがあったら、その前にTASK=GOSUBがあった所まで戻ります。
さかのぼってもTASK=GOSUB が見つからなければ、EZwebのトップメニューが表示されます。

2.元アクティビティへの戻り方

1.で説明したように、サブアクティビティから、元アクティビティへ戻るには、TASK=RETURNを使用する方法があります。
元アクティビティへ戻る方法には、もう1つあり、それがTASK=CANCELです。
上記1.の例で、2つ目のDISPLAYカードの<ACTION>内にあるTASK=RETURNTASK=CANCELに置き替えるだけです。
表示される画面は、1.とまったく同じになります。

表示される画面は全く同じ-----では、何故、2つの方法が用意されているのでしょうか?

次のサンプルをご覧下さい。

1Card1へ
2Card2へ

  sub
1を選択
ここは#card1
RETURNで戻ります

  戻る
ここは#next


  戻る

1Card1へ
2
Card2へ

  sub
2を選択
ここは#card2
CACNELで戻ります

  戻る
ここは#cancel


  OK
<HDML VERSION=3.0 TTL=0>

 <CHOICE KEY=card>
  <ACTION TYPE=ACCEPT TASK=GOSUB DEST=#$(card) LABEL="sub"
   NEXT=#next CANCEL=#cancel>
  <CE VALUE=card1>Card1へ
  <CE VALUE=card2>Card2へ
 </CHOICE>

 <DISPLAY NAME=card1>
  <ACTION TYPE=ACCEPT TASK=RETURN LABEL="戻る">
  ここは#card1<BR>
  RETURNで戻ります
 </DISPLAY>

 <DISPLAY NAME=card2>
  <ACTION TYPE=ACCEPT TASK=CANCEL LABEL="戻る">
  ここは#card2<BR>
  CANCELで戻ります
 </DISPLAY>

 <DISPLAY NAME=next>
  <ACTION TYPE=ACCEPT TASK=GO DEST="?" LABEL="戻る">
  ここは#next<BR>
 </DISPLAY>

 <DISPLAY NAME=cancel>
  <ACTION TYPE=ACCEPT TASK=GO DEST="?" LABEL="戻る">
  ここは#next<BR>
 </DISPLAY>

</HDML>

1つ目のCHOICEカードの<ACTION>に、NEXT=#next CANCEL=#cancel が追加されています。
これは、この先のサブアクティビティで

という指示です。

このように、TASK=RETURNで戻るか、TASK=CANCELで戻るかにより、その後の処理を分岐することができます。
上の例では、あまり意味がない動作になっていますが、変数をやりとりしたり、間にCGIなどをはさむと、ちょっと面白くなります。

ちなみに、NEXT及びCANCELオプションによる移動は、TASK=GOと同義です。

3.アクティビティ間の変数

変数の参照が可能なのは、カレントアクティビティのみです。

サブアクティビティでは、原則として、元アクティビティで使用していた変数を参照することはできません。HDML変数は、各アクティビティ毎に管理されます。これは、変数名の重複を防ぐのに効果があります。

サブアクティビティで、元アクティビティの変数を利用したい場合は、VARSオプションにより、それを可能にすることができます。また、RETVALSオプションの利用により、サブアクティビティ側から、元アクティビティへ、変数を渡すこともできます。

2.の例の説明で、TASK=RETURN/CANCEL があったら、一旦ここ(元アクティビティ)へ戻り、#next/#cancel カードを表示するという機能を紹介しましたが、この「一旦ここ(元アクティビティ)へ戻る」という動作は、変数をやりとりする上で大きな意味を持ちます。

3-1.サブアクティビティへ変数を渡す

変数を、アクティビティを越えて渡したい場合は、VARSオプションを用います。

お名前:
Kimura_


  OK
あなたのお名前は
Kimuraですね
よろしいですか?

No Yes
Yes
No
よかった


  OK
え〜違うの?


  OK
<HDML VERSION=3.0 TTL=0>

 <ENTRY KEY=name>
  <ACTION TYPE=ACCEPT TASK=GOSUB DEST=#check
   VARS="name=$(name)" NEXT=#next CANCEL=#cancel>
  お名前:
 </ENTRY>

 <DISPLAY NAME=check>
  <ACTION TYPE=ACCEPT TASK=RETURN LABEL=Yes>
  <ACTION TYPE=SOFT1 TASK=CANCEL LABEL=No>
  あなたのお名前は<BR>
  $(name)ですね<BR>
  よろしいですか?
 </DISPLAY>

 <DISPLAY NAME=next>
  よかった
 </DISPLAY>

 <DISPLAY NAME=cancel>
  え〜違うの?
 </DISPLAY>

</HDML>

VARSオプションにより、元アクティビティ→サブアクティビティへ$(name)が渡されますので、異なるアクティビティであるcheckカードでも、$(name)の値を参照することができます。

上記は、サンプルとしてあげたもので、あまり実用的ではありません。

<<ここで問題>>
最後に表示されるDISPLAYカード(nextカードでもcancelカードでも良い)で[OK]を選択したら、どのカードが表示されるでしょうか?

(ヒント)
NEXT/CANCELオプションによる移動は、TASK=GOにより行われる。
<ACTION>を指定していないカードのデフォルトタスクは、PREV

答えは、ご自分で上記のタグをシミュレータ等で実行させてみた上で出して下さい。

3-2.元アクティビティへ変数を渡す

サブアクティビティ側から、自分を起動した元アクティビティへ戻るときに、変数データを一緒に持ち帰ることが出来ます。サブアクティビティ側でRETVALSオプションを、受け取る元アクティビティ側ではRECEIVEオプションを指定します。これは、TASK=RETURN時のみ可能です。

TASK=CANCELでは、サブアクティビティ側の処理をすべて破棄して元アクティビティへ戻ります。

1お名前:
2コメント:


  入力
お名前:
Kimura_


  OK
1お名前:Kimura
2
コメント:


  入力
コメント:
はろー_


  OK
1お名前:Kimura
2
コメント:はろー


  入力
<HDML VERSION=3.0 TTL=0>

 <CHOICE>
  <CE TASK=GOSUB DEST=#ename LABEL="入力"
   VARS="name=$(name)" RECEIVE="name">
   お名前:$(name)
  <CE TASK=GOSUB DEST=#ecomm LABEL="入力"
   VARS="comm=$(comm)" RECEIVE="comm">
   コメント:$(comm)
 </CHOICE>

 <ENTRY KEY=name NAME=ename>
  <ACTION TYPE=ACCEPT TASK=RETURN
   RETVALS="$(name)">
  お名前:
 </ENTRY>

 <ENTRY KEY=comm NAME=ecomm>
  <ACTION TYPE=ACCEPT TASK=RETURN
   RETVALS="$(comm)">
  コメント:
 </ENTRY>

</HDML>

VARSオプションで$(name),$(comm)変数をサブアクティビティへ渡し、サブアクティビティから元アクティビティへ戻る際に、それぞれのENTRYカードで入力(編集)されたデータをRETVALSで戻しています。
RETVALSで戻すのは、変数の「」のみです。VARSのように、変数名と変数値をセットにして渡すことはしません。

戻ってこられた各<CE>では、RECEIVEオプションで、サブアクティビティから渡された変数値を受け取ります。RECEIVEで指定するのは、変数名のみです。
サブアクティビティ側では「値」を返し、元アクティビティ側ではそれを受け取る「変数名」を指定するわけです。

3-3.3-2.の改良版

実は、3-2.の例は、あまり良くないのです。わかりやすさを一番に考えて記述しましたので、HDMLの機能を生かすという面では、少し見劣りします。
以下のように書くと、よりシンプルになります。表示される画面や動作は、3-2.と全く同じです。

ただし、下記のようにVARSの変数名に日本語を指定できるのは、EZweb実機のみです。
以下のソースをシミュレータで表示させると、Bad Source エラーになります。
シミュレータでも表示できるようにするには、VARS内の日本語文字列をURLエスケープする必要があります。

<HDML VERSION=3.0 TTL=0>

 <CHOICE>
 <ACTION TYPE=ACCEPT LABEL="入力">
  <CE TASK=GOSUB DEST=#entry
   VARS="title=お名前&val=$(name)" RECEIVE="name">
   お名前:$(name)
  <CE TASK=GOSUB DEST=#entry
   VARS="title=コメント&val=$(comm)" RECEIVE="comm">
   コメント: $(comm)
 </CHOICE>

 <ENTRY KEY=val NAME=entry>
 <ACTION TYPE=ACCEPT TASK=RETURN RETVALS="$(val)">
  $(title):
 </ENTRY>

</HDML>

3-4.変数の受け渡しとNEXTオプション

もし、3-3.の例で、元アクティビティ側にNEXTオプションが指定されていた場合、変数データの受け渡しはどうなるでしょうか?
アクティビティ間の動作の順序は、以下のようになっています。

  1. TASK=GOSUBでサブアクティビティ起動
  2. VARSオプションが指定されていれば、サブアクティビティへ指定した変数データを渡す
  3. TASK=RETURNで元アクティビティへ戻る
  4. サブアクティビティ側で、RETVALSオプションが指定されていれば、元アクティビティへ指定した変数値を渡す
  5. 元アクティビティ側では、RECEIVEオプションで指定する変数名で、サブアクティビティから渡された変数値を受け取る
  6. 元アクティビティ側に、NEXTオプションが指定されていれば、そのURLへ(TASK=GOにより)ジャンプする。

RETVALS/RECEIVEが、NEXTより先に実行されますので、変数データの受け渡しが行われた後に、NEXTが動作することになります。
NEXTでジャンプした先でも、RECEIVEした変数が参照できます。

4.FRIEND=TRUE

カレントアクティビティからサブアクティビティを起動する際、FRIEND=TRUEを指定すると、サブアクティビティ側から元アクティビティの変数にアクセスすることができるようになります。
これは、サブアクティビティ側に、以下のような2つの大きな権利を与えます。

  1. サブアクティビティ側でTASK=RETURN/CANCEL 及びDESTオプションがあると、元アクティビティ側で、NEXT/CANCELオプションを指定していても、そのデータを上書きする。

  2. サブアクティビティ側でTASK=RETURN 及び CLEAR=TRUE オプションがあると、FRIEND=TRUE なアクティビティ全体の変数をクリアできる。

このFRIEND=TRUE は、「セキュリティについて」でも説明している通り、使用には注意が必要ですが、うまく使いこなせば、非常に便利なものです。

4-1.入力データをリセットする

CLEAR=TRUEオプションにより、ユーザーが入力した内容をリセットします。
HTMLのフォームの「リセット」ボタンと同じ働きをします。
入力したデータをリセットするのに、VARSを使っているサイトを散見しますが、VARSによるリセットでは、変数名は消去されません。VARSオプションは、変数の初期化(リセットとは違う)、複数の変数データ渡し、サブアクティビティへの変数渡しの用途に使用するものです。

1お名前:Kimura
2コメント:はろ〜
3
リセット

  Reset
ストックされている変数
name="Kimura"
comm="はろ〜"
3 リセットを
選択
1お名前:
2コメント:
3
リセット

  Reset
ストックされている変数
(なし)
<HDML VERSION=3.0 TTL=0>

 <CHOICE>
 <ACTION TYPE=ACCEPT LABEL="入力">
  <CE TASK=GOSUB DEST=#entry
   VARS="title=お名前&val=$(name)" RECEIVE="name">
   お名前:$(name)
  <CE TASK=GOSUB DEST=#entry
   VARS="title=コメント&val=$(comm)" RECEIVE="comm">
   コメント: $(comm)
  <CE TASK=GOSUB DEST=#reset FRIEND=TRUE LABEL="Reset">
   リセット
 </CHOICE>

 <ENTRY KEY=val NAME=entry>
 <ACTION TYPE=ACCEPT TASK=RETURN RETVALS="$(val)">
 $(title):
 </ENTRY>

 <NODISPLAY NAME=reset>
 <ACTION TYPE=ACCEPT TASK=RETURN CLEAR=TRUE>
 </NODISPLAY>

</HDML>

「3 リセット」のCEタグ内に、「TASK=GOSUB」及び「FRIEND=TRUE」があります。
これが、「呼び出すサブアクティビティは、『フレンド』である」という宣言です。
これにより、サブアクティビティ側から、呼び出し元アクティビティの全変数にアクセスが可能になり、さらに、サブアクティビティ側に「TASK=RETURN」及び「CLEAR=TRUE」があると、『フレンド』なアクティビティ全体の変数をクリアすることができます。

上記の例では、<CHOICE>カードと<NODISPLAY>カードが『フレンド』となりますので、<NODISPLAY>カード側から呼び出し元である<CHOICE>カードの全変数をクリアすることになります。

4-2.NEXT/CANCELを無効にする

2.元アクティビティへの戻り方」でも説明している通り、TASK=RETURN/CANCEL で元アクティビティに戻る時、元アクティビティ側でNEXT/CANCELオプションを指定していると、元アクティビティをスルーして、NEXT/CANCELで指定したURLへジャンプさせることができます。

FRIEND=TRUEで起動されたサブアクティビティでは、TASK=RETURN/CANCEL と共に、DESTオプションを組み合わせることにより、元アクティビティのNEXT/CANCELを無効(上書き)にすることができます。

ほとんどの場合、NEXT/CANCELオプションで事足りると思いますが、例外的な処理をしたい時など、どうしても必要な場合に別のURLを指定することができます。

送信します
よろしいですか?


No  Yes
名前とコメント両方、
あるいはどちらかが

きちんと入力されて
いたら
送信ありがとう!!



  戻る

名前とコメント両方とも
入力されていなかったら
CGI側で
TASK=RETURN
及びDEST=を指定し
他のデッキへ飛ばす
<HDML VERSION=3.0 TTL=0>

 <DISPLAY NAME=mail>
 <ACTION TYPE=ACCEPT TASK=GOSUB DEST=#name
  LABEL="進む" FRIEND=TRUE NEXT=#thanks CANCEL=#name>
  管理人にメールくれます?<BR>
  では次へ進んでください
 </DISPLAY>

 <ENTRY KEY=name NAME=name>
 <ACTION TYPE=ACCEPT TASK=GO DEST=#comm>
 お名前:
 </ENTRY>

 <ENTRY KEY=comm NAME=comm>
 <ACTION TYPE=ACCEPT TASK=GO DEST=#confirm>
 コメント:
 </ENTRY>

 <DISPLAY NAME=confirm>
 <ACTION TYPE=ACCEPT TASK=GO DEST="mail.cgi" LABEL="Yes"
   METHOD=POST POSTDATA="name=$(name)&comm=$(comm)">
 <ACTION TYPE=SOFT1 TASK=GO DEST=#name LABEL="No">
 送信します<BR>
 よろしいですか?
 </DISPLAY>

 <DISPLAY NAME=thanks>
 <ACTION TYPE=ACCEPT TASK=GO DEST="home.hdml"
  LABEL="戻る">
  送信ありがとう!!
 </DISPLAY>

</HDML>

--私自身、ほとんど使ったことがないオプションなので、良いサンプルが浮かびませんでした。

ユーザーに「名前」と「コメント」を送信してもらうフォームです。
ユーザーがきちんと「名前」と「コメント」のどちらか(あるいは両方)を入力して送信してくれた場合のみ、#thanksカードを表示します。
空送信の場合は、CGI(Perlの場合)側から

print "Content-type:text/x-hdml;charset=Shift_JIS\n\n";
print "<HDML VERSION=3.0 TTL=0>";
print "<NODISPLAY>";
print "<ACTION TYPE=ACCEPT TASK=RETURN DEST='some.hdml'>";
print "</NODISPLAY>";
print "</HDML>";

のように出力し、元アクティビティ側のNEXTオプションを上書きして「送信ありがとう!!」の画面を表示することなく、some.hdmlへジャンプさせます。

5.アクティビティの履歴スタック

ここは、アクティビティについて、もっと知りたい方のみお読み下さい。

TASK=GOのみを使用した場合、携帯電話内部の履歴スタックは、単純に、今までに閲覧した順番で保存されます。
今見ている画面が、履歴スタックの最後に保存されています。PREVキーを押すと、今見ている画面の履歴スタックが破棄され、そのひとつ前の履歴スタック(つまり前画面)が表示されます。

アクティビティを起動すると、履歴スタックは、各アクティビティ毎に保存されるようになります。
各アクティビティが起動された順番に保存され、アクティビティ毎に、閲覧した順番で履歴スタックが保存されますので、TASK=RETURN/CANCELがあると直前のアクティビティの履歴スタック内での最新履歴(つまり元アクティビティ)が表示されるということになります。

<画面> <履歴スタック> <ソース>

◇お料理レシピ◇
1お肉
2お魚
3ご飯
4麺類
5デザート

  選択
5 を選択
(サブアクティビティ起動)
◇デザート◇
1ケーキ
2クッキー
3タルト
4アイスクリーム
5和菓子

  選択
1 を選択
◇ケーキ◇
1ショートケーキ
2チーズケーキ
3シフォンケーキ
4チョコケーキ

  選択
2 を選択
チーズケーキレシピ
材料:
クリームチーズ
砂糖
・・・
[レシピトップへ]

  Top
[レシピトップへ]
リンク選択
◇お料理レシピ◇
1お肉
2お魚
3ご飯
4麺類
5デザート

  選択
recipe.hdml
サブアクティビティ
起動
元アクティビティ
recipe.hdml

サブアクティビティ
dessert.hdml
元アクティビティ
recipe.hdml

サブアクティビティ
dessert.hdml
dessert.hdml#cake
元アクティビティ
recipe.hdml

サブアクティビティ
dessert.hdml
dessert.hdml#cake
cheese.hdml
サブアクティビティの
履歴が破棄され、
元アクティビティが
表示される
recipe.hdml
recipe.hdml
<HDML VERSION=3.0 TTL=0>

 <CHOICE KEY=kind>
 <ACTION TYPE=ACCEPT LABEL="選択"
  TASK=GOSUB DEST="$(kind)">
  ◇お料理レシピ◇<BR>
  <CE VALUE="meat.hdml">お肉
  <CE VALUE="fish.hdml">お魚
  <CE VALUE="rice.hdml">ご飯
  <CE VALUE="noodle.hdml">麺類
  <CE VALUE="dessert.hdml">デザート
 </CHOICE>

</HDML>

dessert.hdml
<HDML VERSION=3.0 TTL=0>

 <CHOICE KEY=dessert>
 <ACTION TYPE=ACCEPT TASK=GO
 DEST="#$(dessert)" LABEL="選択">
 ◇デザート◇
  <CE VALUE="cake">ケーキ
  <CE VALUE="cookie">クッキー
  <CE VALUE="tart">タルト
  <CE VALUE="ice">アイスクリーム
  <CE VALUE="japanese">和菓子
 </CHOICE>

・・・

 <CHOICE KEY=cake NAME=cake>
 <ACTION TYPE=ACCEPT LABEL="選択"
  TASK=GO DEST="$(cake)">
 ◇ケーキ◇
  <CE VALUE="short.hdml">ショートケーキ
  <CE VALUE="cheese.hdml">チーズケーキ
  <CE VALUE="chiffon.hdml">シフォンケーキ
  <CE VALUE="choco.hdml">チョコケーキ
 </CHOICE>

</HDML>

cheese.hdml
<HDML VERSION=3.0 TTL=0>

 <DISPLAY>
 <ACTION TYPE=ACCEPT TASK=NOOP>
 チーズケーキレシピ<BR>
  材料:<BR>
  クリームチーズ<BR>
  砂糖<BR>
  ・・・<BR>
 <A TASK=RETURN LABEL="Top">
  レシピトップへ</A>
 </DISPLAY>

</HDML>

Go to Top

最終更新日:2002年11月7日
© My First HDML