SharePoint JavaScript API を使用して SharePoint のデータを操作する
これは、SharePoint ホスト型の SharePoint アドインの開発の基本に関する記事のシリーズの 10 番目です。SharePoint アドインとこのシリーズの前の記事 (「SharePoint ホスト型の SharePoint アドインの作成を始める | 次の手順」にある記事) をよく理解しておいてください。
注:
SharePoint ホスト型アドインに関するこのシリーズを続けて学習してきた方は、このトピックでも引き続き使用できる Visual Studio ソリューションをお持ちです。 また、SharePoint_SP-hosted_Add-Ins_Tutorials でリポジトリをダウンロードし、BeforeJSOM.sln ファイルを開くこともできます。
SharePoint ホスト型 SharePoint アドインは、サーバー側コードを持つことはできませんが、JavaScript と SharePoint JavaScript クライアント オブジェクト モデル ライブラリを使用して、SharePoint ホスト型 SharePoint アドインで SharePoint コンポーネントを使用した、ビジネス ロジックとランタイムの操作を実行できます。 これを JSOM と呼びます。 最後が "M" になっている点に注意してください。 これを JSON (JavaScript Object Notation) と混同しないでください。 この記事では、JavaScript オブジェクト モデルを使用して、シアトルの新入社員 リストから古いアイテムを検索して削除します。
JavaScript とそれを呼び出すボタンの作成
このシリーズの最初のチュートリアルの次の手順が完了したことを確認します。
プロジェクトのルートからファイル /Pages/Default.aspx を開きます。 この生成されたファイルでは、主に SharePoint でホストされている 2 つのスクリプトの sp.runtime.js と sp.js のどちらか、または両方を読み込みます。 これらのファイルを読み込むマークアップは、
PlaceHolderAdditionalPageHead
という ID を持ったファイルの先頭付近にある Content コントロール内にあります。 このマークアップの値は、どのバージョンの Microsoft Office Developer Tools for Visual Studio を使用しているかによって異なります。この一連のチュートリアルでは、両方のファイルを読み込む必要があり、それらのファイルを
<SharePoint:ScriptLink>
タグではなく、通常の HTML<script>
タグで読み込む必要があります。PlaceHolderAdditionalPageHead
コントロール内の行<meta name="WebPartPageExpansion" content="full" />
の直前に、次の行があることを確認してください。<script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script> <script type="text/javascript" src="/_layouts/15/sp.js"></script>
次いで、2 ファイルのどちらかを読み込むマークアップが他にもないかファイルを検索し、重複するマークアップを削除します。 ファイルを保存して閉じます。
ソリューション エクスプローラーの スクリプト ノードでは、既に Add-in.js ファイルが存在する可能性があります。 存在しないが、App.jsファイルがある場合は、 App.js を右クリックし、 Add-in.js名前を変更します。 Add-in.jsまたはApp.jsがない場合は、次の手順で作成します。
[スクリプト] ノードを右クリックして、[追加]>[新しい項目]>[Web] の順に選択します。
[JavaScript ファイル] を選択して、Add-in.js という名前にします。
ASPX ページのコードを更新して、正しい JS ファイルを参照するようにします。以下を変更します。
<script type="text/javascript" src="../Scripts/App.js"></script>
へ
<script type="text/javascript" src="../Scripts/Add-in.js"></script>
Add-in.js を開き、記述がある場合にはそれを削除します。
次に行をファイルに追加します。
'use strict'; var clientContext = SP.ClientContext.get_current(); var employeeList = clientContext.get_web().get_lists().getByTitle('New Employees In Seattle'); var completedItems;
このコードについては、次の点に注意してください。
'use strict';
行により、JavaScript で不適切なプラクティスを不注意で使用した場合に、ブラウザーの JavaScript ランタイムが例外をスローします。clientContext
変数は、SharePoint Web サイトを参照するSP.ClientContext
オブジェクトを保持します。 すべての JSOM コードは、この型のオブジェクトを作成またはこの型のオブジェクトへの参照を取得することで開始されます。employeeList
変数は、リスト インスタンス [シアトルの新入社員] への参照を保持します。completedItems
変数は、スクリプトが削除するリストからのアイテムである、[オリエンテーション ステージ] フィールドが [完了] に設定されているアイテムを保持します。
クライアント ブラウザーと SharePoint サーバーの間のメッセージを最小化するために、JSOM はバッチ処理システムを使用します。 実際にサーバーにメッセージを送信 (および返信を受信) する関数は、
SP.ClientContext.executeQueryAsync
の 1 つだけです。executeQueryAsync
の呼び出しの間に発生する JSOM API への呼び出しはまとめられ、次にexecuteQueryAsync
が呼び出されたときに、バッチでサーバーに送信されます。 ただし、オブジェクトが以前のexecuteQueryAsync
の呼び出しでクライアントに渡されていないと、JSOM オブジェクトのメソッドを呼び出すことができません。スクリプトはリスト上の完了した各アイテムの
SP.ListItem.deleteObject
メソッドを呼び出すので、executeQueryAsync
の呼び出しを 2 回行う必要があります。1 つ目は完了したリスト アイテムのコレクションを取得し、2 つ目はdeleteObject
の呼び出しをバッチ処理して、実行のためにサーバーに送信します。最初に、サーバーからリスト アイテムを取得するメソッドを作成します。 次のコードをファイルに追加します。
function purgeCompletedItems() { var camlQuery = new SP.CamlQuery(); camlQuery.set_viewXml( '<View><Query><Where><Eq>' + '<FieldRef Name=\'OrientationStage\'/><Value Type=\'Choice\'>Completed</Value>' + '</Eq></Where></Query></View>'); completedItems = employeeList.getItems(camlQuery); }
これらの行がサーバーに送信され、そこで実行される場合、リスト アイテムのコレクションを作成しますが、スクリプトはそのコレクションをクライアントに渡す必要があります。 これは、
SP.ClientContext.load
関数の呼び出しを使用して実行されるため、次の行をメソッドの終わりに追加します。clientContext.load(completedItems);
executeQueryAsync
の呼び出しを追加します。 このメソッドには 2 つのパラメーターがあり、どちらもコールバック関数です。 1 つ目は、サーバーがバッチ内のコマンドをすべて正常に実行した場合に動作します。 2 つ目は、サーバーが何らかの理由で失敗した場合に動作します。 これらの 2 つの関数は、後の手順で作成します。 次の行をメソッドの終わりに追加します。clientContext.executeQueryAsync(deleteCompletedItems, onGetCompletedItemsFail);
最後に、次の行をメソッドの最後に追加します。
return false;
関数を呼び出す ASP.NET ボタンに
false
を返すことにより、ASP.NET ボタンの既定の動作をキャンセルします。これにより、ページがリロードされます。 ページをリロードすると、Add-in.js ファイルのリロードも実行されます。 次にこれがclientContext
オブジェクトを再初期化します。このリロードが、
executeQueryAsync
が要求を送信するタイミングと、SharePoint サーバーが応答を返すタイミングの間で完了した場合、元のclientContext
オブジェクトは応答を処理するために存在しません。 関数は、成功または失敗のいずれのコールバックも実行することなく停止します。 (正確な動作はブラウザーによって異なります)。ファイルに次の関数 (
deleteCompletedItems
) を追加します。 これは、purgeCompletedItems
関数が成功した場合に実行される関数です。 このコードについては、次の点に注意してください。SP.ListItem.get_id
メソッドは、リスト アイテムの ID を返します。 配列内のそれぞれの項目は、SP.ListItem
オブジェクトです。SP.List.getItemById
メソッドは、指定された ID を使用してSP.ListItem
オブジェクトを返します。SP.ListItem.deleteObject
メソッドは、executeQueryAsync
が呼び出されたときにサーバー上で削除されるリスト アイテムをマークします。 リスト アイテムは、サーバーから配列に送信されるコレクションからコピーしてからでなければ、削除できません。 スクリプトが各アイテムに対してdeleteObject
メソッドをwhile
ループで直接呼び出した場合、JavaScript は列挙の処理が行われている間に、コレクションの長さが変更されていることを通知するエラーをスローします。
アイテムは
deleteObject
の呼び出しがバンドルされ、サーバーに送信されるまではどこからも削除されないため、エラー メッセージがそのまま当てはまるわけではありません。しかし、JSOM は、サーバーで発生する可能性がある例外のスローを忠実に再現するよう設計されています (コレクションが列挙されている間、コードはコレクションのサイズを変更しません)。 ただし、配列は固定サイズであるため、アイテム上でdeleteObject
を呼び出すと、アイテムがリストから削除されますが、配列のサイズを変更することはありません。function deleteCompletedItems() { var itemArray = new Array(); var listItemEnumerator = completedItems.getEnumerator(); while (listItemEnumerator.moveNext()) { var item = listItemEnumerator.get_current(); itemArray.push(item); } var i; for (i = 0; i < itemArray.length; i++) { itemArray[i].deleteObject(); } clientContext.executeQueryAsync(onDeleteCompletedItemsSuccess, onDeleteCompletedItemsFail); }
ファイルに次の関数 (
onDeleteCompletedItemsSuccess
) を追加します。 これは、完了したアイテムが正常に削除された場合 (またはリストに完了したアイテムがない場合) に動作する関数です。location.reload(true);
行は、ページをサーバーからリロードします。 これは、ページのリスト ビュー Web パーツが、ページの更新まで引き続き完了したアイテムを表示するので便利です。 Add-in.js ファイルもリロードされますが、これは実行継続中の JavaScript 関数を中断する方法で動作するわけではないため、問題が発生しません。function onDeleteCompletedItemsSuccess() { alert('Completed orientations have been deleted.'); location.reload(true); }
次の 2 つの callback-on-failure 関数をファイルに追加します。
// Failure callbacks function onGetCompletedItemsFail(sender, args) { alert('Unable to get completed items. Error:' + args.get_message() + '\n' + args.get_stackTrace()); } function onDeleteCompletedItemsFail(sender, args) { alert('Unable to delete completed items. Error:' + args.get_message() + '\n' + args.get_stackTrace()); }
default.aspx ファイルを開き、ID
PlaceHolderMain
を持つasp:Content
要素を検索します。WebPartPages:WebPartZone
要素と 2 つあるasp:Hyperlink
要素の内の 1 つ目の間に、次のマークアップを追加します。OnClientClick
ハンドラーの値は単にpurgeCompletedItems()
ではなく、return purgeCompletedItems()
です。 関数から返されるfalse
は、ページをリロードしないよう ASP.NET に通知します。<p><asp:Button runat="server" OnClientClick="return purgeCompletedItems()" ID="purgecompleteditemsbutton" Text="Purge Completed Items" /></p>
プロジェクトを Visual Studio で再構築します。
アドインのテスト中にリスト アイテムの [オリエンテーション ステージ] を [完了] に手動で設定する必要を最小限にするには、(リスト テンプレート NewEmployeeOrientation の elements.xml ではなく) リスト インスタンス NewEmployeesInSeattle の elements.xml ファイルを開き、マークアップ
<Field Name="OrientationStage">Completed</Field>
を 1 つ以上のRow
要素の最後の子として追加します。Rows
要素は、次の例のようになります。<Rows> <Row> <Field Name="Title">Tom Higginbotham</Field> <Field Name="Division">Manufacturing</Field> <Field Name="OrientationStage">Completed</Field> </Row> <Row> <Field Name="Title">Satomi Hayakawa</Field> <Field Name="OrientationStage">Completed</Field> </Row> <Row> <Field Name="Title">Cassi Hicks</Field> </Row> <Row> <Field Name="Title">Lertchai Treetawatchaiwong</Field> </Row> </Rows>
アドインを実行してテストする
デバッグ時に、Visual Studio が使用するブラウザーのポップアップ ウィンドウを有効にします。
F5 キーを使用して、アドインを展開して実行します。 Visual Studio が、テスト用 SharePoint サイトにアドインを一時的にインストールして、すぐにアドインを実行します。
アドインのホームページが開きます。リストには、[オリエンテーション ステージ] が [完了] のアイテムが 1 つ以上あります。
図 1. 完了したアイテムの削除前のリスト
アドインの開始ページが読み込まれたら、[完成した項目のパージ] ボタンを選択します。 操作が成功した (失敗のメッセージが表示されない) 場合、[完了] のアイテムがすべて削除され、完了したオリエンテーションが削除されたことを示すポップアップ ウィンドウが表示されます。
ポップアップ ウィンドウを閉じます。 ページがリロードされ、[完了] のアイテムはリスト ビューの Web パーツに表示されなくなります。
図 2. 完了したアイテムの削除後のリスト
デバッグ セッションを終了するには、ブラウザー ウィンドウを閉じるか、Visual Studio でデバッグを停止します。 F5 キーを選択するたびに、Visual Studio は以前のバージョンのアドインを取り消し、最新のバージョンをインストールします。
このアドインと Visual Studio ソリューションは他の記事でも使用しますが、使用を終えた後は、アドインを最後に削除することをお勧めします。 ソリューション エクスプローラーでプロジェクトを右クリックして、[取り消し] を選択します。
次の手順
このシリーズの次の記事では、ホスト Web の SharePoint データを操作するアドイン Web のページに JavaScript を追加します。アドイン Web で JavaScript からのホスト Web データを使って作業する