How to implement NavSherpa on a Card page with sub-lines
If you install NavSherpa-Demo extension, NavSherpa module will be implemented on a few starter pages. If you would like to use NavSherpa on a page, where it is not implemented by default, it can be added. For adding NavSherpa module to a page, please contact your system administrator.
This implementation method is used, if NavSherpa shows information from lines on a page (e.g. “Purchase Lines”) and is connected to a header table and a line table in this page.
Card implementation
1. Create new page extension:
pageextension 4065005 "NSP Purchase Invoice" extends "Purchase Invoice"
{
layout
{
// Add changes to page layout here
}
actions
{
// Add changes to page actions here
}
}
2. Create new global variables on page extension:
var
NSPListSharePointListCode: Code[20];
NSPWorkFlowListSharePointListCode: Code[20];
NSPLineListSharePointListCode: Code[20];
NSPLineWorkFlowListSharePointListCode: Code[20];
NSPSmartTreeDisplay: Enum NSP_SmartTreeDisplay;
NSPLineSmartTreeDisplay: Enum NSP_SmartTreeDisplay;
NSPSharePointListSetupExists: Boolean;
NSPSharePointLibrarySetupExists: Boolean;
NSPWorkFlowListSetupExists: Boolean;
NSPAllowDeleteRecords: Boolean;
NSPShowSmartTree: Boolean;
NSPLineSharePointListSetupExists: Boolean;
NSPLineSharePointLibrarySetupExists: Boolean;
NSPLineWorkFlowListSetupExists: Boolean;
NSPLineAllowDeleteRecords: Boolean;
NSPLineShowSmartTree: Boolean;
3. Add new controls on page factbox area. (Suggestion: Add FactBoxes as first FactBox in page)
layout
{
addfirst(factboxes)
{
part(NSPNavSherpaSmartTree;"NSP SmartTree Factbox")
{
Caption = 'NavSherpa Smart Tree';
ApplicationArea = All;
Visible = NSPShowSmartTree;
}
part(NSPSharePointWFStatusFactbox;"NSP SP WF. Status Header FactB")
{
Caption = 'WorkFlow Status (NavSherpa)';
ApplicationArea = All;
Visible = NSPWorkFlowListSetupExists;
}
part(NSPLineSharePointWFStatusFactbox;"NSP SP WF. Status Header FactB")
{
Caption = 'Lines WorkFlow Status (NavSherpa)';
ApplicationArea = All;
Visible = NSPLineWorkFlowListSetupExists;
}
}
}
4. Add new action group to actions:
actions
{
addlast(Navigation)
{
group(NSPNavSherpa)
{
Caption = 'NavSherpa';
Image = Web;
// Add group actions here
}
}
}
5. Add new actions to group NavSherpa:
group(NSPNavSherpa)
{
Caption = 'NavSherpa';
Image = Web;
action(NSPSPLink)
{
Caption = 'SP Link';
ToolTip = 'Launch the SharePoint web site as specified in Repository URL on tab General in SharePoint List Setup.';
ApplicationArea = All;
Enabled = NSPSharePointListSetupExists;
Image = LinkWeb;
trigger OnAction()
var
NavSherpaInterface: Codeunit "NSP Interface";
begin
NavSherpaInterface.OpenSharePointListLink('',Rec);
end;
}
action(NSPAdvWorkFlow)
{
Caption = 'Advanced WorkFlow';
ToolTip = 'Initiate a workflow as specified in SharePoint List Setup Card/SharePoint List Workflow Setup Card.';
ApplicationArea = All;
Visible = NSPWorkflowListSetupExists;
Image = WorkCenterLoad;
trigger OnAction()
var
NavSherpaInterface: Codeunit "NSP Interface";
begin
NavSherpaInterface.StartWorkflow('',Rec,true,false,Rec,0);
end;
}
action(NSPCopyToSP)
{
Caption = 'Copy to SP';
ToolTip = 'Send a record from Microsoft Dynamics 365 Business Central to SharePoint.';
ApplicationArea = All;
Enabled = NSPSharePointListSetupExists;
Image = ExportElectronicDocument;
trigger OnAction()
var
NavSherpaInterface: Codeunit "NSP Interface";
begin
NavSherpaInterface.UpdateListItems('','',false,Rec,true,false);
end;
}
action(NSPRemFromSP)
{
Caption = 'Remove from SP';
ToolTip = 'Remove a record from SharePoint. Action is visible only if enabled in Allow Delete Records On SP on tab General in SharePoint List Setup.';
ApplicationArea = All;
Enabled = NSPAllowDeleteRecords;
Image = VoidElectronicDocument;
trigger OnAction()
var
NavSherpaInterface: Codeunit "NSP Interface";
begin
NavSherpaInterface.UpdateListItems('','',true,Rec,true,false);
end;
}
action(NSPSmartTree)
{
Caption = 'Smart Tree';
ToolTip = 'Show/hide the Smart Tree factbox, or open a page containing the Smart Tree. The behavior of this action depends on the value set in Smart Tree Display on tab General in SharePoint List Setup.';
ApplicationArea = All;
Visible = NSPSmartTreeDisplay <> NSPSmartTreeDisplay::FactBox;
Image = CopyFromBOM;
trigger OnAction()
var
NavSherpaSmartTreeFactbox: Page "NSP SmartTree Factbox";
begin
if NSPSmartTreeDisplay = NSPSmartTreeDisplay::HideFactBox then begin
NSPShowSmartTree := not NSPShowSmartTree;
CurrPage.UPDATE();
end else begin
NavSherpaSmartTreeFactbox.SetEditable(CurrPage.EDITABLE());
NavSherpaSmartTreeFactbox.SetRecordRecord(Rec);
NavSherpaSmartTreeFactbox.Run();
end;
end;
}
}
6. Create new function UpdateNavSherpaControls on page. This function must have a variable of type record, where the table is the same as table used on subpage. This code shows Purchase Invoice Card with Purchase Lines on subpage.
local procedure NSPUpdateNavSherpaControls()
var
NavSherpaSetup: Record "NSP NavSherpa Setup";
PurchaseLine: Record "Purchase Line";
NavSherpaInterface: Codeunit "NSP Interface";
begin
if NavSherpaSetup.ReadPermission() then begin
NavSherpaInterface.GetSharePointSettings(NSPListSharePointListCode,NSPWorkFlowListSharePointListCode,NSPSharePointListSetupExists,NSPSharePointLibrarySetupExists
,NSPWorkFlowListSetupExists,NSPAllowDeleteRecords,NSPSmartTreeDisplay,Rec);
NSPShowSmartTree := NSPSharePointLibrarySetupExists and ((NSPSmartTreeDisplay = NSPSmartTreeDisplay::FactBox) or NSPShowSmartTree);
if NSPSharePointLibrarySetupExists then
if NSPShowSmartTree then begin
CurrPage.NSPNavSherpaSmartTree.Page.SetEditable(true);
CurrPage.NSPNavSherpaSmartTree.Page.SetRecordRecord(Rec);
end;
if NSPWorkFlowListSetupExists then
CurrPage.NSPSharePointWFStatusFactbox.Page.SetWFMappingFilter('',Rec);
NavSherpaInterface.GetSharePointSettings(NSPLineListSharePointListCode,NSPLineWorkFlowListSharePointListCode,NSPLineSharePointListSetupExists,NSPLineSharePointLibrarySetupExists
,NSPLineWorkFlowListSetupExists,NSPLineAllowDeleteRecords,NSPLineSmartTreeDisplay,PurchaseLine);
NSPLineShowSmartTree := NSPLineSharePointLibrarySetupExists and ((NSPLineSmartTreeDisplay = NSPLineSmartTreeDisplay::FactBox) or NSPLineShowSmartTree);
if NSPLineWorkFlowListSetupExists then begin
PurchaseLine.RESET();
PurchaseLine.SETRANGE("Document Type",Rec."Document Type");
PurchaseLine.SETRANGE("Document No.",Rec."No.");
CurrPage.NSPLineSharePointWFStatusFactbox.Page.SetWFMappingFilter('',PurchaseLine);
end;
end;
end;
Note:
Function changes property Editable in NavSherpa Smart Tree by current page Editable property. It can be a problem on pages which aren't editable, but document can be uploaded. To allow upload you need to change line
CurrPage.NSPNavSherpaSmartTree.PAGE.SetEditable(CurrPage.EDITABLE());
to
CurrPage.NSPNavSherpaSmartTree.PAGE.SetEditable(TRUE);
Note 2:
NSPLineSharePointWFStatusFactbox shows all workflows for all lines from subpage. If workflow uses same name for example "Approve line" and workflow will be started for all lines, the program shows "Approve line" for example 5 times in FactBox. Problem is, that user wouldn't know which workflow is for first line, second line etc.
Function "SetWFMappingFilter" provides parameter "_LineIdentificationFieldNo" and this parameter can be used for line definition. If parameter is set to "0", workflow name will be "Approve line". If parameter will be field number – for example "OpportunityEntry.FIELDNO("Entry No.")" – workflow name will be "(10000) Approve line" and user would know which workflow is running for line. Function below uses field "Sales Cycle Stage" for line definition.
CurrPage.NSPLineSharePointWFStatusFactbox.PAGE.SetWFMappingFilter('', OpportunityEntry,TRUE,OpportunityEntry.FIELDNO("Sales Cycle Stage"));
7. Add code to trigger OnNewRecord:
trigger OnNewRecord(BelowxRec: Boolean)
begin
NSPUpdateNavSherpaControls();
end;
8. Add code to trigger OnAfterGetCurrRecord:
trigger OnAfterGetCurrRecord()
begin
NSPUpdateNavSherpaControls();
end;
Subpage implementation
1. Create new page extension:
pageextension 4065006 "NSP Purch. Invoice Subform" extends "Purch. Invoice Subform"
{
layout
{
// Add changes to page layout here
}
actions
{
// Add changes to page actions here
}
}
2. Create new global variables on page:
var
NSPListSharePointListCode: Code[20];
NSPWorkFlowListSharePointListCode: Code[20];
NSPSmartTreeDisplay: Enum NSP_SmartTreeDisplay;
NSPSharePointListSetupExists: Boolean;
NSPSharePointLibrarySetupExists: Boolean;
NSPWorkFlowListSetupExists: Boolean;
NSPAllowDeleteRecords: Boolean;
NSPShowSmartTree: Boolean;
3. Add new action group to actions:
actions
{
addlast("&Line")
{
Group(NSPNavSherpa)
{
Caption = 'NavSherpa';
Image = Web;
// Add group actions here
}
}
}
4. Add new actions to group NavSherpa:
group(NSPNavSherpa)
{
Caption = 'NavSherpa';
Image = Web;
action(NSPSPLink)
{
Caption = 'SP Link';
ToolTip = 'Launch the SharePoint web site as specified in Repository URL on tab General in SharePoint List Setup.';
ApplicationArea = All;
Enabled = NSPSharePointListSetupExists;
Image = LinkWeb;
trigger OnAction()
var
NavSherpaInterface: Codeunit "NSP Interface";
begin
NavSherpaInterface.OpenSharePointListLink('',Rec);
end;
}
action(NSPAdvWorkFlow)
{
Caption = 'Advanced WorkFlow';
ToolTip = 'Initiate a workflow as specified in SharePoint List Setup Card/SharePoint List Workflow Setup Card.';
ApplicationArea = All;
Visible = NSPWorkflowListSetupExists;
Image = WorkCenterLoad;
trigger OnAction()
var
NavSherpaInterface: Codeunit "NSP Interface";
begin
NavSherpaInterface.StartWorkflow('',Rec,true,false,Rec,0);
end;
}
action(NSPCopyToSP)
{
Caption = 'Copy to SP';
ToolTip = 'Send a record from Microsoft Dynamics 365 Business Central to SharePoint.';
ApplicationArea = All;
Enabled = NSPSharePointListSetupExists;
Image = ExportElectronicDocument;
trigger OnAction()
var
NavSherpaInterface: Codeunit "NSP Interface";
begin
NavSherpaInterface.UpdateListItems('','',false,Rec,true,false);
end;
}
action(NSPRemFromSP)
{
Caption = 'Remove from SP';
ToolTip = 'Remove a record from SharePoint. Action is visible only if enabled in Allow Delete Records On SP on tab General in SharePoint List Setup.';
ApplicationArea = All;
Enabled = NSPAllowDeleteRecords;
Image = VoidElectronicDocument;
trigger OnAction()
var
NavSherpaInterface: Codeunit "NSP Interface";
begin
NavSherpaInterface.UpdateListItems('','',true,Rec,true,false);
end;
}
action(NSPSmartTree)
{
Caption = 'Smart Tree';
ToolTip = 'Show/hide the Smart Tree factbox, or open a page containing the Smart Tree. The behavior of this action depends on the value set in Smart Tree Display on tab General in SharePoint List Setup.';
ApplicationArea = All;
Visible = NSPSmartTreeDisplay <> NSPSmartTreeDisplay::FactBox;
Image = CopyFromBOM;
trigger OnAction()
var
NavSherpaSmartTreeFactbox: Page "NSP SmartTree Factbox";
begin
if NSPSmartTreeDisplay = NSPSmartTreeDisplay::HideFactBox then begin
NSPShowSmartTree := not NSPShowSmartTree;
CurrPage.UPDATE();
end else begin
NavSherpaSmartTreeFactbox.SetEditable(CurrPage.EDITABLE());
NavSherpaSmartTreeFactbox.SetRecordRecord(Rec);
NavSherpaSmartTreeFactbox.Run();
end;
end;
}
action(NSPDocAttach)
{
Caption = 'Attachments';
ApplicationArea = All;
ToolTip = 'Add a file as an attachment. You can attach images as well as documents.';
Image = Attach;
trigger OnAction()
var
DocumentAttachmentDetails: Page "Document Attachment Details";
RecRef: RecordRef;
begin
RecRef.GETTABLE(Rec);
DocumentAttachmentDetails.OpenForRecRef(RecRef);
DocumentAttachmentDetails.RunModal();
end;
}
}
5. Create new function UpdateNavSherpaControls on page:
local procedure NSPUpdateNavSherpaControls()
var
NavSherpaSetup: Record "NSP NavSherpa Setup";
NavSherpaInterface: Codeunit "NSP Interface";
begin
if NavSherpaSetup.ReadPermission() then begin
NavSherpaInterface.GetSharePointSettings(NSPListSharePointListCode,NSPWorkFlowListSharePointListCode,NSPSharePointListSetupExists,NSPSharePointLibrarySetupExists
,NSPWorkFlowListSetupExists,NSPAllowDeleteRecords,NSPSmartTreeDisplay,Rec);
NSPShowSmartTree := NSPSharePointLibrarySetupExists and ((NSPSmartTreeDisplay = NSPSmartTreeDisplay::FactBox) or NSPShowSmartTree);
end;
end;
6. Add code to trigger OnNewRecord:
trigger OnNewRecord(BelowxRec: Boolean)
begin
NSPUpdateNavSherpaControls();
end;
7. Add code to trigger OnAfterGetCurrRecord:
trigger OnAfterGetCurrRecord()
begin
NSPUpdateNavSherpaControls();
end;
8. Save changes.