別のページの一部を利用したページの更新

外部 タイプの AJAX 要求は、あるページ上の指定エリアを 2 番目のページ上の指定エリアで置き換えるよう、サーブレットに促します。更新タイプの要求と同様、パラメーターを 2 番目のページに渡すことができます。onPreRenderFunction 関数は、J2EELib.getQueryParameter システム関数を使用することで、それらのパラメーターを取得することができます。

このタイプの要求では、更新対象となる最初のページのエリア、要求を起動するイベントを指定します。また、要求と一緒に渡されるパラメーターも、オプションで指定できます。他のタイプの要求とは異なり、AJAX 外部要求は別のページを対象とするので、要求の送信先となるページと、最初のページの代わりにこのページで使用されるコントロールを指定する必要があります。

このタイプの AJAX 要求を使用するためには、以下のような 2 つのページを作成する必要があります。 以下のステップに従って、AJAX 外部要求を Web ページに追加します。
  1. 別のページで使用するコンテンツを保持するソース・ページを作成します。
    1. EGL 制御の Web ページを作成する際に通常使用する方法で、JSP ファイルおよび JSF ハンドラーを作成します。
    2. このページで、パネル・コントロールを追加し、ページ内で固有の ID をコントロールに指定します。
    3. コンテンツをパネル・コントロール内に追加します。このパネルからコンテンツを取り出して、別のページで使用するように、要求を通じてサーブレットに命令します。
    4. ページの JSF ハンドラー内で、要求を受け入れるように onPreRenderFunction を構成します。

      AJAX 要求の実行時だけでなく、ページの初回ロード時にも onPreRenderFunction が実行されるため、この関数がどのような操作の結果として実行されることになったかを確認することをお勧めします。 そのためには、パラメーター $$ajaxmode の値をテストします。通常のページ・ロード操作の結果として関数が実行されている場合、このパラメーターは NULL になります。一方、AJAX 要求の結果として関数が実行されている場合、このパラメーターには値が含まれます。

      function onPreRender()
        
        if (J2EELib.getQueryParameter("$$ajaxmode") == NULL)
          //このページは、初めてロードされました。
          //ページのロード操作を、ここで行ってください。
        else
          //AJAX 要求の結果、このページがロードされました。
          //AJAX の更新操作を、ここで行ってください。
        end
      
      end
    5. onPreRenderFunction が AJAX 要求の結果として起動されたことを確認したら、ページ上のコントロールにバインドされている変数の値を設定して、そのコントロールを更新することができます。更新できるのは、要求に含まれている、パネル内のコントロールのみです。
      要求と一緒に渡されるパラメーターは、J2EELib.getQueryParameter() システム関数を使用して取得することができます。例えば、nameText という ID を持つテキスト・コントロールの値が渡された場合、次のコードを使用して、そのパラメーターの値を取得することができます。
      outputText = "Hello "::J2EELib.GetQueryParameter("nameText")::"!";
  2. 次のようにして、コンテンツを配置するターゲット・ページを作成します。
    1. EGL 制御の Web ページを作成する際に通常使用する方法で、JSP ファイルおよび JSF ハンドラーを作成します。
    2. このページで、パネル・コントロールを追加し、ページ内で固有の ID をコントロールに指定します。このパネルのコンテンツは、ソース・ページ上のパネルのコンテンツに置き換えられます。
    3. (オプション) JSF コントロールをパネルに追加します。パネルは、ブランクの場合もありますし、コントロールが取り込まれている場合 (AJAX 要求によって、ソース・ページ上のパネルに置き換えられているとき) もあります。
  3. AJAX 要求を起動するユーザー・イベントを指定します。

    そのためには、JSF 動作をページ上の入力コントロールに追加してから、要求を起動するイベントを選択します。この動作が組み込まれているコントロールは、パネル・コントロール内に配置する必要はありませんが、要求を起動できるのは入力コントロールのみです。

    例えば、ユーザーが特定のコントロールにフォーカスを移動させたときに、AJAX 要求が発生するようにすることができます。その場合には、onFocus イベントを使用します。ユーザーが特定のコントロールからフォーカスを移動させたときに、要求が実行されるようにするには、onBlur イベントを使用します。その他のよく使用されるイベントとしては、onClickonMouseOveronSelect などがあります。

    1. Web ページで、トリガーとして使用する入力コントロールを選択します。
    2. コントロールを選択した状態で、「クイック編集」ビューを開きます。
    3. 「クイック編集」ビューの左側で、onBlur などのイベントを選択します。
    4. 「事前定義の振る舞いを使用」チェック・ボックスを選択します。
    5. 「アクション」リストで、「指定タグの Ajax 動作を起動」を選択します。
    6. 「ターゲット」リストで、更新するパネルの ID を選択します。
    これで、AJAX 要求を起動する動作がコントロールに付加されます。例えば、入力テキスト・コントロールに動作を付加し、onBlur イベントを使用するように設定する場合、ページのコードは次のようになります。
    <h:inputText id="nameText" value="#{myPage.name}" 
      binding="#{myPage.name_Ref}" styleClass="inputText" >
      <hx:behavior event="onblur" id="behavior1" 
        behaviorAction="get" targetAction="updatablePanel">
      </hx:behavior>
    </h:inputText>
    この動作は、次の例のようになります。
    「クイック編集」ビュー内の動作の図
  4. 更新するパネルおよび要求のパラメーターを指定して、要求を作成します。
    1. ターゲット・ページで、パネル・コントロールを選択します。
    2. パネルを選択した状態で、「プロパティー」ビューを開きます。
    3. 「プロパティー」ビューで、パネル・コントロールのタイプの下にある「Ajax」タブに移動します。
    4. 「Ajax」タブで、「Ajax 更新の許可」チェック・ボックスを選択します。
    5. 要求のタイプとして「外部」を選択します。
    6. 要求のタイプの下で、「クリックして Ajax 要求プロパティーを編集 (Click to edit Ajax request properties)」というラベルが付いているボタンをクリックします。
    7. 「ターゲット」リストで、更新するターゲット・ページ上にある、パネルの ID 属性を選択します。
    8. 「URL」フィールドで、ソース・ページへの相対パスを入力します。ターゲット・ページについては、必ず正しい拡張子 (.faces または .jsp) を使用してください。詳しくは、サーバーでの Web ページの実行を参照してください。
    9. 「ソース」フィールドで、ソース・ページ上のパネル・コントロールの ID を入力します。このパネルのコンテンツによって、ターゲット・ページ上のパネルのコンテンツが置き換えられます。

      このフィールドをブランクのままにすると、パネル・コントロールだけでなく、ソース・ページ全体 (つまり、<body> タグ内のすべてのデータ) が、要求によって取り出されます。

    10. 「パラメーターの追加」ボタンのいずれかをクリックして、パラメーターを要求に追加します。

      「ブラウザーから送信されたパラメーター値」というラベルが付いている表内のパラメーターは、ターゲット・ページ上の入力コントロールの値を参照します。例えば、ページ上の入力コントロールの現行値をパラメーターとして渡す場合は、その入力コントロールの ID をここで追加します。

      「サーバーで計算されたパラメーター値」というラベルが付いている表内のパラメーターは、ここで入力するリテラル値またはソース・ページの JSF ハンドラー内にある変数の値の、いずれかを参照します。

    例えば、ページ上の入力コントロールの値が渡されるようにした場合、新規の要求は次のようになります。
    <hx:ajaxExternalRequest id="ajaxExternalRequest1" 
      target="sourcePanel" params="nameText"
      href="sourcePage.faces" soure="replacePanel">
    </hx:ajaxExternalRequest>

これで、ターゲット・ページで要求が起動されると、AJAX 外部要求がパラメーターとともに、サーブレットによってソース・ページに渡されます。サーブレットは、ソース・ページで onPreRenderFunction 関数を起動し、その関数が完了すると、パネルをソース・ページから削除して、そのパネルをターゲット・ページに挿入します。

このトピックで説明したような、AJAX 外部要求を使用して連携する 2 つのページの例を、以下に示します。ユーザーが値を選択できるチェック・ボックスのグループが、ターゲット・ページに含まれています。AJAX 要求は、この値をソース・ページに渡します。その結果、置き換え対象のパネルがメッセージの値に基づいてレンダリングされます。

このページおよびその要求は、次の例のようになります。

「プロパティー」ビュー内のターゲット・ページと要求の図

ターゲット・ページのコード (targetPage.jsp) は、次のとおりです。

<html>
<head>
<title>targetPage</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="theme/stylesheet.css"
  title="Style">
</head>
<f:view>
<body>
<hx:scriptCollector id="scriptCollector1">

<h:form id="form1" styleClass="form">

  <h:panelGroup id="targetPanel" styleClass="panelGroup">

    <h:outputText id="promptMessage" styleClass="outputText"
      value="What is your  favorite type of friut?">
    </h:outputText>
    
    <h:selectOneRadio disabledClass="selectOneRadio_Disabled"
      enabledClass="selectOneRadio_Enabled" id="fruitName"
      styleClass="selectOneRadio">
      <f:selectItem itemValue="bananas" itemLabel="bananas" />
      <f:selectItem itemValue="apples" itemLabel="apples" />
      <f:selectItem itemValue="grapes" itemLabel="grapes" />
    </h:selectOneRadio>

    <hx:behavior event="onchange" target="fruitName" 
     behaviorAction="get" targetAction="targetPanel">
    </hx:behavior>
    
  </h:panelGroup>
  
  <hx:ajaxExternalRequest id="ajaxExternalRequest1"
    target="targetPanel" href="sourcePage.faces" 
    source="sourcePanel" params="fruitName">
  </hx:ajaxExternalRequest>
    
</h:form>
</hx:scriptCollector>
</body>
</f:view>
</html>
ターゲット・ページに関する技術情報の一部を、以下に示します。
  • タグ <h:panelGroup> は、更新される JSF パネル・コントロールであり、ID 属性 targetPanel が設定されています。
  • タグ <h:outputText> は、静的メッセージをプロンプトとして表示する、JSF 出力テキスト・コントロールです。
  • タグ <h:selectOneRadio> は、3 つのオプションを提供する、JSF チェック・ボックス・グループ・コントロールです。このチェック・ボックス・グループには、ID 属性 fruitName が設定されています。 この ID 属性は、要求と一緒に渡されるパラメーターです。
  • タグ <hx:behavior> は、AJAX 要求を起動するイベントを指定します。この動作の属性は、パネル・コントロールの ID およびラジオ・ボタン・グループを指します。このケースでは、イベントは onchange のことです。つまり、ラジオ・ボタン・グループにおける選択が変更されたときに、AJAX 要求が起動することになります。
  • タグ <hx:ajaxExternalRequest> は、AJAX 要求自体を定義します。このタグの target 属性は、パネル・コントロールを指します。つまり、パネルのイベントが起動されたときに、この要求が実行されるということを表しています。要求のその他の属性は、ソース・ページのロケーション、ソース・ページから取り出すパネルの ID、および要求と一緒に渡されるパラメーターを指しています。このケースでは、チェック・ボックス・グループでの選択が、パラメーターとして要求に組み込まれます。

このページと連携する JSF ハンドラー (targetPage.egl) は、次のとおりです。

package jsfhandlers;

handler targetPage type JSFHandler
  {view = "targetPage.jsp"} 
end

ターゲット・ページの JSF ハンドラーについては、特別なコードは必要ありません。この例では外部要求を使用しており、要求はソース・ページを対象とするため、ソース・ページの JSF ハンドラーが要求を処理します。

ソース・ページのコード (sourcePage.jsp) は、次のとおりです。

<html>
<head>
<title>sourcePage</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="theme/stylesheet.css"
  title="Style">
</head>
<f:view>
<body>
<hx:scriptCollector id="scriptCollector1" 
preRender="#{sourcePage._preRender}" postRender="#{sourcePage._postRender}">

  <h:panelGroup id="sourcePanel" styleClass="panelGroup">
    <h:outputText id="text1" styleClass="outputText"
      value="#{sourcePage.message}" binding="#{sourcePage.message_Ref}">
    </h:outputText>
  </h:panelGroup>

</hx:scriptCollector>
</body>
</f:view>
</html>

このページに含まれているパネル・コントロールは、ターゲット・ページのパネルを置き換えるために使用されます。このケースでは、ページの JSF ハンドラー内の変数にバインドされている単一の出力フィールドが、パネルに含まれています。このページは、次のようになります。

エディター内のソース・ページと、パネル・コントロールを表示している「プロパティー」ビュー

このページと連携する JSF ハンドラー (sourcePage.egl) は、次のとおりです。

package jsfhandlers;

handler sourcePage type JSFHandler
  {onPreRenderFunction = onPreRender, 
   view = "sourcePage.jsp"} 
   
   message string = "No value set";

  function onPreRender()
    if (J2EELib.getQueryParameter("fruitName") != null)
      case (J2EELib.getQueryParameter("fruitName"))
        when ("bananas")
          message = "Bananas are a yellow tropical fruit.";
        when ("grapes")
          message = "Grapes grow on vines and can be made into wine.";
        when  ("apples")
          message = "Apples grow on trees in many parts of the world";
      end
    end
  end
end

最初に、JSF ハンドラーの onPreRenderFunction 関数が、AJAX 要求の結果として自らが呼び出されたかどうかを判別します。そうであれば、ページ上のテキスト・コントロールが JSF ハンドラーによって更新され、要求と一緒に渡されるパラメーターの値に基づいて、メッセージが表示されます。次に、この要求は、ソース・ページ上のパネルのコンテンツを使用して、ターゲット・ページ上のパネルのコンテンツを置き換えます。


フィードバック