- PR -

jsfでの子画面の表示と画面を閉じる制御について

投稿者投稿内容
かに
会議室デビュー日: 2005/12/04
投稿数: 11
投稿日時: 2008-05-31 14:33
いつもお世話になっております。

jsfで画面開発を行っており、その画面(画面A)の要件として、
画面Aを閉じたら画面Aのリンクから開かれた子画面(数は不定)
をすべて閉じると言う要件があります。

リンクのパターンとして、
@h:commandLinkタグを利用。renderedで表示を制御し、画面Aから開かれる画面数は無制限。
<h:outputLink id="linkType"
rendered="#{item.hoge == 'true'}"
value="#{item.value}" target="_blank">
<h:outputText value="#{item.name}"/>
</h:outputLink>

Ah:commandLinkを利用。renderedで表示を制御し、画面Aから開かれる画面数は1つ。
パラメタを渡す。
<h:commandLink action="#{item.doLinkClick}"
rendered="#{item.hoge == 'true'}"
target="xxx">
<f:param name="userid" value="#{backingBean.zzz}"/>
<h:outputText value="#{item.name}"/>
</h:commandLink>

となっているのですが、@、Aの実装ですと、親画面を閉じると子画面を閉じる
と言う要件が満たせません。(javascriptのwindow.openを使う必要があると
考えています。)
@のリンクパターンについては
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=43495&forum=12
のスレを参考に解決できるかなと思っていますが、
Aのリンクパターンについて方法が思いつきません。
何か良い方法はございませんでしょうか?
ranco
大ベテラン
会議室デビュー日: 2007/11/02
投稿数: 112
投稿日時: 2008-05-31 19:41
漠然と言えば、onUnloadを使うってこと?
JSFでは使えない?
かに
会議室デビュー日: 2005/12/04
投稿数: 11
投稿日時: 2008-05-31 20:23
rancoさん

説明不足でした。画面Aの閉じるボタンをクリックされたら
画面Aから開かれているすべての画面を閉じるという仕様です。
画面を開く、閉じるのjsは以下のようにすればイケそうなのですが、
h:outputLinkやh:commandLinkを使用しないで、
renderedでの表示制御や、submitして値を渡す方法が思いつかないのです。。
ちなみに×ボタンを押されたときもすべての画面を閉じる必要があるので、
onUnloadを使う必要はあると思っています。
//画面を開くスクリプト
var w;
function showWindow(url) {
if (w != undefined) {

if(w.closed==false) {
w.opener="dummy";
w.close();
}
}

w = window.open (url);
}
// 画面Aと開かれた画面を閉じるスクリプト
function testClose() {
if (w != undefined && w.closed==false) {
w.opener="dummy";
w.close();
}
window.opener="dummy";
window.close();
}
ぴあちゃん
ぬし
会議室デビュー日: 2008/02/07
投稿数: 287
投稿日時: 2008-05-31 21:05
unload って再読み込みや、ページ遷移でも発生するから単純に実装すると
子ページで遷移しただけでその子が勝手に閉じてしまう、ってことになり
かねないと思います。

「×」ボタン押されたのか、リロードなのかを明確に判定するフラグが存在
しないので無理じゃないでしょか。

「「閉じる」ボタンを押さない場合に子画面が残ってしまうことは責任もてません」
とかとんでもない仕様を周知徹底させる必要があると思いますね。

であれば、「閉じる」ボタンでしか画面を閉じることが出来ないので
window.open して初期表示されたタイミングでその親画面に対して、
子画面のオブジェクトを登録してあげることで、つまり、画面のツリー
構造を持つようにしておいて、各画面の「閉じる」ボタン押下時に、
そのツリー以下の子ノード全てを window.close してあげればいけ
そうな気がします。

# 苦労の割りにむ報われない気がします。
# 以前スレ主さんとまったく同じ要件でスクリプト組みましたよ。
# 「×」押しちゃだめ、っていう文面はほとんど現場では無力です。
#

[ メッセージ編集済み 編集者: ぴあちゃん 編集日時 2008-05-31 21:39 ]
かに
会議室デビュー日: 2005/12/04
投稿数: 11
投稿日時: 2008-06-01 00:49
ぴあちゃんさん

お返事ありがとうございます。
×ボタンに関しては下記のスクリプトが一般的に使用されているようなので
それで大丈夫かなと思ってます。
これですと、再読み込みは検知されないので。

function window.onbeforeunload() {
if(((event.clientX > document.body.clientWidth) && (event.clientY<0)) || event.altKey ) {
// 画面を閉じる処理
}
}
ぴあちゃん
ぬし
会議室デビュー日: 2008/02/07
投稿数: 287
投稿日時: 2008-06-01 02:15
親A
子A1
子A2

って感じのとき、
w = window.open()
ってやって、w をどこかに保持しておく、じゃなくて、
window.open() で submit した先つまり、子A1の画面の初期化で
親があるときは、親に自分を登録してあげる、ってやればいけそう
ですね。

コード:
子A1の onload で
function window.onload(e) {
   if (window.opener) {
       window.opener.addChildWindow(window);
   }
}



コード:
親Aに
var childwindow = new Array();

function addChildWindow(w) {
   if (w) {
      childwindows.push(w);
   }
}
function window.onbeforeunload(e) {
    if (...) {
       for (var w in childwindows) {
          if (!w.closed) {
            w.close();
          }
       }
    }
}


こんな感じでしょうか。
こうすれば、commandLink タグを活かしたままでいけそうです。

かに
会議室デビュー日: 2005/12/04
投稿数: 11
投稿日時: 2008-06-01 19:02
ぴあちゃんさん

なるほどー!そういう方法もあるのですね。
勉強になりました!
ただ、commandLinkタグとoutputLinkタグで開かれたwindowにopenerって
あるのでしょうか?(子1のif (window.opener)が心配です・・・。)
ちょっと気になるので検証してみたいと思います。
ありがとうございます!
ぴあちゃん
ぬし
会議室デビュー日: 2008/02/07
投稿数: 287
投稿日時: 2008-06-01 21:11

アンカーを持つ親画面のHTML
コード:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<TITLE></TITLE>
<script>
window.onbeforeunload = function() {
}
function sampleFunction() {
alert("アンカーで開いても親子関係は保てます");
}

</script>
</HEAD>
<BODY>
<a href="mudai2.htm" target="_blank">AAA</a>

</BODY>
</HTML>




アンカーで開く子画面のHTML
コード:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<TITLE></TITLE>
<script>

alert(window.opener.sampleFunction);

</script>

</HEAD>
<BODY>
<a href="mudai3.htm" target="_blank">BBB</a>

</BODY>
</HTML>




子1の子1同じくアンカーで開いてトップの親のsampleFunction を見る。
コード:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<TITLE></TITLE>
<script>
alert(window.opener.opener.sampleFunction);
</script>
</HEAD>
<BODY>


</BODY>
</HTML>




アンカーは問題なしですね。

あとはフォームかな。


[ メッセージ編集済み 編集者: ぴあちゃん 編集日時 2008-06-01 21:18 ]

スキルアップ/キャリアアップ(JOB@IT)