- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-23-2018 03:42 PM
I have cloned an OOB form widget (widget-form), Issue is when user clicks on reference info icon (i) on my cloned widget (my-widget-form) the reference information is opening in widget-form instead of my-widget-form.
below ng-click is calling showForm(data); javascript function
ng-click="openReference(field, formModel.view)
in the below function if you see line 2 , its setting the form widget ID, now my goal is to set the widget ID to my-widget-form instead of widget-form.
function showForm(data) {
var url = spUtil.getWidgetURL("widget-form");
var req = {
method : 'POST',
url : url,
headers : spUtil.getHeaders(),
data : data
}
$http(req).then(qs, qe);
function qs(response) {
var r = response.data.result;
showModal(r);
}
function qe(error) {
console.error("Error " + error.status + " " + error.statusText);
}
}
Is there a way I can override the whole opeReference method from my cloned widget?
Solved! Go to Solution.
- Labels:
-
Service Portal Development

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-24-2018 08:53 AM
I think in order to do what you want, you will likely have to override the spReferenceField directive. I learned a trick from SNOW on how to use angular decorators to do that. You could probably use a decorator to just override the controller (which is where the showForm function is), but the controller makes up the vast majority of the directive, so may as well override the whole thing. I did it by putting this in a UI Script and adding this as a dependency to my portal. This worked for me. Just remember in the showForm method below, to put your form widget in there. And of course the down side of doing this is that during any upgrades, you may have to merge fixes/new functionality provided in updated spReferenceField directives into your custom one.
/*! RESOURCE: /scripts/app.$sp/directive.spReferenceField.js */
angular.module('sn.$sp').directive('spReferenceField', function($rootScope, spUtil, $uibModal, $http, spAriaUtil, i18n) {
'use strict';
return {
restrict: 'E',
replace: true,
templateUrl: 'sp_reference_field.xml',
controller: function($scope) {
var unregister;
$scope.openReference = function(field, view) {
var data = {
table: field.ed.reference,
sys_id: field.value,
view: view
};
if (angular.isDefined(field.reference_key))
data[field.reference_key] = field.value;
else
data.sys_id = field.value;
if (unregister)
unregister();
unregister = $rootScope.$on('$sp.openReference', function(evt, data) {
unregister();
unregister = null;
if (!evt.defaultPrevented && evt.targetScope === $scope)
showForm(data);
});
$scope.$emit('$sp.openReference', data);
};
$scope.$on("$destroy", function() {
if (unregister)
unregister();
});
function showForm(data) {
var url = spUtil.getWidgetURL("widget-form");
var req = {
method : 'POST',
url : url,
headers : spUtil.getHeaders(),
data : data
};
$http(req).then(qs, qe);
function qs(response) {
var r = response.data.result;
showModal(r);
}
function qe(error) {
console.error("Error " + error.status + " " + error.statusText);
}
}
function showModal(form) {
var opts = {
size : 'lg',
templateUrl : 'sp_form_modal',
controller : ModalInstanceCtrl,
resolve : {
}
};
opts.resolve.item = function() {
return angular.copy({
form : form
});
};
var modalInstance = $uibModal.open(opts);
modalInstance.result.then(function() {}, function() {
spAriaUtil.sendLiveMessage($scope.exitMsg);
});
$scope.$on("$destroy", function() {
modalInstance.close();
});
var unregister = $scope.$on('sp.form.record.updated', function(evt, fields) {
unregister();
unregister = null;
modalInstance.close();
if (evt.stopPropagation)
evt.stopPropagation();
evt.preventDefault();
});
}
function ModalInstanceCtrl($scope, $uibModalInstance, item) {
$scope.item = item;
$scope.ok = function() {
$uibModalInstance.close();
};
$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
}
},
link: function(scope) {
i18n.getMessage("Closing modal page", function(msg){
scope.exitMsg = msg;
});
}
};
}).decorator("spReferenceFieldDirective", function($delegate) { return( [ $delegate[1] ] );});

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-24-2018 08:53 AM
I think in order to do what you want, you will likely have to override the spReferenceField directive. I learned a trick from SNOW on how to use angular decorators to do that. You could probably use a decorator to just override the controller (which is where the showForm function is), but the controller makes up the vast majority of the directive, so may as well override the whole thing. I did it by putting this in a UI Script and adding this as a dependency to my portal. This worked for me. Just remember in the showForm method below, to put your form widget in there. And of course the down side of doing this is that during any upgrades, you may have to merge fixes/new functionality provided in updated spReferenceField directives into your custom one.
/*! RESOURCE: /scripts/app.$sp/directive.spReferenceField.js */
angular.module('sn.$sp').directive('spReferenceField', function($rootScope, spUtil, $uibModal, $http, spAriaUtil, i18n) {
'use strict';
return {
restrict: 'E',
replace: true,
templateUrl: 'sp_reference_field.xml',
controller: function($scope) {
var unregister;
$scope.openReference = function(field, view) {
var data = {
table: field.ed.reference,
sys_id: field.value,
view: view
};
if (angular.isDefined(field.reference_key))
data[field.reference_key] = field.value;
else
data.sys_id = field.value;
if (unregister)
unregister();
unregister = $rootScope.$on('$sp.openReference', function(evt, data) {
unregister();
unregister = null;
if (!evt.defaultPrevented && evt.targetScope === $scope)
showForm(data);
});
$scope.$emit('$sp.openReference', data);
};
$scope.$on("$destroy", function() {
if (unregister)
unregister();
});
function showForm(data) {
var url = spUtil.getWidgetURL("widget-form");
var req = {
method : 'POST',
url : url,
headers : spUtil.getHeaders(),
data : data
};
$http(req).then(qs, qe);
function qs(response) {
var r = response.data.result;
showModal(r);
}
function qe(error) {
console.error("Error " + error.status + " " + error.statusText);
}
}
function showModal(form) {
var opts = {
size : 'lg',
templateUrl : 'sp_form_modal',
controller : ModalInstanceCtrl,
resolve : {
}
};
opts.resolve.item = function() {
return angular.copy({
form : form
});
};
var modalInstance = $uibModal.open(opts);
modalInstance.result.then(function() {}, function() {
spAriaUtil.sendLiveMessage($scope.exitMsg);
});
$scope.$on("$destroy", function() {
modalInstance.close();
});
var unregister = $scope.$on('sp.form.record.updated', function(evt, fields) {
unregister();
unregister = null;
modalInstance.close();
if (evt.stopPropagation)
evt.stopPropagation();
evt.preventDefault();
});
}
function ModalInstanceCtrl($scope, $uibModalInstance, item) {
$scope.item = item;
$scope.ok = function() {
$uibModalInstance.close();
};
$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
}
},
link: function(scope) {
i18n.getMessage("Closing modal page", function(msg){
scope.exitMsg = msg;
});
}
};
}).decorator("spReferenceFieldDirective", function($delegate) { return( [ $delegate[1] ] );});
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-24-2018 09:07 AM
Thank you for your response, I am still new to the angular and service portal world.
I have one final request, Do you mind posting the screenshot of your UI script and how to add the UI script as the dependency to the widget.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-24-2018 09:15 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-24-2018 09:40 AM
Thank you so much for your help, I was able to override the spReferenceField directive and its all good now.
now i have learn more about decorator.