Modal windows in Service Portal are based on the BootstrapUI directives. For further documentation see: https://angular-ui.github.io/bootstrap/#/modal
Below is a simple example of how to open up a modal window:
Controller:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function($uibModal, $scope) { var c = this; c.openModal = function() { c.modalInstance = $uibModal.open({ templateUrl: 'modalTemplate', scope: $scope }); } c.closeModal = function() { c.modalInstance.close(); } } |
HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <div> <button class="btn btn-primary" ng-click="c.openModal()">${Open Modal}</button> </div> <script type="text/ng-template" id="modalTemplate"> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title">Modal Window</h4> </div> <div class="panel-body wrapper-xl"> Hello </div> <div class="panel-footer text-right"> <button class="btn btn-primary" ng-click="c.closeModal()">${Close Modal}</button> </div> </div> </script> |
Notes:
- Make sure the $uibModal service and $scope is included in the controller.
- In this example the modal template is just included in the HTML, but you could also set the “templateURL” property to an ng-template associated with this widget.
- You can manually pass in the scope to the template using the “scope” property.
Thanks Nathan! Looking forward to using this with a set of ng-templates that will represent different modal content for different situations based on widget interactions!
Hi Nathan,
I posted some service portal questions on the SN community but I haven’t received any answers from anyone. I hope you can help me 🙂
The questions are below
https://community.servicenow.com/thread/233895
https://community.servicenow.com/thread/234601
Thanks.
This is a nice example for displaying some information, thanks!
Do you have any suggestions on how to make something like what they have done in the example in https://angular-ui.github.io/bootstrap/#/modal? I can’t quite get how to use different controllers in ServiceNow like they have done in the example.
If you wish to have a separate controller for the contents of the modal, just embed another widget as the content within the modal.
Thanks for the answer! I will for sure try it within a couple of weeks and write a small tutorial which I’ll link here!
Hi Nathan,
Is there the possibility to pass some arguments to the modal window? I want it’s body to change based on an argument. I tried passing an object to the c.openModal function but when I tried to log it, it always logs undefined.
Thanks
Nevermind that question Nathan, it was my bad. I can send the argument (an object). But now how can I use on the object’s properites (a String) as the content in the body of the modal window?
A few years late, but maybe will still help someone 🙂 this is how I pass arguments to the modal:
var customObj = {test:true}
var approveModal = $uibModal.open({
templateUrl: templateUrl,
controller: popupController,
controllerAs: ‘ctrl’,
resolve: {
item: function() {
return customObj;
}
}
});
key here is the resolve option, this will make the customObj accessible in the popupController under property ,,item,, (name can be changed)
code for controller: (declared in the same client controller as previous code)
function popupController($scope, $uibModalInstance, item) {
var ctrl = this;
ctrl.item = item;
}
then you can access the customObj in the modal template as {{ctrl.item}}
Thanks Patrik. You made my day.
Thanks I found this hack because you cared to post the answer
Dear Nathan,
First, thank you very much for your site and articles. Really valuable content!
Then, I am trying to understand why sn portal is triggering a request as soon as I open a modal just like you have described it.
This is the (anonymised) url of my page opening the modal
https://my-instance-name.service-now.com/bms/bms?id=name_of_my_page&url_param_one=f12ba5ba4f4366004f32bc511310c7d6&url_param_two=de
as soon as the modal is opened, this request is performed.
Noteworthy imho is the resource /api/now/sp/page, the time and portal_id url parameters and the fact that the url of my page is repeated twice.
The content is some json containing quite some stuff about my page/portal (81kB)
https://my-instance-name.service-now.com/api/now/sp/page?id=name_of_my_page&url_param_one=f12ba5ba4f4366004f32bc511310c7d6&url_param_two=de&time=1479727550061&portal_id=daca4c67378ce20003271d8643990e18&request_uri=%2Fbms%2Fbms%3Fid%3Dname_of_my_page%26url_param_one%3Df12ba5ba4f4366004f32bc511310c7d6%26url_param_two%3Dde
More interesting is that this request is performed only once when the modal is opened for the first time after a fresh login. Later on, this request is no longer made.
My problem is that upon return of this request, the ng-model of my page gets reset to its initial value, thus loosing any field changes that might have been entered prior to opening the modal.
Any idea on what’s going on here? Why is sn portal performing this request?
[RESOLVED] the trigger for the modal was an tag with an href=”#” and an ng-click calling my modal. Obviously this lead to the page being reloaded.
I changed that tag to with only the ng-click attribute and all is now working as expected.
Sorry for the hassle.
Yet, it’s not clear to me why the former behaviour would appear only once and not on each click. But this is only out of curiosity and is no longer an issue.
Hi Nathan,
I would like to know how I can add dynamic content to the modal body.
I look for ward to your help!
All the best,
Srikha
Of course. On line 7 of the controller you are passing in the scope. So based on the above, whatever is on scope in the controller will also be in scope in the modal.
Thanks! This is what I was looking for as a starting point. We have a long (1.5 pages in Word) license agreement to display, so it seems to make sense to put this in an ng-template instead of the widget html. I have an ng-template associated with the widget, but am having trouble getting the syntax correct to set the templateURL property.
Can we use uiv modal in catalog client script. If no, then what is the alternative for GlideDialogWindow for service portal.
So here is how you could do this… you’ll need to embed a widget in the item as a variable that contains the modal window code and that is listening for an event. You could then trigger the event from the catalog client script.
Hi Nathan, good stuff thanks. I have same question as Malvi. I wonder if we can invoke the widget’s URL in catalog client script replacing the GlideDialogWindow?
Hello I have tried to dd a modal button to a widget but i just get sort of redirected to another page. If your adding a modal to a widget that already had Client Controller script in it do you copy and paste the entire script you put or do you remove parts of it. Also in the CSS portion of it do you have to add anything ?
You controller should consist of a single wrapping function, so you would just bring in the openModal and closeModal methods. No additional CSS needed.
Instead of Hello, I want to pass data into the modal window , I have tried putting in variables but they never show up… Wondering do i edit the html portion, do i edit the client controller portion?
Hi Nathan,
I have a drop down variable on catalog form and I need to call a pop up on one of the drop down option onchange.
As the jelly script will not work on service portal . Can you please let me know if we can call widget pop onChange in client script or any other alternative.
Thanks,
Shailesh
Yes, this can be accomplished by creating a widget that is listening for the “field.change” event and adding the widget as a variable on the catalog item.
Thanks for your update Nathan.
I’m new to service portal. Can you please explain with some example.
I have variable name:- as ‘computer’ which is having two option.
1.mac
2.win
I want to configure a pop up which will come up once mac option is selected.
Your help is very much appreciated.
Regards,
Shailesh
Thanks for this article, no problem to implement this modal.
Do you know the Client Controller script syntax for a show/hide text button. So instead of a modal coming up, the widget I am looking at would expand to show the additional text I pass through. Now I was able to get this to work on one widget using the html area but when i try to scale and add more show info buttons, they expand only the original more info button so I think i need to somehow dynamically pass everything thru the client controller ? Thank you in advance.
Hi Nathan,
How we can increase the size of modal dialog, rather how to add class modal-lg along with modal-dialog..
Thanks,
Girish
Take a look at the documentation for UI Bootstrap. It supports providing your own model template:
https://angular-ui.github.io/bootstrap/
Has anyone been able to make this work with the popover directive?
I have a widget being displayed inside a modal. The widget is a clone of the approvals widget (list of item with approve/reject buttons). The modal appears with the correct approvals listed, and when I click reject, the info message that should appear at the top of the screen doesn’t. What do I need to do to allow infoMessages to appear?
I have not seen this before… can you confirm that the widget generates the info messages if used directly on the page outside of the modal. It also could depend on how you’re embedding the widget, but in general the info messages should render regardless of it’s it’s embedded or used in a modal as long as the server script is being called. Feel free to email me if you’re not able to resolve: nathan.firth@newrocket.com
Hi Nathan,
Thanks for the content. It is wonderful read. I’m trying to accomplish similar thing but in the back-end admin users.
I have a UI Action button that opens a pop-up window that loads another widget that supposed to query different tables and display values. I tried GlideDialogWindow(“widget-name”), but my widget does not work properly in the pop-up, but it works fine when you load the widget in the portal and I also, tried with GlideModal, but GlideModal does not load my widget at all…
I was wondering if you have built similar functionality.
Your help is greatly appreciated.
Dave
Hi Nathan,
I am trying to open a modal popup over a popup.
ex: when a request is submitted I get a success popup. in that popup, I have a button which will open another popup for the survey.
I can open the modal, but it’s failing to load all the bootstraps.
in my first modal popup i have
TAKE A SURVEY
for the second popup my script will be
FeedbackX
Please enter mandatory fields.
Thank you for your feedback!
I am calling my second script by
$scope.openFeedbackModal = function() {
showModal(‘OneClick’);
}
can you suggest me how can I close the first popup when I click the button and this button should enable the second popup
Hi Nathan, I have somewhat of a unique situation that I may be over analyzing but could use some clarity on. I have a modal that is called from a widget just like you have described above. However, my modal contains an embedded widget. I need to pass the data from the embedded widget inside the modal back to the original calling form. How would i go about doing this? Thanks!
An easy way to do this would be to use events. You can check out my post on events here: https://serviceportal.io/using-events-communicate-widgets/
Hey Nathan, I am using your provided example, but am getting a strange TypeError when I close the modal. The console says “TypeError: Cannot read property ‘close’ of undefined”. Any thoughts on why this is showing up? Thanks!
That means you never assigned the modal to an object. In the above example, see in the controller on line 5 how we attach the modal to an object on “c”. If you did that, you will also have access to the “close” method. If you are getting an undefined error, that’s saying that object does not exist.
Hello Nathan,
I have written the below Catalog Client Script to open a PopUp Window.
function onSubmit() {
spModal.open({
title: ‘Dialog Window’,
content: ” +
‘Your name:’ +
” +
‘Your email:’ +
” +
‘Your message:’ +
” +
”,
buttons: [{
label:’Yes’, primary: true,
},
{
label: ‘No’, primary: true,
}]
});
}
Can you help me to accomplish below requirements?
1> popup window is opening without displaying form on it which i defined in “content” of spModal.
2> how can we pass value of fields from catalog item form to spModal Popup Window?
Hi Nathan, Thanks for this custom modal. I am facing some strange issue where the modal opens on first click and from the second click the BG screen fades out but modal doesn’t openup.
I had a button in the modal, on-click of it I call the server script and immediately after response from server I close the modal. But no luck.
Please help me solve this issue.
Can you use an angular modal pop up from within regular servicenow? I tried, using an angular UI page but the angular components don’t render (showing as {{variable}}) as the controller never seems to come to life (if I put console.log statements outside and inside the controller script it never gets within).
I’d much rather use some angular in a UI page than go back to the convoluted jelly method
Any thoughts?
To use Angular.js in a UI page you will need to manually include the Angular.js files and set it up as a new Angular application.
Nathan,
I want to display a modal on the Service Catalog item. I have your example here in a widget and have referenced it in a catalog item as a Macro.
The issue is that the modal does not load the first time I click on “Open Modal”. It starts working when I click the second time. It looks as if the “modalTemplate” does not exist onLoad. Do you have any thoughts on how to tackle this? Thanks for your time.
How are you loading the template? Is it inline in the HTML or in the “ng-template” table referencing the widget?
Nathan,
We tried it as a inline HTML as well as a ng-template. In both the cases, the modal does not popup the first time, it pops up only the second time when the button is clicked.
I know this old, but in case anyone in the future has this issue. Here is what worked for me.
I had to stop using the Angular ng-template I made and use it in-line instead. I also added .html to the id and templateURL.
I have a requirement to auto close the modal window once a record producer is submitted, as users are missing the ootb message that the ticket is submitted, heres the number and go to requests type message. How can we auto close the modal window after record producer is submitted?
Modify the Instance JSON for the catalog item widget and add the following property:
“auto_redirect”: {
“value”: “false”,
“displayValue”: “false”
}
Now instead of redirecting to the ticket page, it will trigger the following event: “$sp.sc_cat_item.submitted”. Update your modal widget to close when this event is fired.
Can I open a modal window from the Servicenow Header menu? How?
I have a custom menu called Contact and it has to pull some information from a table and display on the screen. On submit of that modal, it has to redirect to another Widget.
Hi,
Am adding a record producer in the modal, but whenever i load the modal again without refreshing the page I want the record producer fields to be empty but it is taking the values from the last request.
Please let me know, how I can achieve this?
Hi Prashant,
i am trying to achieve the same, i want to show my recordproducer inside modal window. can you share reference?
Hi Nathan,
This really helped me with modal implementation. Need your help on one more thing.
On click of “Close Model” button I want to create request that means it should directly get redirect to order details page. How can I implement it?
Thanks in advance.
Is there a way to display a KB article inside the content area of the modal widget?
Yes, this should be pretty simple to do. Simple use GlideRecord to fetch the article and place it in scope and then you can display it in the modal content. Another way to do it would be to embed the kb article widget directly in the modal and pass in the sys_id via “options”
I am having an issue embedding the article. By modal content where is that? can you show an example or point me to a similar modal with embedded widget?
Never mind, I figured it out.
I have implemented this successfully, but it is not working on a Mac running Safari. Do you know why that might be and how it could be resolved? Thanks!
Does anyone know how to apply CSS to the popup? Any CSS I try to apply to the HTML inside the script tag does not render.
Thanks!
Hi Matt,
when the modal is triggered, it is actually being added at the top of the page body which is why none of the styles seem to work since the CSS is “scoped” to just that widget’s HTML.
To work around this, you can either use: inline styles, place the CSS inside the HTML of the widget using
Hi Nathan,
I am using a modal with a ‘ok’ button.Is it possible to redirect to another page onclicking of ‘ok’ button.
Hi Subasree,
Yes you can do this.
// Open a modal window to notify the user they will be redirected. Upon clicking ok load the URL we have defined.
spModal.open({
message: ‘Text in the boy of the pop-up’,
title: ‘A fancy title for your popup’,
buttons: [{
label: ‘Ok’,
primary: true
}]
}).then(function() {
location.href=’https://google.com/’;
});
hey Nathan, Thanks for this content it helped alot.
Now i want to know can i show a record producer as popup window as you did