- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-12-2022 09:26 AM
I have a page, under the old interface, creating a new record in a custom table. From that page, a button can be hit that will create a URL with a bunch of custom parameters (basically, pulled out of the field values for this new record) that whisks the user off to a Service Catalog page and fills in many of the fields of the SC page with the values from the old page. Cool.
Now, we're trying to take this page over to working under Service Portal. Obviously, the action.setRedirectUrl() from the old page wasn't going to work. After playing with that for a bit, I set the 'Client' flag on the UI action, so it didn't appear.
My next thought was to set a Business Rule on the insert that would do gs.getSession().putClientData() repeatedly, then do a gs.setRedirect() to the correct Service Portal Service Catalog page. This, as near as I can tell, did nothing. First question, was this a dumb idea?
My second thought involves creating a custom page with a Form widget on top (perhaps a custom version of the Form widget with some custom options). I created the custom copy, adding two options: table and fields. Next question: the fields were of type field_list, but when I try to select the fields, it never finishes giving me the list of fields (even though the table is selected, and the form is showing the fields for the correct table). Any idea why?
More importantly, using the Form widget would seem to require a button of some sort to get to the correct page. I added a link-button at the bottom of the page with the correct URL; that will take me to the correct SC page, but without any values pre-loaded. Final question: is there a way to do that preloading? (I was thinking maybe with a script on the custom Form widget that would tack on parameter values to the link-button's href field, but I'm not seeing a way to do that.)
Thanks for any suggestions,
Dave
Solved! Go to Solution.
- Labels:
-
Service Portal Development
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-06-2022 09:57 AM
Ok, it's a little bit painful (and arguably underhanded), but I have come up with a solution.
I was coming from using /sp?id=form&table=whatever, so my solution starts with using the Form widget. If you're starting from a different spot, you will need to adapt this solution. (Also note that I am working on an isolated network, so I could not cut and paste across. Therefore, caveat lector and double- or triple-check for typos.)
step one: create a new Service Portal page, we'll call it ForwardForm
step two: create a clone of the Form widget, we'll call it "Forwarding Form Widget"
step three: create a clone of the icon link widget, we'll call it "Data Forwarding Link"
step four: add the "Forwarding Form Widget" and "Data Forwarding Link" to the ForwardForm page
step five: Set the Link options Type=URL, HREF of the base URL to which you want the link to connect (for instance, for me it was "/sp?id=sc_cat_item&sys_id=..."), Title to desired value, and Template to whichever is preferred.
step six (optional): I found it convenient to add a 'Default table' option to my "Forwarding Form Widget"
step seven: Within the "Forwarding Form Widget", within the Client Script, add the following two blocks:
var g_form;
$scope.$on('spModel.gForm.initialized', function(e, gFormInstance) {
g_form = gFormInstance;
});
$rootScope.$on('field.change', function(evt,parms) {
// note that this is an undocumented method, but using it
// will make your life much easier. I had an alternative, but
// it was very cumbersome, and likely to fail in various corner
// cases. Still, this could break on system upgrades.
var flds = g_form.getEditableFields();
var valueMap = {};
for (var i = 0; i < flds.length; i++) {
// isUserModifed(field) is also undocumented, but will likely
// improve efficiency. Not terribly important.
if (g_form.getValue(flds[i]) && g_form.isUserModified(flds[i])) {
valueMap[flds[i]] = g_form.getValue(flds[i]);
}
}
$rootScope.$broadcast('fieldUpdate', valueMap);
});
step eight: within the "Data Forwarding Link", in the HTML, there are several lines of <a ng-if="..." ng-href="..."...> ... </a>. On each of these lines (or at least the one corresponding to the Template chosen in step five), change ng-href="{{::data.href}}" to ng-click="c.getUrl()" ng-href="{{::data.finalHref}}"
step nine: in the Client Controller, replace the script with:
function($scope, $rootScope, spAriaUtil, spUtil) {
var c = this;
c.href = $scope.data.href;
$scope.accessibilityModeEnabled = spAriaUtil.isAccessibilityEnabled();
$rootScope.$on('fieldUpdate', function (evt, args) {
var baseUrl = c.href;
for (var k in args) {
if (args.hasOwnProperty(k) && args[k]) {
baseUrl += "&sysparm_" + k + "=" + args[k];
}
}
c.tempHref = baseUrl;
});
c.getUrl = function() {
$scope.data.finalHref = c.tempHref;
};
}
step eleven: Your target page will now be opened with a URL with extra sysparm_ variables. Make sure that that page has an onLoad() Client Script that will parse those variables, and apply them as needed. This is left as an exercise for the reader.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-12-2022 05:21 PM
Look up Page Route Maps - this redirects one portal page to the other
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-15-2022 05:06 AM
I like the idea, but unless I'm missing two things, it doesn't help here. 1) It looks like the route destination can only be a generic page (id=sc_cat_item, for instance, rather than to id=sc_cat_item&sys_id=X&sysparm_category=Y). 2) I don't see any way to pass any data to that page (but maybe there's an underhanded way via a Business Rule stuffing that data into the session?).
Am I missing anything?
Thanks,
Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-15-2022 09:02 AM
Addendum question: It doesn't seem that stuffing values into the GlideSession would help, as I don't see any way to get that in a Service Catalog Item (since it's server side only). Is there a way to run server side code as an "onLoad" to a catalog item (scare quotes because I know I'm mangling terminology there, but I can't think of a better term)?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-06-2022 09:57 AM
Ok, it's a little bit painful (and arguably underhanded), but I have come up with a solution.
I was coming from using /sp?id=form&table=whatever, so my solution starts with using the Form widget. If you're starting from a different spot, you will need to adapt this solution. (Also note that I am working on an isolated network, so I could not cut and paste across. Therefore, caveat lector and double- or triple-check for typos.)
step one: create a new Service Portal page, we'll call it ForwardForm
step two: create a clone of the Form widget, we'll call it "Forwarding Form Widget"
step three: create a clone of the icon link widget, we'll call it "Data Forwarding Link"
step four: add the "Forwarding Form Widget" and "Data Forwarding Link" to the ForwardForm page
step five: Set the Link options Type=URL, HREF of the base URL to which you want the link to connect (for instance, for me it was "/sp?id=sc_cat_item&sys_id=..."), Title to desired value, and Template to whichever is preferred.
step six (optional): I found it convenient to add a 'Default table' option to my "Forwarding Form Widget"
step seven: Within the "Forwarding Form Widget", within the Client Script, add the following two blocks:
var g_form;
$scope.$on('spModel.gForm.initialized', function(e, gFormInstance) {
g_form = gFormInstance;
});
$rootScope.$on('field.change', function(evt,parms) {
// note that this is an undocumented method, but using it
// will make your life much easier. I had an alternative, but
// it was very cumbersome, and likely to fail in various corner
// cases. Still, this could break on system upgrades.
var flds = g_form.getEditableFields();
var valueMap = {};
for (var i = 0; i < flds.length; i++) {
// isUserModifed(field) is also undocumented, but will likely
// improve efficiency. Not terribly important.
if (g_form.getValue(flds[i]) && g_form.isUserModified(flds[i])) {
valueMap[flds[i]] = g_form.getValue(flds[i]);
}
}
$rootScope.$broadcast('fieldUpdate', valueMap);
});
step eight: within the "Data Forwarding Link", in the HTML, there are several lines of <a ng-if="..." ng-href="..."...> ... </a>. On each of these lines (or at least the one corresponding to the Template chosen in step five), change ng-href="{{::data.href}}" to ng-click="c.getUrl()" ng-href="{{::data.finalHref}}"
step nine: in the Client Controller, replace the script with:
function($scope, $rootScope, spAriaUtil, spUtil) {
var c = this;
c.href = $scope.data.href;
$scope.accessibilityModeEnabled = spAriaUtil.isAccessibilityEnabled();
$rootScope.$on('fieldUpdate', function (evt, args) {
var baseUrl = c.href;
for (var k in args) {
if (args.hasOwnProperty(k) && args[k]) {
baseUrl += "&sysparm_" + k + "=" + args[k];
}
}
c.tempHref = baseUrl;
});
c.getUrl = function() {
$scope.data.finalHref = c.tempHref;
};
}
step eleven: Your target page will now be opened with a URL with extra sysparm_ variables. Make sure that that page has an onLoad() Client Script that will parse those variables, and apply them as needed. This is left as an exercise for the reader.