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 とそれを呼び出すボタンの作成

  1. このシリーズの最初のチュートリアルの次の手順が完了したことを確認します。

    プロジェクトのルートからファイル /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 ファイルのどちらかを読み込むマークアップが他にもないかファイルを検索し、重複するマークアップを削除します。 ファイルを保存して閉じます。

  2. ソリューション エクスプローラースクリプト ノードでは、既に Add-in.js ファイルが存在する可能性があります。 存在しないが、App.jsファイルがある場合は、 App.js を右クリックし、 Add-in.js名前を変更します。 Add-in.jsまたはApp.jsがない場合は、次の手順で作成します。

    1. [スクリプト] ノードを右クリックして、[追加]>[新しい項目]>[Web] の順に選択します。

    2. [JavaScript ファイル] を選択して、Add-in.js という名前にします。

    3. ASPX ページのコードを更新して、正しい JS ファイルを参照するようにします。以下を変更します。

      <script type="text/javascript" src="../Scripts/App.js"></script>
      

      <script type="text/javascript" src="../Scripts/Add-in.js"></script>
      
  3. Add-in.js を開き、記述がある場合にはそれを削除します。

  4. 次に行をファイルに追加します。

    '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 変数は、スクリプトが削除するリストからのアイテムである、[オリエンテーション ステージ] フィールドが [完了] に設定されているアイテムを保持します。
  5. クライアント ブラウザーと 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);
    }
    
  6. これらの行がサーバーに送信され、そこで実行される場合、リスト アイテムのコレクションを作成しますが、スクリプトはそのコレクションをクライアントに渡す必要があります。 これは、 SP.ClientContext.load 関数の呼び出しを使用して実行されるため、次の行をメソッドの終わりに追加します。

    clientContext.load(completedItems);
    
  7. executeQueryAsync の呼び出しを追加します。 このメソッドには 2 つのパラメーターがあり、どちらもコールバック関数です。 1 つ目は、サーバーがバッチ内のコマンドをすべて正常に実行した場合に動作します。 2 つ目は、サーバーが何らかの理由で失敗した場合に動作します。 これらの 2 つの関数は、後の手順で作成します。 次の行をメソッドの終わりに追加します。

    clientContext.executeQueryAsync(deleteCompletedItems, onGetCompletedItemsFail);
    
  8. 最後に、次の行をメソッドの最後に追加します。

    return false;
    

    関数を呼び出す ASP.NET ボタンに false を返すことにより、ASP.NET ボタンの既定の動作をキャンセルします。これにより、ページがリロードされます。 ページをリロードすると、Add-in.js ファイルのリロードも実行されます。 次にこれが clientContext オブジェクトを再初期化します。

    このリロードが、executeQueryAsync が要求を送信するタイミングと、SharePoint サーバーが応答を返すタイミングの間で完了した場合、元の clientContext オブジェクトは応答を処理するために存在しません。 関数は、成功または失敗のいずれのコールバックも実行することなく停止します。 (正確な動作はブラウザーによって異なります)。

  9. ファイルに次の関数 (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);
    }
    
  10. ファイルに次の関数 (onDeleteCompletedItemsSuccess) を追加します。 これは、完了したアイテムが正常に削除された場合 (またはリストに完了したアイテムがない場合) に動作する関数です。

    location.reload(true); 行は、ページをサーバーからリロードします。 これは、ページのリスト ビュー Web パーツが、ページの更新まで引き続き完了したアイテムを表示するので便利です。 Add-in.js ファイルもリロードされますが、これは実行継続中の JavaScript 関数を中断する方法で動作するわけではないため、問題が発生しません。

    function onDeleteCompletedItemsSuccess() {
      alert('Completed orientations have been deleted.');
      location.reload(true);
    }
    
  11. 次の 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());
    }
    
  12. default.aspx ファイルを開き、ID PlaceHolderMain を持つ asp:Content 要素を検索します。

  13. 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>
    
  14. プロジェクトを Visual Studio で再構築します。

  15. アドインのテスト中にリスト アイテムの [オリエンテーション ステージ][完了] に手動で設定する必要を最小限にするには、(リスト テンプレート NewEmployeeOrientationelements.xml ではなく) リスト インスタンス NewEmployeesInSeattleelements.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>
    

アドインを実行してテストする

  1. デバッグ時に、Visual Studio が使用するブラウザーのポップアップ ウィンドウを有効にします。

  2. F5 キーを使用して、アドインを展開して実行します。 Visual Studio が、テスト用 SharePoint サイトにアドインを一時的にインストールして、すぐにアドインを実行します。

  3. アドインのホームページが開きます。リストには、[オリエンテーション ステージ][完了] のアイテムが 1 つ以上あります。

    図 1. 完了したアイテムの削除前のリスト

    2 つのアイテムが [完了] に設定されている [オリエンテーション ステージ] 列を持った

  4. アドインの開始ページが読み込まれたら、[完成した項目のパージ] ボタンを選択します。 操作が成功した (失敗のメッセージが表示されない) 場合、[完了] のアイテムがすべて削除され、完了したオリエンテーションが削除されたことを示すポップアップ ウィンドウが表示されます。

  5. ポップアップ ウィンドウを閉じます。 ページがリロードされ、[完了] のアイテムはリスト ビューの Web パーツに表示されなくなります。

    図 2. 完了したアイテムの削除後のリスト

    前より 2 つアイテムが少なく、「オリエンテーション ステージ」が「完了」に設定されているアイテムがない「シアトルの新入社員」一覧。

  6. デバッグ セッションを終了するには、ブラウザー ウィンドウを閉じるか、Visual Studio でデバッグを停止します。 F5 キーを選択するたびに、Visual Studio は以前のバージョンのアドインを取り消し、最新のバージョンをインストールします。

  7. このアドインと Visual Studio ソリューションは他の記事でも使用しますが、使用を終えた後は、アドインを最後に削除することをお勧めします。 ソリューション エクスプローラーでプロジェクトを右クリックして、[取り消し] を選択します。

次の手順

このシリーズの次の記事では、ホスト Web の SharePoint データを操作するアドイン Web のページに JavaScript を追加します。アドイン Web で JavaScript からのホスト Web データを使って作業する