Salesforce データの操作

学習の目的

この単元を完了すると、次のことができるようになります。

  • SLDS データテーブルコンポーネントとフォームコンポーネントがどのように機能するか説明する。
  • JavaScript リモートオブジェクトを使用して動的データを表示するリストビューページを作成する。

データの追加

正直に言うと、データが含まれていなければ、Web アプリケーションはそれほど面白いものではありません。この単元では、実際のリストビューを作成し、そこに開発者組織のサンプルプルデータを入力します。

JavaScript リモートオブジェクトを使用して Salesforce データにアクセスしますが、JavaScript Remoting を使用することもできます。Apex タグはまだ Design System でサポートされていませんが、Trailhead の Visualforce ビジュアルデザインの考慮事項に関する単元で、新しい Lightning UI に見えるように従来のコードをスタイル設定するオプションについて説明しています。

この単元の JavaScript は Design System の範疇外ですが、JavaScript によって一定の主要なコンポーネントが生彩を帯び、その使用法がわかるようになります。さらに面白みも増大します。

データテーブルコンポーネント

データテーブルコンポーネントは、Lightning UI のスタイル設定で表形式のデータを表示する、HTML テーブルの拡張バージョンです。データテーブルは、<table> タグに slds-table クラスを適用して作成します。境界線を適用する場合は slds-table_bordered クラスを使用します。

2 列とヘッダー行のあるテーブルの例を次に示します。なじみのある HTML マークアップに Design System クラスが適用されています。この例でも、CSS はどこにも使用されていません。入力については心配いりません。次のセクションで、実際のデータテーブルに Salesforce データを動的に入力します。

<table class="slds-table slds-table_bordered slds-table_cell-buffer slds-no-row-hover">
 <thead>
 <tr class="slds-text-heading_label">
 <th scope="col">Account ID</th>
 <th scope="col">Account name</th>
 </tr>
 </thead>
 <tbody>
 <tr>
 <th scope="row">123</th>
 <td>Account 1</td>
 </tr>
 <tr>
 <th scope="row">456</th>
 <td>Account 2</td>
 </tr>
 </tbody>
</table>

コピー

データテーブルへの動的データの入力

前述のとおり、このリリースでは、Design System はページのレイアウトやデータにアクセスするのに、組み込みの Visualforce コンポーネント (<apex:*><chatter:*> など) の使用をサポートしていません。これには留意してください。従来の Visualforce ページに Design System を適用しても、UI が瞬時に変換されることはありません。

今のところは、リモートオブジェクト、JavaScript Remoting、または REST API を使用して、Design System マークアップに基づいて Visualforce ページから Salesforce データにアクセスすることをお勧めします。このチュートリアルの例では、リモートオブジェクトを採用します。ここでは、Design System に焦点を当てているので、完全なコードを提供しますが、リモートオブジェクト部分については詳しく説明しません。これらのデータアクセス技術についての詳細は、後述のリソースを参照してください。

では始めましょう。手をウォームアップしてください。これからコードを記述します。リストビューページを新しい Visualforce ページとしてコピーし、Trailhead_SLDS_Listview_Data という名前を付けます。Salesforce 組織の取引先レコードをリモートオブジェクトとして接続します。次のコードを </head> タグと <body> タグの間に挿入します。

</head>
<apex:remoteObjects>
 <apex:remoteObjectModel name="Account" fields="Id,Name,LastModifiedDate"/>
</apex:remoteObjects>
<body>

コピー

次に、<ul> プレースホルダを、slds-p-vertical_medium クラスの縦パディングを指定した account-list <div> に 置き換えます。JavaScript によってすぐに、この <div> の空のコンテンツが完全に表示されるデータテーブルに置き換えられます。

<!-- PRIMARY CONTENT WRAPPER -->
<div class="myapp">
 <!-- ACCOUNT LIST TABLE -->
 <div id="account-list" class="slds-p-vertical_medium"></div>
 <!-- / ACCOUNT LIST TABLE -->
</div>
<!-- / PRIMARY CONTENT WRAPPER -->

コピー

最後に、ファイルの末尾の </body> 終了タグの前に次の JavaScript コードを追加します各自のコードでは、この JavaScript を個別の静的リソースに配置することをお勧めします。

<!-- JAVASCRIPT -->
<script>
 (function() {
 var account = new SObjectModel.Account();
 var outputDiv = document.getElementById('account-list');
 var updateOutputDiv = function() {
 account.retrieve(
 { orderby: [{ LastModifiedDate: 'DESC' }], limit: 10 },
 function(error, records) {
 if (error) {
 alert(error.message);
 } else {
 // create data table
 var dataTable = document.createElement('table');
 dataTable.className = 'slds-table slds-table_bordered slds-table_cell-buffer slds-no-row-hover';
 // add header row
 var tableHeader = dataTable.createTHead();
 var tableHeaderRow = tableHeader.insertRow();
 var tableHeaderRowCell1 = tableHeaderRow.insertCell(0);
 tableHeaderRowCell1.appendChild(document.createTextNode('Account name'));
 tableHeaderRowCell1.setAttribute('scope', 'col');
 tableHeaderRowCell1.setAttribute('class', 'slds-text-heading_label');
 var tableHeaderRowCell2 = tableHeaderRow.insertCell(1);
 tableHeaderRowCell2.appendChild(document.createTextNode('Account ID'));
 tableHeaderRowCell2.setAttribute('scope', 'col');
 tableHeaderRowCell2.setAttribute('class', 'slds-text-heading_label');
 // build table body
 var tableBody = dataTable.appendChild(document.createElement('tbody'))
 var dataRow, dataRowCell1, dataRowCell2, recordName, recordId;
 records.forEach(function(record) {
 dataRow = tableBody.insertRow();
 dataRowCell1 = dataRow.insertCell(0);
 recordName = document.createTextNode(record.get('Name'));
 dataRowCell1.appendChild(recordName);
 dataRowCell2 = dataRow.insertCell(1);
 recordId = document.createTextNode(record.get('Id'));
 dataRowCell2.appendChild(recordId);
 });
 if (outputDiv.firstChild) {
 // replace table if it already exists
 // see later in tutorial
 outputDiv.replaceChild(dataTable, outputDiv.firstChild);
 } else {
 outputDiv.appendChild(dataTable);
 }
 }
 }
 );
 }
 updateOutputDiv();
 })();
</script>
<!-- / JAVASCRIPT -->

コピー

このコードは、リモートオブジェクト経由で取引先レコードにアクセスし、updateOutputDiv() 関数がそのレコードを使用して account-list <div> 内にテーブルを表示します。

テーブルは、slds-scrollable_x ユーティリティクラスが指定された div にラップされています。これで、データの幅が画面に収まらないときには、テーブルに水平スクロールバーが表示されます。

ページをプレビューすると、次のようになります。あなたの取引先名はもっと工夫してください。

入力されたデータテーブル

入力フォームの追加

もっと改良することができます。テーブルを対話型にしてみましょう。このステップでは、ユーザが新しい取引先を作成できる Visualforce ページの上部に基本フォームを追加します。取引先リストの上の主コンテンツラッパー内に次のコードを挿入します。

<!-- PRIMARY CONTENT WRAPPER -->
<div class="myapp">
 <!-- CREATE NEW ACCOUNT -->
 <div aria-labelledby="newaccountform">
 <!-- CREATE NEW ACCOUNT FORM -->
 <form class="slds-form_stacked" id="add-account-form">
 <!-- BOXED AREA -->
 <fieldset class="slds-box slds-theme_default slds-container_small">
 <legend id="newaccountform" class="slds-text-heading_medium slds-p-vertical_medium">Add a new account</legend>
 <div class="slds-form-element">
 <label class="slds-form-element__label" for="account-name">Name</label>
 <div class="slds-form-element__control">
 <input id="account-name" class="slds-input" type="text" placeholder="New account"/>
 </div>
 </div>
 <button class="slds-button slds-button_brand slds-m-top_medium" type="submit">Create Account</button>
 </fieldset>
 <!-- / BOXED AREA -->
 </form>
 <!-- CREATE NEW ACCOUNT FORM -->
 </div>
 <!-- / CREATE NEW ACCOUNT -->
</div>
<!-- / PRIMARY CONTENT WRAPPER -->
...

コピー

ここでも新しいマークアップが多く使用されています。順を追って確認していきましょう。

フォームマークアップは、<div> ラッパーにラップされており、ページ構造を追加します。

次に、別の Design System コンポーネントであるフォームを見つけました。Design System は、horizontal (横方向)、stacked (積み上げ)、compound (複合) を含む、複数のフォームレイアウトのスタイル設定を提供しています。この例では、slds-form_stacked クラスが指定された <form> に縦方向の積み上げレイアウトを適用します。

フォーム内には 2 番目のラッパー要素 <fieldset> があり、slds-boxslds-theme_defaultslds-container_small という 3 つのクラスが指定されています。これら 3 つのクラスは、きちんと整理されて見えるように、白いボックスの小さな領域を作成します。<legend> タグのタイトルは、ボックスの上部にタイトルを追加します。<legend> 要素の id 属性は、アクセシビリティのラッパー <div> 要素の aria-labelledby 属性に対応します。

ラベルと入力の各ペアが slds-form-element が指定されたラッパー div 内に配置され、最適なスペーシングを提供します。ラッパー内の <label> 要素には slds-form-element__label クラスが指定されています。slds-form-element__control クラスが指定された別のラッパー <div> 内に <input> 項目が配置され、これも最適なスペーシングを提供します。<input> 項目自体には、slds-input クラスが指定されています。

フォームにこのマークアップとクラスをすべて追加すると、Lightning (とほぼ同じ) スタイル設定が自動的に適用されます。クラスさえ追加されれば、CSS はすべてこちらにお任せください。

ユーザがフォームを送信できるようにしなければなりません。そのために、slds-button クラス、slds-button_brand クラス、slds-m-top_medium クラスが指定された <button> が含まれています。もうこれらについての説明は不要でしょうが、必要であれば、リンク先のドキュメントを参照してください。

最後に、フォームにデータを実際に保存する方法を結び付ける必要があります。これは、リモートオブジェクトを使用する createAccount() JavaScript 関数を使用して行います。updateOutputDiv() 関数の下に次を追加します。

var accountForm = document.getElementById('add-account-form');
var accountNameField = document.getElementById('account-name');
var createAccount = function() {
 var account = new SObjectModel.Account();
 account.create({ Name: accountNameField.value }, function(error, records) {
 if (error) {
 alert(error.message);
 } else {
 updateOutputDiv();
 accountNameField.value = '';
 }
 });
}
accountForm.addEventListener('submit', function(e) {
 e.preventDefault();
 createAccount();
});

コピー

フォームを送信すると createAccount() 関数がコールされ、この関数がリモートオブジェクトをコールし、新しいレコードが作成されます。

ページをプレビューし、取引先をいくつか追加してみてください。テーブルは有効な取引先名を使用してフォームを送信するたびに自動更新されます。

入力されたデータテーブル

なかなかの単元でしたね。すべてが正常に機能した場合は、ウイニングランをしてください。あなたはそれに値します!

このユニットでは、データテーブルおよびフォームコンポーネントについて学習し、リモートオブジェクトを使用してコンポーネントを実際のデータに結び付けました。でも何か忘れていませんか? Lightning のスタイル設定を適用したテーブルがありましたが、ちょっとさえないテーブルでした。ページに活気をもたらすアイコンや画像が必要だと思いませんか? 次のセクションでは、ページにふさわしいデザインについて説明します。

リソース