この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

JavaScript Remoting と静的 HTML

JavaScript Remoting と静的 HTML を組み合わせて、高度なパフォーマンスとユーザーインターフェースを Salesforce モバイルアプリケーションに匹敵させ、ユーザーの操作性を最大限に高めます。このアーキテクチャでは、JavaScript のページ要素のレンダリングが優先され、Visualforce タグの大半が回避されます。このオプションでは、開発者に最も高度な専門知識が求められ、標準の Visualforce または Visualforce と HTML の組み合わせよりも設定に多少時間がかかることがあります。Salesforce モバイルパックを使用すると、すぐに着手できるほか、最先端のモバイル Web アプリケーションテクノロジーを活用できます。

可能な場合は、Equality の会社の値に一致するように、含めない用語を変更しました。顧客の実装に対する影響を回避するために、一部の用語は変更されていません。

重要

この方法で設計された Visualforce ページは、要求-応答サイクルに対する制御が強化され、ページの再読み込みの代わりに JavaScript を使用したページの更新が優先されるため、標準の Visualforce の簡略化された自動機能の多くが使用されません。このアプローチはページのパフォーマンスを大幅に高めることができます。帯域幅が狭く、遅延の大きいワイヤレスネットワーク接続でモバイルデバイスを文字通りモバイルとして使用する場合は特に有効です。この方法の欠点は記述するコードが増えることで、Apex と Visualforce のほか、JavaScript、JavaScript Remoting、HTML5、ご使用のモバイルツールキット、CSS などの専門知識が必要です。一方、利点は、モバイル開発の最新鋭のツールを使用して作業できることと、この手法で構築したページにより、アプリケーションと完全統合するカスタム機能を最も適切で最も完璧な方法で組み込めることです。

デスクトップ用の Visualforce ページも、Salesforce モバイルアプリケーション用のページもこのアプローチで構築できます。さらに、このアプローチによるページは、スタイル設定をカスタマイズすれば 2 つの環境で共有することも可能です。ただし、Salesforce フルサイトのデザインに近づけることは容易なことではありません。最も重要なことは、設計するページの応答性を最大限に高められることと、幅広いデバイスやフォーム要素に適合させられることです。

このアプローチの Visualforce ページへの適用

Salesforce モバイルアプリケーションのページの作成にこのアプローチを採用する場合は、次の一般的なプロセスに従います。

  1. 任意の Salesforce Mobile パック (Salesforce で入手可) を静的リソースとして組織にインストールします。
  2. ページの docType を html-5.0 に設定します。標準のスタイルシートとヘッダーを無効にすることを強くお勧めします。次に例を示します。
    1<apex:page standardController="Warehouse__c" 
    2    extensions="WarehouseEditor"
    3    showHeader="false" standardStylesheets="false"
    4    docType="html-5.0">
  3. Visualforce リソースタグを使用して、選択したモバイルツールキットのスクリプトとスタイルをページに追加します。次に例を示します。
    1<apex:includeScript 
    2    value="{!URLFOR(
    3        $Resource.Mobile_Design_Templates,
    4        'Mobile-Design-Templates-master/common/js/
    5            jQuery2.0.2.min.js'
    6    )}"/>
  4. HTML5 とモバイルツールキットのタグおよび属性を使用して、ページのスケルトンを作成します。
  5. Javascript 関数を、ユーザー操作に応答するハンドラーとしてページに追加します。JavaScript Remoting を使用して、Apex @RemoteAction メソッドをコールします。このメソッドは、レコードの取得、DML の実行などを行います。
  6. ユーザーアクションやページ更新を処理する Javascript 関数を追加します。HTML 要素を JavaScript で構築してから、ページのスケルトンに追加して、ページ更新を実行します。

JavaScript Remoting と静的 HTML ページの例

次のサンプルコードは、ユーザーが倉庫レコードを編集できるようにする、Remoting と HTML を組み合わせた Visualforce ページを示します。編集機能は、JavaScript Remoting の要求に応答する @RemoteAction メソッドが設定されたコントローラー拡張によって提供されます。
1<apex:page standardController="Warehouse__c" extensions="WarehouseEditor"
2    showHeader="false" standardStylesheets="false"
3    docType="html-5.0" applyHtmlTag="false" applyBodyTag="false">
4
5    <!-- Include Mobile Toolkit styles and JavaScript -->
6    <apex:stylesheet 
7      value="{!URLFOR($Resource.Mobile_Design_Templates,
8      'Mobile-Design-Templates-master/common/css/app.min.css')}"/>
9    <apex:includeScript 
10      value="{!URLFOR($Resource.Mobile_Design_Templates,
11      'Mobile-Design-Templates-master/common/js/jQuery2.0.2.min.js')}"/>
12    <apex:includeScript 
13      value="{!URLFOR($Resource.Mobile_Design_Templates,
14      'Mobile-Design-Templates-master/common/js/jquery.touchwipe.min.js')}"/>
15    <apex:includeScript 
16      value="{!URLFOR($Resource.Mobile_Design_Templates,
17      'Mobile-Design-Templates-master/common/js/main.min.js')}"/>
18
19<head>
20<style>
21    html, body, p { font-family: sans-serif; }
22    input { display: block; }
23</style>
24
25<script>
26    $(document).ready(function(){
27        // Load the record
28        loadWarehouse();
29    });
30
31    // Utility; parse out parameter by name from URL query string
32    $.urlParam = function(name){
33        var results = new RegExp('[\\?&]' + name + '=([^&#]*)')
34            .exec(window.location.href);
35        return results[1] || 0;
36    }
37
38    function loadWarehouse() {
39        // Get the record Id from the GET query string
40        warehouseId = $.urlParam('id');
41
42        // Call the remote action to retrieve the record data
43        Visualforce.remoting.Manager.invokeAction(
44            '{!$RemoteAction.WarehouseEditor.getWarehouse}',
45            warehouseId,
46            function(result, event){;
47                if(event.status){
48                    console.log(warehouseId);
49                    $('#warehouse_name').text(result.Name);
50                    $('#warehouse_address').val(
51                      result.Street_Address__c);
52                    $('#warehouse_city').val(result.City__c);
53                    $('#warehouse_phone').val(result.Phone__c);
54                } else if (event.type === 'exception'){
55                    console.log(result);
56                } else {
57                    // unexpected problem...
58                }
59        });
60    }
61
62    function updateWarehouse() {
63        // Get the record Id from the GET query string
64        warehouseId = $.urlParam('id');
65
66        // Call the remote action to save the record data
67        Visualforce.remoting.Manager.invokeAction(
68            '{!$RemoteAction.WarehouseEditor.setWarehouse}',
69            warehouseId, $('#warehouse_address').val(),
70                $('#warehouse_city').val(), 
71                $('#warehouse_phone').val(),
72            function(result, event){;
73                if(event.status){
74                    console.log(warehouseId);
75                    $('#action_status').text('Record updated.');
76                } else if (event.type === 'exception'){
77                    console.log(result);
78                    $('#action_status').text(
79                      'Problem saving record.');
80                } else {
81                    // unexpected problem...
82                }
83        });
84    }
85
86</script>
87</head>
88
89<body>
90
91<div id="detailPage">
92    <div class="list-view-header" id="warehouse_name"></div>
93    <div id="action_status"></div>
94
95    <section>
96        <div class="content">
97            <h3>Warehouse Details</h3>
98            <div class="form-control-group">
99                <div class="form-control form-control-text">
100                    <label for="warehouse_address">
101                        Street Address</label>
102                    <input type="text" id="warehouse_address" />
103                </div>
104                <div class="form-control form-control-text">
105                    <label for="warehouse_city">City</label>
106                    <input type="text" id="warehouse_city" />
107                </div>
108                <div class="form-control form-control-text">
109                    <label for="warehouse_phone">Phone</label>
110                    <input type="text" id="warehouse_phone" />
111                </div>
112            </div>
113        </div>
114    </section>
115
116    <section class="data-capture-buttons one-buttons">
117        <div class="content">
118            <section class="data-capture-buttons one-buttons">
119                <a href="#" id="updateWarehouse"
120                    onClick="updateWarehouse();">save</a>
121            </section>
122        </div>
123    </section>
124</div> <!-- end detail page -->
125
126</body>
127
128</apex:page>
静的 HTML には、空のフォーム項目など、ページのシェルが用意されています。Javascript 関数は、レコードを読み込み、フォーム項目に入力して、更新されたフォームデータを Salesforce に送り返します。

このページは、Salesforce フルサイトでも使用できますが、Salesforce アプリケーションページとして設計されているため、通常の Visualforce ページとはデザインがかなり異なります。

JavaScript Remoting と静的 HTML コントローラーの例

モバイルページを作成する他の 2 つのアプローチとは異なり、Remoting + HTML のアプローチでは、標準のコントローラー機能を使用して Salesforce のデータを取得したり保存したりすることがありません。その代わりに、��ントローラー拡張またはカスタムコントローラーを作成して、ページに必要な @RemoteAction メソッドを追加します。上記のページをサポートする、簡略化されたコントローラー拡張は次のようになります。
1global with sharing class WarehouseEditor {
2
3    // Stub controller
4    // We're only using RemoteActions, so this never runs
5    public WarehouseEditor(ApexPages.StandardController ctl){ }
6
7    @RemoteAction
8    global static Warehouse__c getWarehouse(String warehouseId) {
9
10        // Clean up the Id parameter, in case there are spaces
11        warehouseId = warehouseId.trim();
12
13        // Simple SOQL query to get the warehouse data we need
14        Warehouse__c wh = [
15            SELECT Id, Name, Street_Address__c, City__c, Phone__c
16            FROM Warehouse__c
17            WHERE Id = :warehouseId];
18
19        return(wh);
20    }
21
22    @RemoteAction
23    global static Boolean setWarehouse(
24        String whId, String street, String city, String phone) {
25
26        // Get the warehouse record for the Id
27        Warehouse__c wh = WarehouseEditor.getWarehouse(whId);
28
29        // Update fields
30        // Note that we're not validating / sanitizing, for simplicity
31        wh.Street_Address__c = street.trim();
32        wh.City__c = city.trim();
33        wh.Phone__c = phone.trim();
34
35        // Save the updated record
36        // This should be wrapped in an exception handler
37        update wh;
38
39        return true;
40    }
41}