web-dev-qa-db-ja.com

JavaScriptで使用できるようにJSFコンポーネントのIDを知るにはどうすればよいですか

問題:時々getElementByIdでjavascriptからコンポーネントにアクセスしたいが、idはJSFで動的に生成されるため、オブジェクトIDを取得する方法。これを行う方法について以下に回答します。


元の質問:以下のようなコードを使用したいです。 JavascriptでinputText JSFコンポーネントを参照するにはどうすればよいですか?

_<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://Java.Sun.com/jsf/html"
      xmlns:f="http://Java.Sun.com/jsf/core">
    <head>
       <title>Input Name Page</title>
        <script type="javascript" >
          function myFunc() {
            // how can I get the contents of the inputText component below          
            alert("Your email address is: " + document.getElementById("emailAddress").value);
          }
       </script>
    </head>
    <h:body>
        <f:view>
            <h:form>
                Please enter your email address:<br/>
                <h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>
                <h:commandButton onclick="myFunc()" action="results" value="Next"/>
            </h:form>
        </f:view>
    </h:body>
</html>
_

Update:この投稿 JSF2.0のクライアント識別子 は次のようなテクニックの使用について説明しています:

_<script type="javascript" >
  function myFunc() {
    alert("Your email address is: " + document.getElementById("#{myInptTxtId.clientId}").value);
  }
</script>

<h:inputText id="myInptTxtId" value="backingBean.emailAddress"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
_

idコンポーネントの属性inputTextは、上記の例で、_#{myInptTxtId}_を使用してELでアクセスできるオブジェクトを作成することを提案します。この記事では、JSF 2.0が引数なしのgetClientId()メソッドをUIComponentクラスに追加することを述べています。これにより、上記で提案した_#{myInptTxtId.clientId}_コンストラクトを使用して、コンポーネントの実際に生成されたIDを取得できます。

私のテストではこれは機能しませんが。誰でも確認/拒否できます。以下に示す回答には、上記の手法にはない欠点があります。したがって、上記の手法が実際に機能するかどうかを知るのは良いことです。

42
ftravers

Answer:これが、私が一番幸せなテクニックです。コンポーネントのIDを把握するためにtoo多くの奇妙なことをする必要はありません。これの重要な点は、実際のjustではなく、ページのどこからでもコンポーネントのidを知ることができることです。コンポーネント自体。これが重要です。ボタンを押して、javascript関数を起動すると、起動したコンポーネントだけでなく、any他のコンポーネントにアクセスできるはずです。

このソリューションでは「右クリック」を必要とせず、IDを確認できます。 idは動的に生成されるため、このタイプのソリューションは脆弱です。ページを変更する場合は、毎回そのナンセンスを実行する必要があります。

  1. コンポーネントをバッキングBeanにバインドします。

  2. バインドされたコンポーネントをどこでも参照できます。

そのため、これを行う方法のサンプルを次に示します。

前提:* .xhtmlページ(* .jspの場合もあります)があり、バッキングBeanを定義しました。私もJSF 2.0を使用しています。

* .xhtmlページ

<script>
  function myFunc() {
    var inputText = document.getElementById("#{backBean.emailAddyInputText.clientId}")                 
    alert("The email address is: " + inputText.value );
  }
</script>

<h:inputText binding="#{backBean.emailAddyInputText}"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>

BackBean.Java

UIInput emailAddyInputText;

このプロパティのゲッター/セッターも必ず作成してください。

6
ftravers

JSFが生成されたHTML出力で割り当てたとおりに、IDを正確に使用する必要があります。 Webブラウザでページを右クリックし、ソースの表示を選択します。これはまさにJSが見るHTMLコードです(JSはwebbrowserで実行され、HTML DOMツリーでインターセプトします)。

与えられた

<h:form>
    <h:inputText id="emailAddresses" ... />

次のようになります。

<form id="j_id0">
    <input type="text" id="j_id0:emailAddress" ... />

ここで、j_id0は、生成されたHTML <form>要素の生成されたIDです。

JSFが自動生成しないように、すべてのJSF NamingContainer コンポーネントに固定idを指定する方が望ましいです。 <h:form>はそのうちの1つです。

<h:form id="formId">
    <h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>

この方法では、フォームはj_id0のような自動生成IDを取得せず、入力フィールドはformId:emailAddressの固定IDを取得します。その後、JSでそのように参照できます。

var input = document.getElementById('formId:emailAddress');

その時点から、通常どおりJSコードを使用し続けることができます。例えば。 input.valueを介して値を取得します。

こちらもご覧ください:


Updateアップデートごと:あなたはブログ記事を誤解しました。特別な#{component}参照は、EL式が評価されるcurrentコンポーネントを参照し、これはコンポーネント自体の属性の内部でのみ機能します。必要なものはすべて、次のようにして達成することもできます。

var input = document.getElementById('#{emailAddress.clientId}');

with(ビューへのbindingに注意してください、 絶対にそうではありません Beanにバインドする必要があります)

<h:inputText binding="#{emailAddress}" />

しかし、それは見苦しいです。生成されたHTML DOM要素をJavaScript this参照として関数に渡す次のアプローチを使用する方が良い

<h:inputText onclick="show(this)" />

function show(input) {
    alert(input.value);
}

JQueryを使用している場合は、スタイルクラスをマーカーインターフェイスとして使用して抽象化することにより、さらに一歩進めることもできます。

<h:inputText styleClass="someMarkerClass" />

$(document).on("click", ".someMarkerClass", function() {
    var $input = $(this);
    alert($input.val());
});
56
BalusC

IDは動的に生成されるため、j_id123のようなIDを避けるために、すべての親要素の名前を定義する必要があります。

JQueryを使用して要素を選択する場合は、コロンの前に二重スラッシュを使用する必要があることに注意してください。

    jQuery("my-form-id\\:my-text-input-block\\:my-input-id")

の代わりに:

    jQuery("my-form-id:my-text-input-block:my-input-id")

Richfacesの場合、jsfページでel式を使用できます。

    #{rich:element('native-jsf-input-id')} 

javascript要素を選択するには、たとえば:

    #{rich:element('native-jsf-input-id')}.value = "Enter something here";
4
Ivan Bochko

これが生成されたときにHTMLソースを表示し、IDの設定を確認できるため、JavaScriptでそれを使用できます。フォーム内にあるため、フォームIDを先頭に追加している可能性があります。

0
planetjones

これはJSFの方法ではないことを知っていますが、IDの痛みを避けたい場合は、セレクターに特別なCSSクラスを設定できます。誰かがクラス名を読んだときに、それがこの目的のために使用されたことが明確になるように、適切な名前を使用してください。

<h:inputText id="emailAddresses" class="emailAddressesForSelector"...

JavaScriptで:

jQuery('.emailAddressesForSelector');

もちろん、クラス名の一意性を手動で管理する必要があります。再利用可能なコンポーネントでこれを使用しない限り、これは維持可能であると思います。その場合、規則を使用してクラス名を生成できます。

0