GlideDialogWindow – Terms and Conditions Acceptance Page

//GlideDialogWindow – Terms and Conditions Acceptance Page

GlideDialogWindow – Terms and Conditions Acceptance Page

L

ast week I had a request come in from a client where they wanted to require users to accept certain terms and conditions before ordering a specific catalog item. I have seen this type of request before, but I don’t think I’ve really seen an elegant solution to it…or anything that could really be called a solution at all :). Usually you end up with some combination of a wizard, some custom form, and some crazy scripts that make no sense to anyone but the person who created it. Then I realized that I had just written about a solution a week or so ago when I wrote about how to create a UI Page popup using GlideDialogWindow! The specific application of the solution I wrote about was a little bit different, but the basic pieces were identical. By making some basic tweaks to a solution I already knew about, I was able to come up with what I think is a really nice way to require acceptance of some terms before a user orders a catalog item. This same method could also be used on other forms and tables in ServiceNow.



The first part of this solution is to set up a client-side trigger for your terms dialog. For this example, we assume that the Terms dialog only needs to be displayed for a particular catalog item so our trigger can be in an ‘onLoad’ catalog client script set against the item in question. The script simply needs to create and render the dialog when the item (or potentially variables) load. It also needs to point to a UI Page (by name) that should load within the dialog. It’s the UI Page that will contain all of the specific form elements and terms. If you want your dialog to redirect to a specific location if the ‘Cancel’ button is clicked you can include the ‘cancel_url’ preference as shown below…

‘Load Terms’ Catalog Client Script
Name: Load Terms
Type: onLoad
Script:

function onLoad() {
   //Initialize and open the Dialog Window
   var dialog = new GlideDialogWindow('terms_and_conditions_dialog'); //Render the dialog containing the UI Page 'terms_and_conditions_dialog'
   dialog.setTitle('Terms and Conditions'); //Set the dialog title
   dialog.setSize(600,600); //Set the dialog size
   dialog.removeCloseDecoration(); //Remove the dialog close icon
   dialog.setPreference('cancel_url', 'catalog_home.do?sysparm_view=catalog_default'); //Set optional cancel redirect URL
   dialog.render(); //Open the dialog
}

Now that we’ve set up a trigger, we need to make sure that we have a UI Page with the correct name to be triggered. Notice in the script above that we’re looking for a UI Page named ‘terms_and_conditions_dialog’ in our dialog client script. The correct name is the only absolute in the UI Page. It needs to match the name given in the client script trigger.
The other elements of the UI Page are up to you. Typically when I’ve seen a terms and conditions page, the page contains the terms, an ‘Agree’ checkbox of some sort, and buttons to agree or cancel. I’ve commented those portions of code below. The buttons both trigger specific client-side functions that make sure the ‘Agree’ checkbox is checked (for the ‘OK’ button) and redirect back to the default homepage – or the homepage passed in via the ‘cancel_url’ parameter (for the ‘Cancel’ button). The only thing I haven’t provided is the actual terms and formatting. In order to produce that in a nice HTML format, I actually cheated and pasted my terms into the HTML editor on a blank KB article. Then I could get it formatted like I want and then just toggle to the code editor and copy the HTML into the correct place in my UI Page…

‘terms_and_conditions_dialog’ UI Page
HTML

<g:ui_form>
   <!-- Get values from dialog preferences passed in -->
   <g:evaluate var="jvar_cancel_url"
     expression= "RP.getWindowProperties().get('cancel_url')" />
   <input type="hidden" id="cancel_url" value="${jvar_cancel_url}" />
   <table width="100%">
     <tr>
       <td>
          <div style="width:584px; height:400px; overflow:auto; border: 1px solid gray;">
             ENTER YOUR TERMS HERE...
          </div>
       </td>
     </tr>
     <tr>
       <td>
         <div style="margin-top: 10px;">
           <!-- Pull in 'ui_checkbox' UI Macro for accept checkbox -->
           <g:ui_checkbox id="accept_terms" name="accept_terms" value="false"/>
           <label for="load_demo">I accept these terms and conditions.</label>  
         </div>
       </td>
     </tr>
     <tr>
       <td colspan="2">
       </td>
     </tr>
     <tr id="dialog_buttons">
        <td colspan="2" align="right">
           <!-- Pull in 'dialog_buttons_ok_cancel' UI Macro for submit/cancel buttons -->
           <g:dialog_buttons_ok_cancel ok="return termsOK()" cancel="termsCancel()" ok_type="button" cancel_type="button"/>
        </td>
     </tr>
  </table>
</g:ui_form>

Client Script

function termsOK(){
   //Gets called if the 'OK' dialog button is clicked
   //Make sure terms have been accepted
   var terms = gel('accept_terms').value;
   if(terms != 'true'){
      //If terms are false stop submission
      alert('Please accept the terms and conditions to continue your order.');
      return false;
   }
   //If accept checkbox is true do this...
   GlideDialogWindow.get().destroy(); //Close the dialog window
   //g_form.setValue('myvar', true); //Optionally set the value of a variable or field indicating acceptance
}

function termsCancel(){
   //Redirect gets called if the 'Cancel' dialog button is clicked
   if($('cancel_url').value != 'null'){
      window.location = $('cancel_url').value;
   }
   else{
      window.location = 'home.do'; //Redirect to default homepage
   }
}
By | 2018-07-09T15:14:25-06:00 October 11th, 2010|Categories: System UI|Tags: , , , , |41 Comments

About the Author:

41 Comments

  1. alli October 12, 2010 at 9:27 pm - Reply

    Hi,

    The timing of this is awesome.

    I tried this but the buttons doesn’t seem to check if the checkbox is checked or not.

    also is this possible on the onsubmit function?

    was playing around with it and I can’t get it to render, it always proceeds to the checkout

    thanks for all your help

    • Mark Stanger October 13, 2010 at 1:51 am - Reply

      I posted the wrong version of code to validate the checkbox. It’s updated now. The ‘onSubmit’ would be a little bit trickier. You would have to check for the value of a variable to see if the acceptance had already been done. Then if it hadn’t, pop the dialog. If you created a ‘Yes/No’ variable defaulted to ‘No’ and added it to your item, that could be done like this…

      function onSubmit() {
      //Check 'terms' variable to see if it has been marked
      var termsOK = g_form.getValue('terms_ok');
       
      //If not then pop the dialog and stop the submission
      if(termsOK == 'No'){

      //Initialize and open the Dialog Window
      var dialog = new GlideDialogWindow("demo_terms_and_conditions_dialog"); //Render the dialog containing the UI Page 'demo_terms_and_conditions_dialog'
      dialog.setTitle("Terms and Conditions"); //Set the dialog title
      dialog.setSize(600,600);
      dialog.removeCloseDecoration();
      dialog.render(); //Open the dialog
      return false;
      }
      }

      Then you would need to modify your UI page client script to set the value of that variable on acceptance. You would also want to change the ‘Cancel’ function to simply close the dialog instead of redirecting…

      function termsOK(){
      //Gets called if the 'OK' dialog button is clicked
      //Make sure terms have been accepted
      var terms = gel('accept_terms').value;
      if(terms != 'true'){
      //If terms are false stop submission
      alert("Please accept the terms and conditions to continue your order.");
      return false;
      }

      //If accept checkbox is true do this...
      GlideDialogWindow.get().destroy(); //Close the dialog window
      g_form.setValue('terms_ok', 'Yes');
      }
       
      function termsCancel(){
      //Gets called if the 'Cancel' dialog button is clicked
      GlideDialogWindow.get().destroy(); //Close the dialog window
      }

      This works fine in my testing. The only thing I wish I could add would be to have the submission automatically happen once the user approved the dialog. That would involve capturing the original submit action and calling that again. I couldn’t get that to work when I tested. If somebody else can figure it out I’d be happy to post it.

  2. alli October 17, 2010 at 7:59 pm - Reply

    Thanks Mark

    It’s working now, but needs to click submit button again after the dialog closes ,

  3. alli October 22, 2010 at 12:06 am - Reply

    Hi Mark,

    Quick Question

    Can you control the position where the dialog pops out?

    thanks

    • Mark Stanger October 22, 2010 at 3:19 am - Reply

      You can. There is a ‘moveTo’ function you can utilize to move the dialog to any x,y coordinate within the frame. The dialogs are all set up to naturally want to be centered when they are rendered so you have to set a callback function to set this positioning when the dialog finishes loading. You need to add the callback function before your ‘dialog.render’ call.

      If I wanted to position the dialog in the top-left corner of my frame I could do this…

       dialog.setLoadCallback(function() {
          dialog.moveTo('0', '0');
       });
      • Mark Stanger November 5, 2011 at 9:31 am - Reply

        I just tested this again. It looks like ‘setLoadCallback’ is not available for standard dialogs, just quickforms.

  4. Michael Baker July 20, 2011 at 10:51 am - Reply

    Hi Mark,

    This works great. I was able to get the order to submit when clicking the OK button by adding a few lines to the Client Script. Hope this helps others…

    function termsOK(){
    //Gets called if the 'OK' dialog button is clicked
    //Make sure terms have been accepted
    var terms = gel('accept_terms').value;
    if(terms != 'true'){
    //If terms are false stop submission
    alert('Please accept the terms and conditions to continue your order.');
    return false;
    }
    //If accept checkbox is true do this...
    GlideDialogWindow.get().destroy(); //Close the dialog window
    //g_form.setValue('myvar', true); //Optionally set the value of a variable or field indicating acceptance

    // This will submit the order
    gel("order_now").onclick = "";
    var item_guid = gel("sysparm_item_guid");
    if (item_guid) {
      item_guid = item_guid.value;
    }
    g_cart.order(gel("sysparm_id").value, getQuantity(), item_guid);

    }

    function termsCancel(){
    //Gets called if the 'Cancel' dialog button is clicked
    window.location = 'catalog_home.do?sysparm_view=catalog_default'; //Redirect to catalog homepage
    }
    • Mark Stanger July 20, 2011 at 10:53 am - Reply

      Awesome! Thanks for sharing.

      • Praveen September 4, 2015 at 4:54 am - Reply

        Hi Michael,

        i tried this script but when i click on Ok button its not submitting order it is just collapsing window,please guide me to proceed.

        Regards,
        Bharath

  5. Libby August 9, 2011 at 6:14 pm - Reply

    This is working wonderfully for us in IE & Firefox.. but will not work (dialog pop up stays up and proceeds to fill the screen) in both Chrome & Safari. Any ideas on that?

    • Mark Stanger October 6, 2011 at 2:10 pm - Reply

      I just found a fix for this problem. The UI page above uses dialog buttons that need to have a special setting so that the button acts as a regular button instead of trying to perform a form submission…and redirecting the user. Take a look at your ‘dialog_buttons’ line in your UI page and make sure that it has both an ‘ok_type’ and a ‘cancel_type’ of ‘button’ as shown here…

      <g:dialog_buttons_ok_cancel ok="return termsOK()" cancel="termsCancel()" ok_type="button" cancel_type="button"/>
  6. Matt Wascak October 26, 2011 at 10:21 am - Reply

    I am getting this XML error……
    This page contains the following errors:

    error on line 1 at column 47: Namespace prefix g on ui_form is not defined
    error on line 12 at column 40: Namespace prefix g on ui_checkbox is not defined
    error on line 24 at column 69: Namespace prefix g on dialog_buttons_ok_cancel is not defined
    Below is a rendering of the page up to the first error.

    ENTER YOUR TERMS HERE… I accept these terms and conditions.

    • Mark Stanger October 26, 2011 at 2:30 pm - Reply

      I’m not sure why this would be necessary, but you can try wrapping the UI page script in tags like this…

      <?xml version="1.0" encoding="utf-8" ?>
      <j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
         EXISTING CODE HERE
      </j:jelly>
  7. Shaun Oelofsen November 5, 2011 at 4:12 am - Reply

    Hi Mark,

    Quick Question

    Is there an option to control where the user can be returned to if they choose No.
    We have a requirement that the user be returned to the homepage, as a hard cancel.
    Would we need to build up a URL? Are we able to embed that into the dialog function, much the same as the setCallBack.

    Thanks

    • Mark Stanger November 5, 2011 at 9:20 am - Reply

      Good idea. I’ve modified the solution above to include an optional ‘cancel_url’ preference that you can pass in when you render the dialog. The default cancel redirect just goes to the regular user homepage unless you pass in an override redirect URL of your choosing. Please let me know how this works for you.

      See this page for details on passing parameters into a dialog…
      https://www.servicenowguru.com/system-ui/glidedialogwindow-advanced-popups-ui-pages/

  8. Trinu February 6, 2012 at 5:00 am - Reply

    HI Mark,

    Is there any onsubmit client script for Confirmation message like: when user clicks on OK it going to URL(incident form),similarly when clicks on cancel stay in the same page?

    Thanks in advance

    • Mark Stanger February 6, 2012 at 5:50 am - Reply

      Yes, you’ve got a client-side function that runs when you click the ‘OK’ button. In this case, it’s called ‘termsOK’. You could modify that button to redirect you to another location if you want.

  9. David Otika May 2, 2013 at 9:44 am - Reply

    Mark,

    Thank you for the link. This is exactly what I need. Now I just need to put on my limited scripting hat and try to make it work for me. I guess my only concern here is, just like with any Service Now customization, what will the impact of applying the script be to any future updates?

    • Mark Stanger May 2, 2013 at 9:55 am - Reply

      Hey David, good question. This particular customization just sits on top of anything else you build so it’s very unlikely that it would ever cause any upgrade issues since it’s all custom code rather than modifications to system code.

  10. Joe Lighthall September 12, 2013 at 9:11 am - Reply

    I’ve been using GlideDialogWindow and have the call

    gdw.removeCloseDecoration();

    The problem I see is that even though the button no longer appears a user can hit the ‘Esc’ key and close the dialog without hitting Ok or Cancel which is desired since certain behavior needs to be done by those buttons. Do you know how to intercept this key or prevent it? I was going to try to overload the _eventKeyUp function on GlideDialogWindow but have no clue if this is possible.

    Thanks,
    Joe

    • Mark Stanger September 12, 2013 at 9:46 am - Reply

      A couple of thoughts here. If someone does hit the escape key to try and work around the process, I would consider that the same as acceptance really. If you’re not recording the fact that they accepted or not, then it really wouldn’t matter if they tried to cheat the system that way. If you really want to secure that, then I would probably advise you to modify the dialog (as shown above) to set a field on your form (which should be hidden) that indicates their acceptance. Then you could add a secondary, ‘onSubmit’ client script to check whether or not that field had been checked so that you would have a backup validation just in case. Your ‘onSubmit’ script could prevent the form submission if they didn’t accept.

      • Joe Lighthall September 12, 2013 at 10:10 am - Reply

        Thanks Mark. That’s a clever way of doing it. I saw your post after I re-posted my solution. That seems more solid as it guarantees beyond the escape character issue. So if the dialog is destroyed some other way beyond the escape character the okay or cancel determination of if they have been ran can still be caught.

        Thanks!
        Joe

        • Mark Stanger September 12, 2013 at 10:12 am - Reply

          No problem. Whatever you choose to use, I’m glad you posted your solution since it might be helpful to someone else in the future. Thanks!

      • Joe Lighthall September 12, 2013 at 10:12 am - Reply

        Thinking about this more, I like both solutions together. That way the dialog doesn’t go away with escape and if it goes away by other means it is still caught. Awesome.

    • Joe Lighthall September 12, 2013 at 10:03 am - Reply

      I just figured this out on my own.

      I added a keyup event handler in the one and only text area on the ui-page.

      The function then looks like the following…
      function keyup() {
      //alert(“got a key = ” + event.keyCode);
      // this will stop further processing of the event
      // this is needed since the escape key will close the window
      event.stopImmediatePropagation();
      }

      So without this if a user presses the escape key neither the ok or cancel buttons are invoked and the dialog goes away. However with it the escape key is now ignored.

  11. AdminPro September 23, 2014 at 2:16 pm - Reply

    Mark,
    Do you know of any API for server side dialog window which can be triggered from a script action? My goal is to replicate something similar to UI 14 pop-up, but with a different intention in mind.

    • Mark Stanger September 23, 2014 at 2:21 pm - Reply

      I don’t know of anything SN has created that allows you to invoke dialogs from the server side unfortunately.

  12. Shawn December 12, 2014 at 9:03 am - Reply

    This is great! The only issue I’m having is it doesn’t appear in the center of the screen but in the lower right with the options off the screen. It seemed to work earlier but not now. Any ideas?

  13. Ethan January 21, 2015 at 8:23 am - Reply

    I’m having trouble getting this to work with a Wizard Launcher. Is there something I need to modify to get this to work?

    • Ethan January 21, 2015 at 9:24 am - Reply

      Nevermind. Answer is (obviously) to create a Wizard Client Script rather than the Catalog Client Script. Catalog Client Script will allow you to select the wizard but will not function. The same exact Catalog Client Script can be used for the Wizard Client Script and it functions as intended. Thanks Mark, this is great.

      • Mark Stanger January 21, 2015 at 9:48 am - Reply

        You’re welcome, I’m glad you’ve got it working!

  14. Joel E January 29, 2015 at 11:33 pm - Reply

    Hi,

    This script is very helpful. I am trying to get this to work on an Order Guide in Eureka. It works well except the following script that simulates that order submission.

    // This will submit the order
    gel("order_now").onclick = "";
    var item_guid = gel("sysparm_item_guid");
    if (item_guid) {
      item_guid = item_guid.value;
    }
    g_cart.order(gel("sysparm_id").value, getQuantity(), item_guid);

    I inspected the element of the “Check Out” button in Order Guide, it does not have an element id. Also, all the references in the above code snippet is not in the Order Guide. Is there a way to make this work on Order Guide – i.e. once the user accepted the Term and Condition, the order is submitted?

    Thanks and regards,
    Joel

  15. GeoffM May 18, 2015 at 1:29 pm - Reply

    Hi all – is there another call besides g:dialog_buttons_ok_cancel that will display just an OK button? I can’t seem to find a reference for it. The reason would be in situations where you want to use a better looking, formatable UI page instead of an ugly javascript alert to impart info to the user.

    Cheers,

    G

    • Mark Stanger May 18, 2015 at 1:33 pm - Reply

      I don’t think there’s an existing call like this just for an ‘OK’ button, but it would be very easy to create one. You can find the ‘dialog_buttons_ok_cancel’ UI macro record in your system and then use that as a template to create your own custom UI macro with just the one button. Once you’ve done that you can reference it in the same way by whatever name you choose for the macro.

  16. Chris May 22, 2015 at 10:44 am - Reply

    Mark,
    This works great and I’ve put it to use on our cell phone request by putting our Wireless Policy on the screen that the user has to accept before submitting the request. Now our HR department would like us to capture the user acceptance in the activity section RITM. They would even like to go as far as capturing the verbiage of the Wireless Policy (UI page) in the activity section of the RITM. That way, in the event the policy is updated in the future then we know what version of the policy the user had accepted at that time. Can this be done, and if so, how?

    Thanks,
    Chris

    • Mark Stanger May 22, 2015 at 10:48 am - Reply

      In that case, it might be easier just to go with a checkbox and an HTML variable on the catalog item. This would allow you to capture point-in-time terms pretty easily. You could also set up the dialog to write the HTML terms to an HTML field on the RITM form, but you’re essentially getting that with the variable approach without any fancy scripting. You’ll want to restrict the ‘Create roles’ to ‘nobody’ on the HTML variable if you go that route.

  17. Richard Saunders July 30, 2015 at 1:56 am - Reply

    Hello, Thanks for this is exactly what we are looking for. One odd thing is the popup renders halfway down the page and then you have to scroll back up to Add to Basket. This is only affecting IE and works seamlessly in Chrome. Any ideas?

    • Mark Stanger July 30, 2015 at 6:09 am - Reply

      Sounds like maybe a timing issue in IE. You might try using ‘setTimeout’ to slightly delay the rendering of the terms and conditions page. You can google ‘setTimeout’ to see how that is done.

  18. Vinoth January 11, 2017 at 6:42 am - Reply

    Hi,

    For me close button is working on the homepage loading page(which should not be) and the same close (X) is not shown if I open in new page. Can you please advise me, X should not be available even if I load on the same page

  19. Rick Saunders September 21, 2017 at 2:48 am - Reply

    We have found recently that when Cancel is clicked on this UI popup it does not cancel or redirect to the catalogue. It seems to work fine in Chrome. Anyone else had this issue?

Leave A Comment