クライアント側のレンダリングを使用して位置情報フィールドの種類を拡張する

クライアント側レンダリングを使用して SharePoint の位置情報フィールド型をプログラムでカスタマイズする方法について説明します。

SharePoint では、ジオロケーションと呼ばれる新しいフィールド型が導入されており、位置情報を使用して SharePoint リストに注釈を付けることができます。 Geolocation 型の列では、位置情報を緯度と経度の座標のペアとして 10 進度で入力したり、W3C Geolocation API を実装している場合はブラウザーからユーザーの現在の位置の座標を取得したりできます。 [位置情報] フィールドの詳細については、「 SharePoint での場所とマップの機能の統合」を参照してください。

位置情報フィールド の種類は、SharePoint のリストまたはドキュメント ライブラリの既定のコンテンツ タイプでは使用できません。 位置情報フィールドの種類は SharePoint に含まれていますが、リストの列の作成ページには表示されません。Geolocation フィールド型をプログラムで追加する必要があります。 詳細については、「 方法: SharePoint でプログラムを使用して Geolocation 列をリストに追加する」を参照してください。

SharePointに地理位置情報フィールド型を追加したら、Bing Maps を使用して地図を表示するのに使用できます。 組み込みの地理位置情報フィールドは Bing Maps でしか表示できません。 ただし、地理位置情報フィールドを親フィールド型として使用してユーザー設定フィールドを作成できます。 ユーザー設定レンダリングはクライアント側のレンダリング機構にある JSLink プロパティによって実現します。 クライアント側のレンダリング機構は SharePointに導入されています。 詳細については、「 [方法] クライアント側レンダリングを使用して、フィールド タイプをカスタマイズする」を参照してください。

注:

JSLink プロパティは、アンケートの一覧またはイベントの一覧ではサポートされていません。 SharePoint の予定表は、イベント リストです。

このセクションの手順では、クライアント側レンダリングを使用して、位置情報フィールドの種類から派生するカスタム フィールドを作成します。

ユーザー設定地理位置情報フィールドの作成の前提条件

次のものが必要です。

  • SharePointが実行されているサーバー
  • Microsoft Visual Studio 2012
  • Office Developer Tools for Visual Studio 2012
  • SharePoint リストへのアクセスと、列を追加する権限

地理位置情報フィールドのカスタマイズ方法を理解するための中心概念

表 1. 位置情報フィールド型を拡張するための主要な概念

記事のタイトル 説明
SharePoint でロケーションとマップ機能を組み込む
新しい地理位置情報フィールドを使用し、独自の地理位置情報ベースのフィールド型を作成して、SharePoint リストとロケーションベースの Web およびモバイル アプリケーションに位置情報と地図を統合する方法を確認します。
[方法] クライアント側レンダリングを使用して、フィールド タイプをカスタマイズする
SharePointに導入された新しいクライアント側レンダリングの詳細について確認します。
[方法] SharePoint で地理位置情報列をプログラムでリストに追加する
地理位置情報列を SharePointのリストにプログラムで追加する方法を確認します。

ステップ 1: Visual Studio プロジェクトの設定

カスタム フィールド プロジェクトを設定するには

  1. SharePoint がインストールされているコンピューターで Visual Studio 2012 を起動します。

  2. [ 新しいプロジェクト] ダイアログ ボックスの [ インストールされたテンプレート] で、[ Visual C#]、[ Office SharePoint]、[ SharePoint ソリューション] を順に選択します。 [ SharePoint] プロジェクトの種類を選択します。 図 1 は、Visual Studio 2012 の [ SharePoint プロジェクト] テンプレートの場所を示しています。 セキュリティで保護されたソリューションではなく [ ファーム ソリューション] にします。

    図 1. Visual Studio の SharePoint プロジェクト テンプレート

    SharePoint プロジェクトの Visual Studio テンプレート

  3. プロジェクトの名前を指定します。 この例では CustomGeolocationField を使用します。 次に、[ OK] をクリックします。

  4. SharePoint カスタマイズ ウィザードで、新しいユーザー設定フィールド型を展開する SharePoint サイトの URL を入力します。

  5. ソリューション エクスプローラーでプロジェクト名 (この例では [ CustomGeolocationField]) のショートカット メニューを開き、[ 追加]、[ 新しいアイテム] を順に選択します。

  6. [ 新しいアイテムの追加] ダイアログ ボックスの [ コード] テンプレートで、[ クラス] を選択し、クラスの名前 (この例では CustomGeolocationField.cs) を指定します。

  7. ソリューション エクスプローラーでプロジェクト名のショートカット メニューを開き、[ 追加]、[ SharePoint mapped folder] (SharePoint のマップされたフォルダー) を順に選択します。

  8. [Add SharePoint Mapped Folder] (SharePoint のマップされたフォルダーの追加) ダイアログ ボックスで、ツリー コントロールを使用してフォルダーを [TEMPLATE\LAYOUTS] に割り当て、[OK] をクリックします。

  9. ソリューション エクスプローラーで、プロジェクト名ではなく新しい [LAYOUTS] フォルダーのショートカット メニューを開き、[追加]、[新しいアイテム] を順に選択します。

  10. [ 新しいアイテムの追加] ダイアログ ボックスで [ Visual C#]、[ Web] を順に選択し、[ テンプレート] の下の [ Javascript ファイル] を選択します。

  11. [ 名前] ボックスでファイルの名前 (この例では CustomGeolocationField) を指定し、[ 追加] を選択します。

  12. ステップ 8 を繰り返して、別の SharePoint のマップされたフォルダーを作成し、それを [TEMPLATE\XML] に割り当てます。 次に、[OK] を選択します。

  13. ソリューション エクスプローラーで、プロジェクト名ではなく新しい [ XML] フォルダーのショートカット メニューを開き、[ 追加]、[ 新しいアイテム] を順に選択します。

  14. [ 新しいアイテムの追加] ダイアログ ボックスで [ Visual C#]、[ データ] を順に選択し、[ テンプレート] の下の [ XML ファイル] を選択します。

  15. [ 名前 ] ボックスで、ファイルの名前 (この例 ではusesfldtypes_CustomGeolocationControl.xml) を指定し、[ 追加 ] ボタンを選択します。

ステップ 2: ユーザー設定フィールド クラスの作成

フィールド クラスは、そのインスタンスによって、ユーザー設定フィールド型に基づいく特定のフィールドを表すことができるクラスのことです。 このクラスは、 SPField または、そこから派生した SharePoint Foundation のクラスのいずれかを継承する必要があります。 地理位置情報フィールド型の拡張またはカスタマイズを実現するには、このクラスが SPFieldGeolocation を継承している必要があります。 フィールド型の作成方法の詳細については、「[ウォークスルー] ユーザー設定フィールド型を作成する」を参照してください。

注:

この例では、クラスおよびソリューションに CustomGeolocationField という名前が付けられています。Visual Studio プロジェクトの作成時にクラスおよびプロジェクトの名前を指定することができます。

カスタム フィールドを作成するには

  1. CustomGeolocationField.cs ファイルを開き、次のように ディレクティブを using 追加します。

    using System;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.WebControls;
    
  2. 名前空間 CustomGeolocationFieldが であることを確認します。

  3. クラスに という名前 CustomGeolocationFieldが付いていることを確認し、その宣言を から SPFieldGeolocation継承するように変更します。 クラスに必要な次のコンストラクターを追加します。

    public class CustomGeolocationField : SPFieldGeolocation
    {
        /// <summary>
        /// Create an instance of CustomGeolocationField object.
        /// </summary>
        /// <param name="fields">Field collection</param>
        /// <param name="fieldName">Name of the field</param>
        ///
        public CustomGeolocationField(SPFieldCollection fields, string fieldName)
            : base(fields, fieldName)
        {
        }
    
        /// <summary>
        /// Create an instance of CustomGeolocationField object.
        /// </summary>
        /// <param name="fields">Field collection</param>
        /// <param name="typeName">type name of the field</param>
        /// <param name="displayName">display name of the field</param>
    
        public CustomGeolocationField(SPFieldCollection fields, string typeName, string displayName)
            : base(fields, typeName, displayName)
        {
        }
    
  4. メソッドの次のオーバーライドを JSLink クラスに追加します。 CustomGeolocationControl.js は次のステップで作成する JavaScript ファイルです。 独自の JavaScript ファイルを指定することによって、Bing Maps の既定のレンダリングをオーバーライドします。 このメソッドをオーバーライドしない場合は、Bing Maps の既定のレンダリングが実行されます。 プロパティは JSLink SharePoint で導入されています。 プロパティの JSLink 詳細については、「 方法: クライアント側のレンダリングを使用してフィールドの種類をカスタマイズする」を参照してください。

    /// <summary>
    /// Override JSLink property.
    /// </summary>
    
    public override string JSLink
    {
        get
        {
            return "CustomGeolocationControl.js";
        }
        set
        {
            base.JSLink = value;
        }
    }
    
  5. メソッドは GetFieldValue() 、指定した値をフィールド型の値に変換します。 メソッドの GetFieldValue() 詳細については、「 GetFieldValue(String)」を参照してください。 メソッドの次のオーバーライドを GetFieldValue() クラスに CustomGeolocationField 追加します。

    /// <summary>
    /// get the field values
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    
    public override object GetFieldValue(string value)
    {
        return base.GetFieldValue(value);
    }
    
  6. GetValidatedString メソッドの次のオーバーライドを クラスにCustomGeolocationField追加します。

    /// <summary>
    /// get validated string
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    
    public override string GetValidatedString(object value)
    {
        return base.GetValidatedString(value);
    }
    

ステップ 3: 新しいユーザー設定フィールド用のレンダリングの作成

次に、フィールド クラスのメソッドが JSLink 指す JavaScript ファイルを作成する必要があります。 このファイルでは、新しいクライアント側レンダリング機構を使用するユーザー設定フィールド型のレンダリングを定義します。 詳細については、「 [方法] クライアント側レンダリングを使用して、フィールド タイプをカスタマイズする」を参照してください。

次の例に、SharePointに導入されたクライアント側レンダリング機構への登録に必要なロジックを示します。

function _registerCustomGeolocationFieldTemplate() {
    var geolocationFieldContext = {};
    geolocationFieldContext.Templates = {};
    geolocationFieldContext.Templates.Fields = {

        'CustomGeolocationField': {
            'View': CustomGeolocationFieldTemplate.RenderGeolocationField,
            'DisplayForm': CustomGeolocationFieldTemplate.SPFieldGeolocation_Display,
            'EditForm': CustomGeolocationFieldTemplate.SPFieldGeolocation_Edit,
            'NewForm': CustomGeolocationFieldTemplate.SPFieldGeolocation_Edit
        }
    };
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(geolocationFieldContext);
}

登録プロセスには 4 つの変数とそれぞれのメソッドが存在します。 クライアント側レンダリング機構は CustomGeolocationControl のレンダリングのため、これらのメソッドを呼び出します。

次のコード例では、地理位置情報から派生する新しいユーザー設定フィールド用の新しいレンダリングが作成されます。

JavaScript ファイルを作成するには

  1. テキスト ファイルを作成し、x などの名前を指定し、.js拡張子を付けて、SharePoint マップの TEMPLATE\LAYOUTS フォルダーに保存します。 この例では CustomGeolocationControl.js という名前を使用します。

  2. 次のコードを .js ファイルにコピーします。

    (function () {
        if (typeof CustomGeolocationFieldTemplate == "object") {
            return;
        }
        window.CustomGeolocationFieldTemplate = (function () {
            return {
                SPFieldGeolocation_Display: function (rCtx) {
                    if (rCtx == null || rCtx.CurrentFieldValue == null || rCtx.CurrentFieldValue == '')
                        return '';
                    var listItem = rCtx['CurrentItem'];
                    var fldvalue = CustomGeolocationFieldTemplate.ParseGeolocationValue(listItem[rCtx.CurrentFieldSchema.Name]);
                    var _myData = SPClientTemplates.Utility.GetFormContextForCurrentField(rCtx);
    
                    if (_myData == null || _myData.fieldSchema == null)
                        return '';
                    var _latitude = 0;
                    var _longitude = 0;
    
                    if (fldvalue != null) {
                        _latitude = fldvalue.latitude;
                        _longitude = fldvalue.longitude;
                    }
    
                    var result = '<div>';
                    result += '<span>Latitude:</span><span>' + _latitude + '</span><span>Longitude:</span><span>' + _longitude + '</span>';
                    result += '</div>';
                    return result;
                },
                ParseGeolocationValue: function (fieldValue) {
    
                    if (fieldValue == null || fieldValue == '')
                        return null;
    
                    var point = new Object();
                    point.longitude = null;
                    point.latitude = null;
                    point.altitude = null;
                    point.measure = null;
    
                    var matches = fieldValue.match(/POINT\\s*\\((\\d+(\\.\\d+)?)\\s+(\\d+(\\.\\d+)?)\\s+(\\d+(\\.\\d+)?)\\s+(\\d+(\\.\\d+)?)\\)/i);
                    if (matches != null) {
    
                        point.longitude = parseFloat(matches[1]);
                        point.latitude = parseFloat(matches[3]);
                        point.altitude = parseFloat(matches[5]);
                        point.measure = parseFloat(matches[7]);
                    }
                    else
                    {
                        matches = fieldValue.match(/POINT\\s*\\((\\d+(\\.\\d+)?)\\s+(\\d+(\\.\\d+)?)\\)/i);
                        if (matches != null) {
    
                            point.longitude = parseFloat(matches[1]);
                            point.latitude = parseFloat(matches[3]);
                        }
                    }
                    return point;
                },
                SPFieldGeolocation_Edit: function (rCtx) {
                    if (rCtx == null)
                        return '';
                    var _myData = SPClientTemplates.Utility.GetFormContextForCurrentField(rCtx);
    
                    if (_myData == null || _myData.fieldSchema == null)
                        return '';
                    var _latitude = null;
                    var _longitude = null;
                    var _inputId_Latitude = _myData.fieldName + '_' + _myData.fieldSchema.Id + '_$geolocationField_Latitude';
                    var _inputId_Longitude = _myData.fieldName + '_' + _myData.fieldSchema.Id + '_$geolocationField_Longitude';
                    var _inputId_Div = _myData.fieldName + '_' + _myData.fieldSchema.Id + '_$geolocationField_Div';
                    var _latitudeBox = null;
                    var _longitudeBox = null;
    
                    var _value = _myData.fieldValue != null ? _myData.fieldValue : '';
                    var listItem = rCtx['CurrentItem'];
                    var fldvalue = CustomGeolocationFieldTemplate.ParseGeolocationValue(listItem[rCtx.CurrentFieldSchema.Name]);
    
                    if (fldvalue != null) {
                        _latitude = fldvalue.latitude;
                        _longitude = fldvalue.longitude;
                    }
    
                    var validators = new SPClientForms.ClientValidation.ValidatorSet();
    
                    if (_myData.fieldSchema.Required)
                        validators.RegisterValidator(new SPClientForms.ClientValidation.RequiredValidator());
    
                    _myData.registerClientValidator(_myData.fieldName, validators);
    
                    // Post DOM initialization callback.
                    _myData.registerInitCallback(_myData.fieldName, function () {
    
                        // Initialize the input control references.
                        _latitudeBox = document.getElementById(_inputId_Latitude);
                        _longitudeBox = document.getElementById(_inputId_Longitude);
    
                        // Set the initial values.
                        if ((_latitudeBox != null &amp;&amp; _longitudeBox != null) &amp;&amp;
                            (_latitude != null &amp;&amp; _longitude != null)) {
                            _latitudeBox.value = _latitude;
                            _longitudeBox.value = _longitude;
                        }
                    });
                    // On focus call back.
                    _myData.registerFocusCallback(_myData.fieldName, function () {
                        if (_latitudeBox != null)
                            _latitudeBox.focus();
                    });
                    // Validation failure handler.
                    _myData.registerValidationErrorCallback(_myData.fieldName, function (errorResult) {
                        SPFormControl_AppendValidationErrorMessage(_inputId_Div, "invalid Geolocation Field");
                    });
    
                    // Register a callback just before submit.
                    _myData.registerGetValueCallback(_myData.fieldName, function () {
                        if (_latitudeBox == null &amp;&amp; _longitudeBox == null)
                            return '';
                        else {
                            _latitude = _latitudeBox.value;
                            _longitude = _longitudeBox.value;
    
                            if (_latitude != null &amp;&amp; _longitude != null)
                                return "Point(" + _longitude + " " + _latitude + ")";
                        }
                    });
                    _myData.updateControlValue(_myData.fieldName, _value);
    
                    var result = '<div width="100%" id=' + STSHtmlEncode(_inputId_Div) + '>';
                    result += '<div><span>Latitude:</span><input id=' + STSHtmlEncode(_inputId_Latitude) + ' type="text" name="Latitude" /></div>';
                    result += '<div><span>Longitude:</span><input id=' + STSHtmlEncode(_inputId_Longitude) + ' type="text" name="Longitude" /></div>';
                    result += '</div>';
                    return result;
    
                },
                RenderGeolocationField: function (inCtx, field, listItem, listSchema) {
                    var fldvalue = CustomGeolocationFieldTemplate.ParseGeolocationValue(listItem[field.Name]);
                    var result = '';
    
                    if (fldvalue != null) {
                        var result = '<div>';
                        result += '<span>Latitude:</span><span>' + fldvalue.latitude + '</span><span>Longitude:</span><span>' + fldvalue.longitude + '</span>';
                        result += '</div>';
                    }
                    return result;
                }
            };
        })();
        function _registerCustomGeolocationFieldTemplate() {
    
            var geolocationFieldContext = {};
            geolocationFieldContext.Templates = {};
            geolocationFieldContext.Templates.Fields = {
    
                'CustomGeolocationField': {
                    'View': CustomGeolocationFieldTemplate.RenderGeolocationField,
                    'DisplayForm': CustomGeolocationFieldTemplate.SPFieldGeolocation_Display,
                    'EditForm': CustomGeolocationFieldTemplate.SPFieldGeolocation_Edit,
                    'NewForm': CustomGeolocationFieldTemplate.SPFieldGeolocation_Edit
                }
            };
            SPClientTemplates.TemplateManager.RegisterTemplateOverrides(geolocationFieldContext);
        }
        ExecuteOrDelayUntilScriptLoaded(_registerCustomGeolocationFieldTemplate, 'clienttemplates.js');
    })();
    

ステップ 4: フィールド型定義の作成

フィールド型定義は、%ProgramFiles%\Common Files\Microsoft Shared\web サーバー拡張機能\15\TEMPLATE\XML にデプロイされる fldtypes.xml* のような名前の XML ファイルです。 フィールド定義ファイルには、SharePoint Foundation がリスト ビューと、表示、編集、新規作成フォームでフィールドを正しくレンダリングするのに必要な情報が含まれます。 最も重要な点は、定義にはコンパイルされたフィールド型を含むアセンブリに関する情報が含まれるということです。 フィールド型の定義の詳細については、「[方法] ユーザー設定フィールド型の定義を作成する」を参照してください。

フィールド型定義を作成するには

  1. Visual Studio でプロジェクトをビルドします。 プロジェクトは完成していませんが、アセンブリの GUID と公開キー トークンを生成するために、この時点でビルドする必要があります。

  2. fldtypes_CustomGeolocationControl.xml ファイルを開き、その内容を次のマークアップに置き換えます。

    <?xml version="1.0" encoding="utf-8" ?>
    <FieldTypes>
      <FieldType>
        <Field Name="TypeName">CustomGeolocationField</Field>
        <Field Name="ParentType">Geolocation</Field>
        <Field Name="TypeDisplayName">Custom Geolocation field</Field>
        <Field Name="TypeShortDescription"> Custom Geolocation field </Field>
        <Field Name="UserCreatable">TRUE</Field>
        <Field Name="ShowOnListCreate">TRUE</Field>
        <Field Name="ShowOnSurveyCreate">TRUE</Field>
        <Field Name="ShowOnDocumentLibraryCreate">TRUE</Field>
        <Field Name="ShowOnColumnTemplateCreate">TRUE</Field>
        <Field Name="FieldTypeClass">CustomGeolocationField.CustomGeolocationField,$SharePoint.Project.AssemblyFullName$</Field>
        <Field Name="SQLType">nvarchar</Field>
      </FieldType>
    </FieldTypes>
    

    このファイルは、SharePointのユーザー設定フィールド型を定義するものです。 要素の目的と意味の詳細については、「 ユーザー設定フィールド型の定義」、「 FldTypes.xml」、「 FieldTypes 要素 (フィールド型)」FieldType 要素 (フィールド型)および Field 要素 (フィールド型)を参照してください。 <Field Name="FieldTypeClass"> 要素は、1 行で記述する必要があります。

  3. 要素の <Field Name="FieldTypeClass"> 値は、ユーザー設定フィールド クラスの完全修飾名、コンマ、Visual Studio トークン ($SharePoint.Project.AssemblyFullName$) です。 プロジェクトのコンパイル時にこのファイルのコピーが作成され、そのコピー内でトークンが 4 つの部分で構成される完全なアセンブリ名に置き換えられます。 そのコピーは Visual Studio 2012 の Visual Studio [ ビルド] メニューの [ ソリューションの展開] を選択すると展開されます。

ステップ 5: ユーザー設定フィールド型の作成およびテスト

ユーザー設定フィールドを SharePoint サーバーに展開すると、ソリューションが展開されているサーバー上の任意の SharePoint リストに新しいユーザー設定列を追加できるようになります。

  1. F5 キーを選択します。

    注:

    F5 キーを選択すると、Visual Studio によってソリューションがビルドされて展開され、ソリューションが展開された SharePoint Web サイトが開きます。

  2. カスタム リストを作成し、新しいカスタム位置情報フィールド列を追加します。

  3. リストにアイテムを 1 つ追加し、ユーザー設定地理位置情報列に経度と緯度の値を入力します。

  4. 図 2 は、新しいユーザー設定フィールド型を含む [列の作成] ページを示しています。

    図 2. 新しいユーザー設定フィールド型の列を作成する

    新しいカスタム地理位置情報フィールド タイプの作成

関連項目