予測の基になるレコード グリッドのカスタマイズ
開発者は、この参照ドキュメントを使用して、予測の基になるレコード グリッドをカスタマイズするためのイベントとコンテキスト オブジェクトについて学習します。 コンテキスト オブジェクトを使用して、グリッド全体または特定のフィールドを読み取り専用にしたり、フィールドを無効にしたり、エラー通知を表示したりするなどのカスタマイズを実行できます。
基になるレコード グリッドのイベント
予測では、以下のイベントに対応しています:
次のサンプル シナリオは、サポートされているイベント ハンドラーに基づいて作成されています。
- すべてのフィールドを無効にしてグリッドを読み取り専用にします。
- エンティティに基づいて常に少数のフィールドのみを有効にします。
- ロジックとエンティティに基づくフィールドの編集を無効にします。
- 値に基づいてエラー通知を表示します。
- preventDefault を使用して推定値に基づいて自動保存をブロックし、ウィンドウ イベントを開きます。
OnRowLoad イベント
OnRowLoad
イベントは、グリッドに読み込まれたすべての基盤となるレコードに対してトリガーされます。
OnRowLoad
イベント ハンドラーに受け渡されるコンテキスト オブジェクトには、基盤となるレコードに固有の API が含まれています。
OnRowLoad
ハンドラーを使用して実行できるサンプル シナリオを次に示します。
Note
予測の構成では、基になるレコード グリッドで Groupby 属性を選択することで、さまざまなエンティティの基になるレコードが表示されます。 これらのエンティティに基づいてロジックを処理するには、エンティティに基づいて常に少数のフィールドのみを有効にするとロジックとエンティティに基づくフィールドの編集を無効にするのサンプルを参照してください。
OnChange イベント
この OnChange
イベントは、基になるレコード グリッド内のセルの値が更新され、セルのフォーカスが合わなくなったときにトリガーされます。
注意
- 基になるレコード グリッドでは、フィールドが変更されると、
OnChange
とOnSave
のイベント ハンドラー (存在する場合) がトリガーされます。 -
OnChange
ハンドラーでクライアント API を使用してフィールドにエラー通知が設定されている場合、保存はトリガーされません。 予測クライアント API に関する通知については、setNotification
context.getFormContext().data.entity.attributes.getByName("Attribute Name").controls.get(0) の API に移動します。 -
OnChange
ハンドラーへの属性間のマッピングはなく、フィールドが変更されると、コンテキスト オブジェクト パラメータを使用してOnChange
ハンドラーがトリガーされます。 ハンドラーをトリガーした属性を特定するには、属性オブジェクトのgetIsDirty
関数を使用します。 詳細: context.getFormContext().data.entity.attributes.getByName("Attribute Name")
OnChange
ハンドラーを使用して実行できるサンプル シナリオを次に示します。
OnSave イベント
この OnSave
イベントは、基になるレコード グリッド内のセルの値が変更され、セルのフォーカスが合わなくなったときにトリガーされます。 ただし、OnChange
ハンドラーが同じ予測構成に対して存在する場合、OnSave
ハンドラーは OnChange
ハンドラーの後に呼び出されます。
OnSave
ハンドラーは、フィールドを実際に保存する前に呼び出されます。
注意
- 基になるレコード グリッドでは、フィールドが変更されると、
OnChange
とOnSave
のイベント ハンドラー (存在する場合) がトリガーされます。 -
OnSave
ハンドラーでクライアント API を使用してフィールドにエラー通知が設定されている場合、保存はトリガーされません。 予測クライアント API に関する通知については、setNotification
context.getFormContext().data.entity.attributes.getByName("Attribute Name").controls.get(0) の API に移動します。 -
OnSave
ハンドラーへの属性間のマッピングはなく、フィールドが変更されると、コンテキスト オブジェクト パラメータを使用してOnSave
ハンドラーがトリガーされます。 ハンドラーをトリガーした属性を特定するには、属性オブジェクトのgetIsDirty
関数を使用します。 詳細: context.getFormContext().data.entity.attributes.getByName("Attribute Name")
OnSave
ハンドラーを使用して実行できるサンプル シナリオを次に示します。
基になるレコード グリッドにおけるイベント ハンドラーのコンテキスト オブジェクト
コンテキスト オブジェクトには、予測内の基盤となるレコードに固有の操作を実行するための一連の API が含まれています。 このコンテキスト オブジェクトは、基になるレコード グリッド ビューのイベント ハンドラーにパラメーターとして渡されます。
次の API がサポートされています。
context.getFormContext メソッド
基になるレコード グリッド上のレコードへの参照を返します。
context.getFormContext().data.entity
これはエンティティ オブジェクトを返し、次のメソッドがあります。
メソッド | 返り値の種類 | 説明設定 |
---|---|---|
getEntityName() |
String | レコードのエンティティの論理名を表す文字列を返します。 |
getId() |
String | レコードの GUID 値を表す文字列を返します。 |
attributes |
リスト | ビューに関連する属性のリストと、基になるレコード グリッドの一部として読み込まれるエンティティを返します。 次の操作を実行できます。 - context.getFormContext().data.entity.attributes.forEach - context.getFormContext().data.entity.attributes.getByName(arg) - context.getFormContext().data.entity.attributes.get(index) |
context.getFormContext().data.entity.attributes.getByName("Attribute Name")
これは属性オブジェクトを返し、次のメソッドがあります。
メソッド | 返り値の種類 | 説明設定 |
---|---|---|
getName() |
String | 属性の論理名を表す文字列を返します。 |
getValue() |
-- | 属性のデータ値を取得します。 |
getIsDirty() |
ブール型 | 属性値に対する変更内容が保存されていないことを示すブール値を返します。 |
controls |
リスト | 各属性オブジェクトのコントロールのリストを返します。 注意: controls オブジェクト リストの長さは常に 1 で、get(0) は直接使用できます。 |
context.getFormContext().data.entity.attributes.getByName("Attribute Name").controls.get(0)
これは、属性へのコントロール オブジェクト マッピングを返します。次のメソッドがあります。
メソッド | 返り値の種類 | 説明設定 |
---|---|---|
getDisabled() |
ブール型 | コントロールが無効かどうかを返します。 |
setDisabled(bool) |
-- | コントロールに無効な値 (有効または無効) を設定します。 |
setNotification(message: string, uniqueId?: string) |
ブール型 | データが無効であることを示すコントロールのエラー メッセージを表示します。 このメソッドを使用すると、セル内のコントロールの横に赤の十字アイコンが表示されます。 エラー アイコンにカーソルを合わせると、指定されたメッセージが表示されます。 エラー アイコンを選択すると、行が再読み込みされ、変更が元に戻されます。
uniqueId は、clearNotification メソッドの使用時にこのメッセージをクリアするために使用されます。 |
clearNotification(uniqueId?: string) |
ブール型 | 既にコントロールに表示されているメッセージを削除します。 一意の ID が指定されていない場合、そのコントロールのすべての通知が削除されます。 |
Note
JavaScript ファイルの関数名は、イベント名と一致し、コンテキスト オブジェクト パラメーターを受け取ることをお勧めします。
JavaScript コードを作成して、基になるレコード グリッドのすべてのフィールドを読み取り専用にしましょう。 また、グリッドが正常にロードおよび保存されると、各行に対して OnRowLoad
関数を呼び出します。
function OnRowLoad(executionContext) {
// Iterating through all attributes and disabling it.
executionContext.getFormContext().data.entity.attributes.forEach(
attribute => {
attribute.controls.get(0).setDisabled(true);
}
)
}
営業案件 エンティティのみのいくつかを除くすべてのフィールドを無効にする JavaScript コードを作成しましょう。 また、グリッドが正常にロードおよび保存されると、各行に対して OnRowLoad
関数を呼び出します。
function OnRowLoad(executionContext) {
// Get the logical name of the loaded entity as part of underlying records grid.
var entityName = executionContext.getFormContext().data.entity.getEntityName();
if (entityName === "opportunity") {
// Defining the attributes list from opportunity that has to be enabled if loaded as part of view.
var OPTY_ENABLE_ATTRS_LIST = ["name", "msdyn_forecastcategory", "actualvalue", "actualclosedate", "estimatedvalue", "estimatedclosedate"];
executionContext.getFormContext().data.entity.attributes.forEach(
attribute => {
// Disabling all attributes other than OPTY_ENABLE_ATTRS_LIST
if (!OPTY_ENABLE_ATTRS_LIST.includes(attribute.getName())) {
attribute.controls.get(0).setDisabled(true);
}
}
)
}
}
例 3:
読み込まれた予測構成のさまざまなエンティティを処理する JavaScript コードを作成しましょう。
営業案件エンティティの場合、スクリプトは以下を無効にします。
- 名前列
-
actualRevenue
とactualCloseData
(forecastCategory
の値が最良のケース、コミット、省略、またはパイプラインの場合)。 -
estimatedRevenue
とestimatedCloseDate
(forecastCategory
の値が受注または失注の場合)。
同様に、スクリプトは取引先企業エンティティの名前列を無効にし、他のエンティティのすべての列を無効にします。
また、グリッドが正常にロードおよび保存されると、各行に対して OnRowLoad
関数を呼び出します。
function OnRowLoad(executionContext) {
// Get the logical name of the loaded entity as part of underlying records grid.
var entityName = executionContext.getFormContext().data.entity.getEntityName();
// If loaded logical name of entity in underlying records grid is opportunity.
if (entityName === "opportunity") {
var allAttrs = executionContext.getFormContext().data.entity.attributes;
// Disable column name for all records if exists in the view.
var nameAttr = allAttrs.getByName("name");
if (nameAttr) {
nameAttr.controls.get(0).setDisabled(true);
}
var fcatAttr = allAttrs.getByName("msdyn_forecastcategory");
if (fcatAttr) {
// Disable actualRevenue, actualCloseDate for forecastcategory Bestcase, committed, omitted, or pipeline.
if (fcatAttr.getValue() <= 100000004 && fcatAttr.getValue() >= 100000001) {
var actualRevenueAttr = allAttrs.getByName("actualvalue");
var actualCloseDateAttr = allAttrs.getByName("actualclosedate");
if (actualRevenueAttr) actualRevenueAttr.controls.get(0).setDisabled(true);
if (actualCloseDateAttr) actualCloseDateAttr.controls.get(0).setDisabled(true);
}
// Disable estimatedRevenue, estimatedCloseDate for forecastCategory won or lost.
else if (fcatAttr.getValue() == 100000005 || fcatAttr.getValue() == 100000006) {
var estimatedRevenueAttr = allAttrs.getByName("estimatedvalue");
var estimatedCloseDateAttr = allAttrs.getByName("estimatedclosedate");
if (estimatedRevenueAttr) estimatedRevenueAttr.controls.get(0).setDisabled(true);
if (estimatedCloseDateAttr) estimatedCloseDateAttr.controls.get(0).setDisabled(true);
}
}
}
// Else disable name column, if loaded logical name of entity is Account.
else if (entityName === "account"){
var attrNameObj = executionContext.getFormContext().data.entity.attributes.getByName("name");
if (attrNameObj) {
attrNameObj.controls.get(0).setDisabled(true);
}
}
// For all other entities
else {
executionContext.getFormContext().data.entity.attributes.forEach(
attribute => {
attribute.controls.get(0).setDisabled(true);
}
)
}
}
値が 10 未満の場合に保存をブロックし、売上見込み列にエラー通知を表示する検証 JavaScript ファイルを作成しましょう。 また、エラー通知を削除し、売上見込み列の値が 10 以上に修正されたときに保存できるようにします。 ここでは、予測の基になるレコード グリッドでいずれかのフィールドの値が更新されたときに、OnChange
関数が呼び出されます。
// OnChange function is invoked when any field's value is updated on the underlying records grid of the forecast
function OnChange(executionContext) {
let entity = executionContext.getFormContext().data.entity;
// Verify the logical name of the entity and load as part of the underlying records grid.
if (entity.getEntityName() === "opportunity") {
// Verify estimated revenue value
let estValAttr = entity.attributes.get("estimatedvalue");
// Verify if this attribute exists within the grid view and changed
if(estValAttr && estValAttr.getIsDirty())
{
if(estValAttr.getValue() < 10){
// This will show an error icon next to the estimated revenue field. On hovering over the icon, the below provided message is displayed.
// Any save attempts are blocked by the system until all notifications are cleared from the columns.
estValAttr.controls.get(0).setNotification("Estimated revenue cannot be less than 10");
}
else{
// Clearing notifications to save.
estValAttr.controls.get(0).clearNotification();
}
}
}
}
context.getWebApiContext()
これは webApiContext
オブジェクトを返し、次のメソッドがあります。
メソッド | 説明設定 |
---|---|
retrieveRecord(entityLogicalName, id, options) then (successCallback, errorCallback); |
エンティティ レコードを取得します。 詳細: retrieveRecord (クライアント API 参照) |
updateRecord(entityLogicalName, id, data) then(successCallback, errorCallback); |
エンティティ レコードを更新します。 詳細: updateRecord (クライアント API 参照) |
createRecord(entityLogicalName, data) then(successCallback, errorCallback); |
エンティティ レコードを作成します。 詳細: createRecord (クライアント API 参照) |
deleteRecord(entityLogicalName, id) then(successCallback, errorCallback); |
エンティティ レコードを削除します。 詳細: deleteRecord (クライアント API 参照) |
context.getEventArgs().preventDefault()
preventDefault()
メソッドは、OnSave
イベント内で使用可能です。
OnSave
内でこのメソッドを呼び出すと、保存イベントが進行しなくなります。
サンプル JavaScript を作成して営業案件グリッドを開き、自動保存イベントをブロックして、売上見込み値が 10 未満の場合にウィンドウ アラートを開きます。 また、売上見込み値が 10 以上の場合、自動保存イベントを許可します。
// OnSave function will be invoked whenever grid attempts to save changes made to any field.
function OnSave(executionContext){
let entity = executionContext.getFormContext().data.entity;
// Verify the logical name of the entity and load as part of the underlying records grid.
if (entity.getEntityName() === "opportunity") {
// Verify estimated revenue value
var estValAttr = entity.attributes.get("estimatedvalue");
if(estValAttr && estValAttr.getIsDirty() && estValAttr.getValue() < 10){
// This call will prevent the save event from proceeding
executionContext.getEventArgs().preventDefault();
alert("Estimated revenue cannot be less than 10");
}
}
}