- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
4 weeks ago
Hi Everyone,
I am facing issues displaying attachments in a cloned Form widget within a scoped application. Your guidance and support on this would be greatly appreciated. Thanks in advance.
HTML:
<div ng-if="::!data.isValid && !data.emptyStateTemplate" class="panel panel-default">
<div class="panel-body wrapper-lg text-center">
<span ng-if="!data.tableUnsupported">${Record not found}</span>
<span ng-if="data.tableUnsupported">${Form view not supported for requested table}</span>
</div>
</div>
<div ng-if="!data.isValid && data.emptyStateTemplate" class="panel-shift">
<div class="empty-state-wrapper panel panel-default" ng-include="data.emptyStateTemplate"></div>
</div>
<div ng-if="data.isValid" class="panel-shift">
<div class="" ng-if="!data.f._view.length && data.hideRelatedLists && data.emptyStateTemplate">
<div class="empty-state-wrapper panel panel-default" ng-include="data.emptyStateTemplate"></div>
</div>
<div class="" ng-if="!data.f._view.length && data.hideRelatedLists && !data.emptyStateTemplate">
<div class="panel panel-default">
<div class="panel-heading"><span class="panel-title">{{data.f.title}}</span> <span ng-if="::options.showFormView == 'true' && data.f.view != ''">[{{data.f.view_title}} view]</span></div>
<div class="panel-body wrapper-lg text-center">
${No elements to display}
</div>
</div>
</div>
<!-- readOnly due to scope -->
<div ng-if="isPageReady && data.f.outOfScope" class="read-only-message">
<div class="alert alert-info sp-cross-scope" role="alert">
<p>${This record is in the <strong>{{data.f.recordScopeLabel}}</strong> application, but <strong>{{data.f.currentScopeLabel}}</strong> is the current application.}</p>
</div>
</div>
<div ng-show="isPageReady" class="panel panel-default" ng-if="data.f._view.length || !data.hideRelatedLists" >
<div class="panel-heading" ng-if="data.f.title.length" sp-context-menu="getUIActionContextMenu(event)">
<span class="dropdown m-r-xs" ng-if="(data.isAdmin || getUIActions('context').length > 0) && options.omitHeaderOptions != 'true'">
<button aria-label="${{{data.f.label}} Form menu}" title="${{{data.f.label}} Form menu}" class="btn btn-form-menu dropdown-toggle glyphicon glyphicon-menu-hamburger" style="line-height: 1.4em" id="adminMenu" data-toggle="dropdown" data-placement="bottom" aria-haspopup="true" aria-expanded="false" autofocus="true"></button>
<ul class="dropdown-menu" aria-labelledby="adminMenu">
<li ng-if="::data.isAdmin"><a ng-href="/{{data.f.table}}.do?sys_id={{data.f.sys_id}}&sysparm_view={{data.f.view}}" target="_blank" tabindex="-1">${Open in platform}</a></li>
<li ng-if="::data.isAdmin" class="dropdown-header" tabindex="-1">${Configure}</li>
<li ng-if="::data.isAdmin"><a href="/slushbucket.do?sysparm_referring_url={{adminMenu.encodedPageUrl}}&sysparm_list={{data.f._sections[0].id}}&sysparm_form=section&sysparm_view={{data.f.view}}" target="_blank" tabindex="-1">${Form Layout}</a></li>
<li ng-if="::data.isAdmin"><a href="/slushbucket.do?sysparm_referring_url={{adminMenu.encodedPageUrl}}&sysparm_list={{data.f.table}}&sysparm_form=related_list&sysparm_view={{data.f.view}}" target="_blank" tabindex="-1">${Related Lists}</a></li>
<li ng-if="::data.isAdmin"><a href="?id=lf&table=sys_ui_policy&filter=table%3D{{data.f.table}}%5EORtableIN{{data.tableHierarchy}}%5Eactive%3Dtrue%5Eui_type%3D1%5EORui_type%3D10" ng-click="openRelatedList($event, {id:'lf', table: 'sys_ui_policy', filter: 'table%3D{{data.f.table}}%5EORtableIN{{data.f.table}},sys_metadata%5Eactive%3Dtrue%5Eui_type%3D1%5EORui_type%3D10'})" tabindex="-1">${UI Policies} <span class="badge pull-right" ng-if="f.policy.length">{{f.policy.length}}</span></a></li>
<li ng-if="::data.isAdmin"><a href="?id=lf&table=sys_script_client&filter=table%3D{{data.f.table}}%5EORtableIN{{data.tableHierarchy}}%5Eactive%3Dtrue%5Eui_type%3D1%5EORui_type%3D10" ng-click="openRelatedList($event, {id: 'lf', table: 'sys_script_client', filter: 'table%3D{{data.f.table}}%5EORtableIN{{data.f.table}},sys_metadata%5Eactive%3Dtrue%5Eui_type%3D1%5EORui_type%3D10'})" tabindex="-1">${Client Scripts} <span class="badge pull-right" ng-if="adminMenu.getClientScriptCount()">{{adminMenu.getClientScriptCount()}}</span></a></li>
<li ng-if="getUIActions('context').length > 0 && data.isAdmin" role="separator" class="divider"></li>
<li ng-repeat="action in getUIActions('context')"><a href="" ng-click="triggerUIAction(action)" tabindex="-1">{{action.name}}</a></li>
<li ng-if="::data.isAdmin || getUIActions('context').length > 0" role="separator" class="divider"></li>
<li><a target="_new" href="/{{data.f.table}}.do?PDF&sys_id={{data.sys_id}}&sysparm_view={{data.f.view}}" tabindex="-1">${Export to PDF}</a></li>
<li><a target="_new" href="/{{data.f.table}}.do?PDF&landscape=true&sys_id={{data.sys_id}}&sysparm_view={{data.f.view}}" tabindex="-1">${Export to PDF (landscape)}</a></li>
</ul>
</span>
<!-- optional "Open in platform" link when omitHeaderOptions is true -->
<span class="dropdown m-r-xs" ng-if="::data.isAdmin && options.omitHeaderOptions == 'true' && options.ensurePlatformLink == 'true'">
<button aria-label="${{{data.f.label}} Form menu}" title="${{{data.f.label}} Form menu}" class="btn btn-form-menu dropdown-toggle glyphicon glyphicon-menu-hamburger" style="line-height: 1.4em" id="platformLink" data-toggle="dropdown" data-placement="botton" aria-haspopup="true" aria-expanded="false"></button>
<ul class="dropdown-menu" aria-labelledby="platformLink">
<li><a ng-href="/{{data.f.table}}.do?sys_id={{data.f.sys_id}}&sysparm_view={{data.f.view}}" target="_blank" tabindex="-1">${Open in platform}</a></li>
</ul>
</span>
<span class="panel-title" role="heading" aria-level="{{embeddedInModal ? '1' : '2'}}">{{data.f.title}}</span> <span ng-if="::options.showFormView == 'true' && data.f.view != ''">[{{data.f.view_title}} view]</span>
<div ng-if="::attachmentHandler && data.canAttach" title="{{::data.addAttachmentMsg}}" class="pull-right attachment-button">
<sp-attachment-button modal="true" supported-extensions="{{::data.supportedAttachmentExtensions}}"></sp-attachment-button>
</div>
<div ng-if="embeddedInModal && isCloseButtonDisplayed">
<i class="fa fa-close text-base sp-form-modal-close-button" ng-click="cancel()" role="button" aria-label="{{data.closeWindowMsg}}" tabindex="0" data-original-title="{{data.closeWindowMsg}}" data-toggle="tooltip" data-placement="bottom"></i>
</div>
</div>
<div class="panel-body">
<!-- performance debug -->
<div ng-if="data.show_sql">
<div class="comment">
<span ng-if="data.f._perf.sql_count">${SQL Statements {{data.f._perf.sql_count}}}, </span>
<span>${Time {{data.f._perf.time}}}</span>
</div>
<div ng-repeat="s in data.f._perf.sql" class="{{s.type}}">
{{s.statement}}
</div>
</div>
<!-- attachments -->
<sp-attachment-manager table="::data.table" sys-id="data.f._attachmentGUID" omit-edit="::!data.canAttach"></sp-attachment-manager>
<!-- asterisk info text -->
<div ng-if="mandatory.length > 0" class="asterisk-div">
<span class="fa fa-asterisk asterisk mandatory" title="${asterisk}"></span> ${Indicates required}
</div>
<!-- form -->
<form id="widget-form">
<div>
<sp-model form_model="data.f" mandatory="mandatory" embedded_in_modal="embeddedInModal"></sp-model>
</div>
</form>
<!-- UI Action Links -->
<!-- <div ng-if="getUIActions('link').length > 0">
<label class="h4" role="heading" aria-level="{{embeddedInModal ? '2' : '3'}}" style="margin: 0;">${Related Links}</label>
<nav aria-label="${Related Links}">
<div ng-repeat="action in getUIActions('link')">
<a href ng-click="triggerUIAction(action)" gsft_id="{{::action.sys_id}}">{{::action.name}}</a>
</div>
</nav>
</div>-->
<!-- related lists -->
<div>
<sp-widget widget="data.editChangeReqDataTableWidget"></sp-widget>
</div>
</div>
<!-- <div class="panel-footer">
<!-- Rework Button -->
<div style="display: flex; gap: 10px;">
<sp-widget widget="data.rework"></sp-widget>
<sp-widget widget="data.withdraw"></sp-widget>
<sp-widget widget="data.cancel"></sp-widget>
</div>
</div>
</div>
Client Script:
Server side:
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
4 weeks ago
Thanks for pasting all that — I can see exactly what’s happening.
When you clone the Form widget into a scoped app, attachments usually don’t show up for two reasons:
Why Attachments Fail in Scoped Clone
-
Cross-scope issue
-
The out-of-box Form widget uses the nowAttachmentHandler service, which is in the global scope.
-
If you clone the widget into a custom scope, your version may not have the right access to call it.
-
-
Attachment params not wired up
-
The <sp-attachment-manager> directive needs:
<sp-attachment-manager table="::data.table" sys-id="data.f._attachmentGUID" omit-edit="::!data.canAttach"> </sp-attachment-manager> -
If data.f._attachmentGUID is blank or data.canAttach is false, no attachments render.
-
What to Check / Fix
1. Ensure your scoped widget has access to nowAttachmentHandler
-
In the client controller you already have:
function($rootScope, $scope, ..., nowAttachmentHandler, ...) -
That injection will break if the scoped app does not include the dependency.
-
Solution:
-
In your scoped widget, make sure "Accessible from" is set to All application scopes (not just this scope).
-
Or create a Dependency record in sys_script_include to allow cross-scope calls.
-
2. Verify you are passing correct sys_id
-
In your controller:
var tableId = $scope.data.sys_id != -1 ? $scope.data.sys_id : ($scope.data.f ? $scope.data.f._attachmentGUID : -1); -
Make sure data.sys_id is set correctly in the server script. If this resolves to -1, the widget will think you are on a “new record” and won’t render attachments.
Try hard-coding temporarily:
If that works → your problem is in how data.f._attachmentGUID is populated.
3. Set data.canAttach correctly
-
In your server script, you currently commented this:
/* data.canAttach = !options.omitAttachmentButton && hasRecordAccess && ... */ -
If data.canAttach is undefined or false, <sp-attachment-manager> will render nothing.
-
Make sure to set it explicitly:
data.canAttach = true;
4. Debugging Tip
From your browser console (in the portal):
This should show you if the directive has any attachments loaded.
If you found my response helpful, I would greatly appreciate it if you could mark it as "Accepted Solution" and "Helpful."
Your support not only benefits the community but also encourages me to continue assisting. Thank you so much!
Thanks and Regards
Ravi Gaurav | ServiceNow MVP 2025,2024 | ServiceNow Practice Lead | Solution Architect
CGI
M.Tech in Data Science & AI
YouTube: https://www.youtube.com/@learnservicenowwithravi
LinkedIn: https://www.linkedin.com/in/ravi-gaurav-a67542aa/
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
4 weeks ago
Thanks for pasting all that — I can see exactly what’s happening.
When you clone the Form widget into a scoped app, attachments usually don’t show up for two reasons:
Why Attachments Fail in Scoped Clone
-
Cross-scope issue
-
The out-of-box Form widget uses the nowAttachmentHandler service, which is in the global scope.
-
If you clone the widget into a custom scope, your version may not have the right access to call it.
-
-
Attachment params not wired up
-
The <sp-attachment-manager> directive needs:
<sp-attachment-manager table="::data.table" sys-id="data.f._attachmentGUID" omit-edit="::!data.canAttach"> </sp-attachment-manager> -
If data.f._attachmentGUID is blank or data.canAttach is false, no attachments render.
-
What to Check / Fix
1. Ensure your scoped widget has access to nowAttachmentHandler
-
In the client controller you already have:
function($rootScope, $scope, ..., nowAttachmentHandler, ...) -
That injection will break if the scoped app does not include the dependency.
-
Solution:
-
In your scoped widget, make sure "Accessible from" is set to All application scopes (not just this scope).
-
Or create a Dependency record in sys_script_include to allow cross-scope calls.
-
2. Verify you are passing correct sys_id
-
In your controller:
var tableId = $scope.data.sys_id != -1 ? $scope.data.sys_id : ($scope.data.f ? $scope.data.f._attachmentGUID : -1); -
Make sure data.sys_id is set correctly in the server script. If this resolves to -1, the widget will think you are on a “new record” and won’t render attachments.
Try hard-coding temporarily:
If that works → your problem is in how data.f._attachmentGUID is populated.
3. Set data.canAttach correctly
-
In your server script, you currently commented this:
/* data.canAttach = !options.omitAttachmentButton && hasRecordAccess && ... */ -
If data.canAttach is undefined or false, <sp-attachment-manager> will render nothing.
-
Make sure to set it explicitly:
data.canAttach = true;
4. Debugging Tip
From your browser console (in the portal):
This should show you if the directive has any attachments loaded.
If you found my response helpful, I would greatly appreciate it if you could mark it as "Accepted Solution" and "Helpful."
Your support not only benefits the community but also encourages me to continue assisting. Thank you so much!
Thanks and Regards
Ravi Gaurav | ServiceNow MVP 2025,2024 | ServiceNow Practice Lead | Solution Architect
CGI
M.Tech in Data Science & AI
YouTube: https://www.youtube.com/@learnservicenowwithravi
LinkedIn: https://www.linkedin.com/in/ravi-gaurav-a67542aa/
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
4 weeks ago
@Ravi Gaurav
Thanks for your response🙂.