Ever wonder how to embed a Service Portal widget into a form and have it access fields in the parent form? GlideForm to the rescue!
GlideForm is a client-side JavaScript API that provides methods to customize forms. Use the g_form object to access all of the GlideForm API methods.
When using the Service Catalog variable types Macro or “Macro with Label”, you can embed a Service Portal widget into the form. Within the client controller of the embedded widget you have access to both g_form and the field object by accessing them from the page object on $scope:
- $scope.page.field
- $scope.page.g_form
FEATURES
GlideForm supports over 50 different methods of accessing and manipulating form fields, in this quick tutorial, we will cover just a few of the most frequently used functions:
- getValue()
- setValue()
- getFieldNames()
- setVisible()
- setReadOnly()
- setMandatory()
You can view the full list of supported g_form methods here.
WALKTHROUGH
To get started:
- Add a new variable with type “Macro” to a catalog item with a few existing variables
- From the “Type Specifications” tab, click on the Widget reference field picker and select “New”
- Name your widget and submit
- Navigate to “/sp_config/?id=widget_editor” and select your newly created widget
- Paste in the following code.
HTML:
1 2 3 4 5 6 7 | <div> <button class="btn btn-primary" ng-click="setReadOnlyAll(true)">Disable All</button> <button class="btn btn-primary" ng-click="setReadOnlyAll(false)">Enable All</button> <button class="btn btn-primary" ng-click="toggleVisible('FIELDNAME')">Toggle</button> <button class="btn btn-primary" ng-click="getValue('FIELDNAME')">Get Value</button> <button class="btn btn-primary" ng-click="setMandatory('FIELDNAME',true)">Set Mandatory</button> </div> |
Client Script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | function($scope) { var g_form = $scope.page.g_form; var field = $scope.page.field; // See all the methods available console.log(g_form); // Set read only of all fields $scope.setReadOnlyAll = function(bool) { var fields = g_form.getFieldNames(); for (var i in fields) { g_form.setReadOnly(fields[i],bool); } } // Toggle the visibility of a field $scope.toggleVisible = function(field) { var isVisible = g_form.isVisible(field); g_form.setVisible(field,!isVisible); } // set field as mandatory $scope.setMandatory = function(field,bool) { g_form.setMandatory(field,bool); } // alert with field label and value $scope.getValue = function(field) { var field_obj = g_form.getField(field); var value = g_form.getValue(field); alert(field_obj.label + ": " + value); } } |
- Update the field names (FIELDNAME) in the HTML to match some fields from your form
- Now if you view the catalog item in the portal, you should see your widget embedded in the form displaying 5 buttons.
DEMO
Another great article.. Thanks Nathan…
Love your videos. Please keep them coming!
Hello Nathan, thanks a lot. This is very helpful for some of our requirements. Maybe it would be good to refer to this older post: https://serviceportal.io/embedding-widgets-in-service-catalog/
It would be great if you could add some samples how to interact with “default” Catalog Item varaibles and react “inside” the widget on changes of these varaiables values. I saw solution using recordWatch(), but cannot find it anymore.
Thx a lot
I will typically use $scope.$watch and g_form to achieve this functionality. i.e.
$scope.$watch(function() {
return $scope.page.g_form.getValue(‘FIELDNAME’);
}, function(value){
//do something
});
Hi, Is it possible to show the embedded list in the serviceportal forms? Any workarounds please suggest.
Fantastic. 🙂
Hi Nathan,
Does the functionality supports in Kingston.
As I have used your code and changed the color of “variable” name on catalog item, on-click of button in london version.
And Did same functionality in “Kingston”, I am unable to get results as expected.Their is no change in the color.
Tried this code in london working fine but not in kingston:
HTML code:
Toggle
Client Controller:
function($scope){
var field = $scope.page.field;
$scope.colorChange = function(field){
var change = = document.getElementById(field);
change.style.color=’red’;
}
}
If you console.log the fields list you will see that the field names changed in London to using “IO:SYS_ID”
The reason your code doesn’t work is in the auto generated ID, you will see semicolon (:). You need to scape it by adding \ or remove it…
Good One
It really helped us!! Thanks a ton.
Hi Nathan,
Need your help on what is $private in $scope.page.g_form.$private.emit.on(‘submit’, callback);
Is there any place where we can see what variables we have on $private
how can we pass g_form.getValue() to Jelly .
Hi,
I need suggestion on portal requirement.
I calling a modal on submit , where user will provide input which I need to set in one of the field.
g_form.setValue() is not working from client controller.
Could anyone help me how to set value from client controller?