[Visualforce]jQueryから簡単にVisualforceコンポーネントを操作しよう

2016年11月9日水曜日

jQuery Salesforce Visualforce

Visualforceページの動的なUIの実装にJavascriptライブラリのjQueryを使用していますが、しばしばjQueryからVisualforceコンポーネントの要素を操作する必要が出てきます。

コンポーネント ID へのアクセスのベストプラクティス

上のガイドにあるように$Componentグローバル変数でJavascriptからコンポーネントIDを取得することができます。
ただこの方法だと、例えばスクリプトをソースコードの上部や下部にまとめて記述して管理したい時などは、DOMの階層構造を意識して変数指定しないといけないので、意外と面倒です。

【操作対象のコンポーネントと同階層にスクリプトを記述する場合、対象のコンポーネントIDのみ指定すれば良いが…】
<apex:page standardController="Account">
  <apex:form id="form1">
    <apex:pageBlock id="pageBlock1">
      <apex:pageBlockSection id="pageBlockSection1">
        <apex:inputField id="accountName" value="{!account.name}"/>
        <script>
            $("input").change(function () {
                var input = $("#" + $.escapeSelector("{!$Component.accountName}"));
                alert(input.val());
            });
        </script>
      </apex:pageBlockSection>
    </apex:pageBlock>
  </apex:form>
  <apex:includeScript value="{!URLFOR($Resource.jQueryMinJS, '')}"/>
</apex:page>

【DOM階層の外にスクリプトを記述する場合、コンポーネントの階層をフルパスで指定しないといけない!】
<apex:page standardController="Account">
  <apex:form id="form1">
    <apex:pageBlock id="pageBlock1">
      <apex:pageBlockSection id="pageBlockSection1">
        <apex:inputField id="accountName" value="{!account.name}"/>
      </apex:pageBlockSection>
    </apex:pageBlock>
  </apex:form>
  <apex:includeScript value="{!URLFOR($Resource.jQueryMinJS, '')}"/>
  <script>
      $("input").change(function () {
          var input = $("#" + $.escapeSelector("{!$Component.form1.pageBlock1.pageBlockSection1.accountName}"));
          alert(input.val());
      });
  </script>
</apex:page>

そんな時は、jQueryセレクタの後方一致を使用するのが一番簡単でおススメです。

【jQueryのセレクタでコンポーネントIDの後方一致を行う】
<apex:page standardController="Account">
  <apex:form id="form1">
    <apex:pageBlock id="pageBlock1">
      <apex:pageBlockSection id="pageBlockSection1">
        <apex:inputField id="accountName" value="{!account.name}"/>
      </apex:pageBlockSection>
    </apex:pageBlock>
  </apex:form>
  <apex:includeScript value="{!URLFOR($Resource.jQueryMinJS, '')}"/>
  <script>
      $("input").change(function () {
          var input = $("[id$=accountName]");
          alert(input.val());
      });
  </script>
</apex:page>
操作対象のコンポーネントのIDが他のコンポーネントやHTML要素のIDと重複しないようご注意。