├── README.md ├── assets ├── CCW3956 │ ├── Screen Shot 2017-04-26 at 12.27.36 PM.png │ ├── Screen Shot 2017-04-26 at 12.28.03 PM.png │ ├── Screen Shot 2017-04-26 at 12.38.10 PM.png │ ├── Screen Shot 2017-04-26 at 8.35.42 PM.png │ ├── Screen Shot 2017-04-26 at 8.36.12 PM.png │ ├── Screen Shot 2017-04-26 at 8.37.32 PM.png │ ├── Screen Shot 2017-04-26 at 8.41.48 PM.png │ ├── Screen Shot 2017-04-28 at 1.25.58 PM.png │ ├── Screen Shot 2017-04-28 at 1.35.53 PM.png │ ├── Screen Shot 2017-04-28 at 1.38.59 PM.png │ ├── Screen Shot 2017-04-28 at 1.49.20 PM.png │ ├── Screen Shot 2017-04-28 at 11.11.35 AM.png │ ├── Screen Shot 2017-04-28 at 4.00.25 PM.png │ ├── Screen Shot 2017-04-28 at 7.32.12 AM.png │ ├── Screen Shot 2017-04-28 at 7.34.49 AM.png │ ├── Screen Shot 2017-04-28 at 7.38.02 AM.png │ ├── Screen Shot 2017-04-28 at 9.59.34 AM.png │ ├── Screen Shot 2017-04-30 at 1.18.33 PM.png │ ├── Screen Shot 2017-04-30 at 1.18.38 PM.png │ ├── Screen Shot 2017-04-30 at 6.25.30 AM.png │ ├── Screen Shot 2017-04-30 at 6.26.09 AM.png │ ├── Screen Shot 2017-04-30 at 6.56.24 AM.png │ ├── Screen Shot 2017-04-30 at 7.44.42 AM.png │ ├── Screen Shot 2017-04-30 at 7.49.26 AM.png │ ├── Screen Shot 2017-04-30 at 7.53.09 AM.png │ ├── Screen Shot 2017-05-01 at 10.11.27 AM.png │ ├── Screen Shot 2017-05-01 at 11.31.55 AM.png │ ├── Screen Shot 2017-05-01 at 11.39.57 AM.png │ ├── Screen Shot 2017-05-01 at 11.59.40 AM.png │ ├── Screen Shot 2017-05-01 at 2.34.22 PM.png │ ├── Screen Shot 2017-05-01 at 3.31.05 PM.png │ ├── Screen Shot 2017-05-02 at 9.46.31 AM.png │ ├── Screen Shot 2017-05-03 at 8.13.31 AM.png │ ├── Screen Shot 2017-05-03 at 8.18.28 AM.png │ ├── Screen Shot 2017-05-03 at 9.31.48 AM.png │ ├── Screen Shot 2017-05-03 at 9.40.16 AM.png │ ├── Screen Shot 2017-05-04 at 1.23.46 PM.png │ ├── Screen Shot 2017-05-04 at 1.39.30 PM.png │ ├── Screen Shot 2017-05-04 at 11.17.41 AM.png │ ├── Screen Shot 2017-05-04 at 12.06.28 PM.png │ ├── Screen Shot 2017-05-04 at 12.34.34 PM.png │ ├── Screen Shot 2017-05-04 at 12.35.21 PM.png │ ├── Screen Shot 2017-05-04 at 4.10.29 PM.png │ ├── Screen Shot 2017-05-04 at 4.10.32 PM.png │ ├── Screen Shot 2017-05-04 at 8.34.42 PM.png │ ├── Screen Shot 2017-05-04 at 9.04.19 PM.png │ └── Screen Shot 2017-05-04 at 9.05.24 PM.png ├── cart │ ├── bundle.png │ ├── enable_cart_header.png │ └── show_add_to_cart.png ├── css │ ├── css-container-column.png │ ├── css-container-row.png │ ├── css-container.png │ ├── css-layout-tree.png │ ├── css-layout.png │ ├── css-page.png │ ├── css-portal.png │ ├── css-widget-instance.png │ └── css-widget.png ├── home │ ├── service-portal.png │ ├── sp-home.png │ └── watch.png ├── layout │ ├── bootstrap-alternative.png │ ├── move-to-header.png │ └── theme.png ├── service_catalog_patch2_changes │ └── label-html.png ├── spmodal │ ├── alert.png │ ├── confirm.png │ ├── confirm_html_message.png │ ├── embedded_widget.png │ ├── open_shared_data.gif │ ├── open_with_promise.png │ ├── prompt.png │ ├── prompt_with_label.png │ ├── size_lg.png │ ├── size_md.png │ └── size_sm.png ├── sso │ └── portal_suffix.png ├── widget │ └── widget-instance.png ├── widget_embedded │ ├── clock-options.png │ ├── example_clock_options_1.png │ └── example_clock_options_2.png ├── widget_options │ └── widget_options_schema_modal.png └── widget_server_script_apis │ ├── canReadRecord.png │ ├── getCatalogItem.png │ ├── getDisplayValue.png │ ├── getDisplayValue_pagemap.png │ ├── getPortalRecord.png │ └── getValue.png ├── documentation ├── accessibility.md ├── client_scripting.md ├── cms.md ├── css.md ├── css_functions.md ├── css_mixins.md ├── css_scoped.md ├── debugging.md ├── faq.md ├── form.md ├── page.md ├── page_css.md ├── page_layout.md ├── portal.md ├── portal_url.md ├── service_catalog_patch2_changes.md ├── service_portal.md ├── spModal.md ├── sso_configuration.md ├── widget.md ├── widget_client_script.md ├── widget_client_script_apis.md ├── widget_css.md ├── widget_dependencies.md ├── widget_embedded.md ├── widget_html.md ├── widget_instances.md ├── widget_internationalization.md ├── widget_link.md ├── widget_options.md ├── widget_record_watch.md ├── widget_server_script.md └── widget_server_script_apis.md └── release-notes └── helsinki.md /README.md: -------------------------------------------------------------------------------- 1 | # Service Portal Documentation 2 | 3 | Here you will find the unofficial documentation for the ServiceNow Service Portal technology. This material was originally created by the Service Portal development team. However, the original documentation on GitHub has since been removed, so we have decided to pick up where they left off. 4 | 5 | Our goal is that the maintenance of this documentation will become a community effort. If you'd like to contribute, please feel free to submit a pull request from our repo on GitHub: 6 | 7 | https://github.com/newrocketinc/service-portal-docs/ 8 | 9 | ### Contents 10 | 11 | + [Service Portal](documentation/service_portal.md) 12 | + [Portal](documentation/portal.md) 13 | - [URL](documentation/portal_url.md) 14 | + [Page](documentation/page.md) 15 | - [Layout](documentation/page_layout.md) 16 | - [CSS](documentation/css.md#page) 17 | + [Client Scripting & g_form](documentation/client_scripting.md) 18 | + [Widget](documentation/widget.md) 19 | - [HTML](documentation/widget_html.md) 20 | - [Client Script](documentation/widget_client_script.md) 21 | - [Link Function (Advanced)](documentation/widget_link.md) 22 | - [Server Script](documentation/widget_server_script.md) 23 | - [Dependencies](documentation/widget_dependencies.md) 24 | - [CSS/SCSS](documentation/css.md) 25 | - [Embedded Widgets](documentation/widget_embedded.md) 26 | - [Client Script APIs](documentation/widget_client_script_apis.md) 27 | - [Server Script APIs](documentation/widget_server_script_apis.md) 28 | - [Instances](documentation/widget_instances.md) 29 | - [Options](documentation/widget_options.md) 30 | - [Record Watch](documentation/widget_record_watch.md) 31 | - [Internationalization](documentation/widget_internationalization.md) 32 | + [Sass Support](documentation/css.md) 33 | + [Debugging](documentation/debugging.md) 34 | + [Form Widget](documentation/form.md) 35 | + [CMS and Service Portal](documentation/cms.md) 36 | + [SSO, Login & Redirect](documentation/sso_configuration.md) 37 | + [FAQ](documentation/faq.md) 38 | 39 | ___ 40 | 41 | >This site is unofficial and not endorsed by ServiceNow. 42 | -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-26 at 12.27.36 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-26 at 12.27.36 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-26 at 12.28.03 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-26 at 12.28.03 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-26 at 12.38.10 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-26 at 12.38.10 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-26 at 8.35.42 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-26 at 8.35.42 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-26 at 8.36.12 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-26 at 8.36.12 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-26 at 8.37.32 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-26 at 8.37.32 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-26 at 8.41.48 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-26 at 8.41.48 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-28 at 1.25.58 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-28 at 1.25.58 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-28 at 1.35.53 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-28 at 1.35.53 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-28 at 1.38.59 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-28 at 1.38.59 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-28 at 1.49.20 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-28 at 1.49.20 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-28 at 11.11.35 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-28 at 11.11.35 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-28 at 4.00.25 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-28 at 4.00.25 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-28 at 7.32.12 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-28 at 7.32.12 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-28 at 7.34.49 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-28 at 7.34.49 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-28 at 7.38.02 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-28 at 7.38.02 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-28 at 9.59.34 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-28 at 9.59.34 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-30 at 1.18.33 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-30 at 1.18.33 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-30 at 1.18.38 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-30 at 1.18.38 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-30 at 6.25.30 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-30 at 6.25.30 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-30 at 6.26.09 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-30 at 6.26.09 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-30 at 6.56.24 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-30 at 6.56.24 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-30 at 7.44.42 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-30 at 7.44.42 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-30 at 7.49.26 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-30 at 7.49.26 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-04-30 at 7.53.09 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-04-30 at 7.53.09 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-01 at 10.11.27 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-01 at 10.11.27 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-01 at 11.31.55 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-01 at 11.31.55 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-01 at 11.39.57 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-01 at 11.39.57 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-01 at 11.59.40 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-01 at 11.59.40 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-01 at 2.34.22 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-01 at 2.34.22 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-01 at 3.31.05 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-01 at 3.31.05 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-02 at 9.46.31 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-02 at 9.46.31 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-03 at 8.13.31 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-03 at 8.13.31 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-03 at 8.18.28 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-03 at 8.18.28 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-03 at 9.31.48 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-03 at 9.31.48 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-03 at 9.40.16 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-03 at 9.40.16 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-04 at 1.23.46 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-04 at 1.23.46 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-04 at 1.39.30 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-04 at 1.39.30 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-04 at 11.17.41 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-04 at 11.17.41 AM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-04 at 12.06.28 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-04 at 12.06.28 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-04 at 12.34.34 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-04 at 12.34.34 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-04 at 12.35.21 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-04 at 12.35.21 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-04 at 4.10.29 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-04 at 4.10.29 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-04 at 4.10.32 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-04 at 4.10.32 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-04 at 8.34.42 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-04 at 8.34.42 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-04 at 9.04.19 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-04 at 9.04.19 PM.png -------------------------------------------------------------------------------- /assets/CCW3956/Screen Shot 2017-05-04 at 9.05.24 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/CCW3956/Screen Shot 2017-05-04 at 9.05.24 PM.png -------------------------------------------------------------------------------- /assets/cart/bundle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/cart/bundle.png -------------------------------------------------------------------------------- /assets/cart/enable_cart_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/cart/enable_cart_header.png -------------------------------------------------------------------------------- /assets/cart/show_add_to_cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/cart/show_add_to_cart.png -------------------------------------------------------------------------------- /assets/css/css-container-column.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/css/css-container-column.png -------------------------------------------------------------------------------- /assets/css/css-container-row.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/css/css-container-row.png -------------------------------------------------------------------------------- /assets/css/css-container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/css/css-container.png -------------------------------------------------------------------------------- /assets/css/css-layout-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/css/css-layout-tree.png -------------------------------------------------------------------------------- /assets/css/css-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/css/css-layout.png -------------------------------------------------------------------------------- /assets/css/css-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/css/css-page.png -------------------------------------------------------------------------------- /assets/css/css-portal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/css/css-portal.png -------------------------------------------------------------------------------- /assets/css/css-widget-instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/css/css-widget-instance.png -------------------------------------------------------------------------------- /assets/css/css-widget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/css/css-widget.png -------------------------------------------------------------------------------- /assets/home/service-portal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/home/service-portal.png -------------------------------------------------------------------------------- /assets/home/sp-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/home/sp-home.png -------------------------------------------------------------------------------- /assets/home/watch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/home/watch.png -------------------------------------------------------------------------------- /assets/layout/bootstrap-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/layout/bootstrap-alternative.png -------------------------------------------------------------------------------- /assets/layout/move-to-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/layout/move-to-header.png -------------------------------------------------------------------------------- /assets/layout/theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/layout/theme.png -------------------------------------------------------------------------------- /assets/service_catalog_patch2_changes/label-html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/service_catalog_patch2_changes/label-html.png -------------------------------------------------------------------------------- /assets/spmodal/alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/spmodal/alert.png -------------------------------------------------------------------------------- /assets/spmodal/confirm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/spmodal/confirm.png -------------------------------------------------------------------------------- /assets/spmodal/confirm_html_message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/spmodal/confirm_html_message.png -------------------------------------------------------------------------------- /assets/spmodal/embedded_widget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/spmodal/embedded_widget.png -------------------------------------------------------------------------------- /assets/spmodal/open_shared_data.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/spmodal/open_shared_data.gif -------------------------------------------------------------------------------- /assets/spmodal/open_with_promise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/spmodal/open_with_promise.png -------------------------------------------------------------------------------- /assets/spmodal/prompt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/spmodal/prompt.png -------------------------------------------------------------------------------- /assets/spmodal/prompt_with_label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/spmodal/prompt_with_label.png -------------------------------------------------------------------------------- /assets/spmodal/size_lg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/spmodal/size_lg.png -------------------------------------------------------------------------------- /assets/spmodal/size_md.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/spmodal/size_md.png -------------------------------------------------------------------------------- /assets/spmodal/size_sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/spmodal/size_sm.png -------------------------------------------------------------------------------- /assets/sso/portal_suffix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/sso/portal_suffix.png -------------------------------------------------------------------------------- /assets/widget/widget-instance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/widget/widget-instance.png -------------------------------------------------------------------------------- /assets/widget_embedded/clock-options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/widget_embedded/clock-options.png -------------------------------------------------------------------------------- /assets/widget_embedded/example_clock_options_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/widget_embedded/example_clock_options_1.png -------------------------------------------------------------------------------- /assets/widget_embedded/example_clock_options_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/widget_embedded/example_clock_options_2.png -------------------------------------------------------------------------------- /assets/widget_options/widget_options_schema_modal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/widget_options/widget_options_schema_modal.png -------------------------------------------------------------------------------- /assets/widget_server_script_apis/canReadRecord.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/widget_server_script_apis/canReadRecord.png -------------------------------------------------------------------------------- /assets/widget_server_script_apis/getCatalogItem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/widget_server_script_apis/getCatalogItem.png -------------------------------------------------------------------------------- /assets/widget_server_script_apis/getDisplayValue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/widget_server_script_apis/getDisplayValue.png -------------------------------------------------------------------------------- /assets/widget_server_script_apis/getDisplayValue_pagemap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/widget_server_script_apis/getDisplayValue_pagemap.png -------------------------------------------------------------------------------- /assets/widget_server_script_apis/getPortalRecord.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/widget_server_script_apis/getPortalRecord.png -------------------------------------------------------------------------------- /assets/widget_server_script_apis/getValue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrocketinc/service-portal-docs/ec0e865009988a202536c9ad724778e21170df5e/assets/widget_server_script_apis/getValue.png -------------------------------------------------------------------------------- /documentation/accessibility.md: -------------------------------------------------------------------------------- 1 | # Web Content Accessibility Guidelines 2.0 2 | 3 | A summary and checklist for WCAG 2.0 compliance with links to the specifications and implementation advisories applicable to Service Portal. 4 | 5 | ## Table of Contents 6 | 7 | - [Level A](#level-a) 8 | - [Level AA](#level-aa) 9 | - [Testing](#testing) 10 | - [Resources](#resources) 11 | 12 |
13 | 14 | ## Level A 15 | 16 | The most basic web accessibility features 17 | 18 | | Guideline | Section | Status | Difficulty | Notes 19 | | ------------------------- | ------- | ------ | ---------- | ----- 20 | | 1.1 – Text Alternatives | [1.1.1][] [Non-text Content](#111-non-text-content) | FAILED | 1 | All images and other non-textual items should have a text alternative that describes what it is 21 | | 1.3 – Adaptable | [1.3.1][] [Info and Relationships](#131-info-and-relationships) | FAILED | 1 | Info, structure and relationships can be programmatically determined. 22 | | | [1.3.2][] [Meaningful Sequence](#132-meaningful-sequence) | FAILED | 2 | The correct reading sequence can be programmatically determined. 23 | | | [1.3.3][] [Sensory Characteristics](#133-sensory-characteristics) | FAILED | 1 | Users should not be required to identify elements solely by their shape or their position on the page. 24 | | 1.4 – Distinguishable | [1.4.1][] [Use of Colour](#141-use-of-color) | PARTIAL | 2 | Color should not be used as the only means of conveying information. 25 | | | [1.4.3][] [Contrast (Minimum)](#143-contrast-minimum) | PARTIAL | 2 | The visual presentation of text and images of text has a contrast ratio of at least 4.5:1 26 | | | [1.4.4][] [Resize Text](#144-resize-text) | PARTIAL | 2 | Text can be resized without assistive technology up to 200 percent. 27 | | | [1.4.5][] [Images of Text](#145-images-of-text) | PARTIAL | 1 | 28 | | 2.1 – Keyboard Accessible | [2.1.1][] [Keyboard](#211-keyboard) | PARTIAL | 1 | Site can be accessed using a keyboard only. 29 | | | [2.1.2][] [No Keyboard Trap](#212-no-keyboard-trap) | FAILED | 1 | Using the keyboard should not become trapped on a particular element or section. 30 | | 2.2 – Enough Time | [2.2.1][] [Timing Adjustable](#221-timing-adjustable) | FAILED | 1 | Users are warned of time limits shorter than 20 hours and time limits can be turned off or extended. 31 | | | [2.2.2][] [Pause, Stop, Hide](#222-pause-stop-hide) | FAILED | 1 | Users should be able to pause, stop or hide any moving, blinking or automatically updating content on the page. 32 | | 2.3 – Seizures | [2.3.1][] [Three Flashes or Below](#231-three-flashes-or-below) | FAILED | 1 | Do not get seizures from content that flashes onscreen. 33 | | 2.4 – Navigable | [2.4.1][] [Bypass Blocks](#241-bypass-blocks) | FAILED | 2 | Allow users to go straight to the main content on the page. 34 | | | [2.4.2][] [Page Titled](#242-page-titled) | PARTIAL | 1 | Each page should have a title clearly describing the topic or purpose of that page. 35 | | | [2.4.3][] [Focus Order](#243-focus-order) | PARTIAL | 2 | Users can tab through the elements of a page in a logical order. 36 | | | [2.4.4][] [Link Purpose (In Context)](#244-link-purpose-in-context) | PARTIAL | 2 | Target of each link should be clear from the text. 37 | | | [2.4.5][] [Multiple Ways](#245-multiple-ways) | PARTIAL | 2 | More than one way is available to navigate to other pages. 38 | | | [2.4.6][] [Headings and Labels](#246-headings-and-labels) | PARTIAL | 2 | The headings and labels are clear and consistent, accurately describing the topic or purpose. 39 | | | [2.4.7][] [Focus Visible](#247-focus-visible) | PARTIAL | 2 | The page element with the current keyboard focus has a visible focus indicator. 40 | | 3.1 – Readable | [3.1.1][] [Language of Page](#311-language-of-page) | PARTIAL | 1 | Specify the language (e.g. English) of the Web page. 41 | | | [3.1.2][] [Language of Parts](#312-language-of-parts) | FAILED | 2 | Specify the language (e.g. English) of each text phrase or passage that is in a language other than the default language specified for the entire page. 42 | | 3.2 – Predictable | [3.2.1][] [On Focus](#321-on-focus) | PARTIAL | 2 | When a UI component receives focus, this does not trigger unexpected actions. 43 | | | [3.2.2][] [On Input](#322-on-input) | PARTIAL | 2 | No unexpected actions should occur when the user makes changes to a particular UI element. 44 | | | [3.2.3][] [Consistent Navigation](#323-consistent-navigation) | PARTIAL | 2 | Navigation menus are in the same location and order on every page. 45 | | | [3.2.4][] | PARTIAL | 2 | 46 | | 3.3 – Input Assistance | [3.3.1][] [Error Identification](#331-error-identification) | PARTIAL | 2 47 | | | [3.3.2][] [Labels or Instructions](#332-labels-or-instructions) | PARTIAL | 2 48 | | | [3.3.3][] | PARTIAL | 2 | 49 | | | [3.3.4][] | PARTIAL | 2 | 50 | | 4.1 – Compatible | [4.1.1][] [Parsing](#411-parsing) | PARTIAL | 2 51 | | | [4.1.2][] [Name, Role, Value](#412-name-role-value) | FAILED | 3 52 | 53 | 54 | [1.1.1]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=111 55 | [1.3.1]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=131 56 | [1.3.2]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=132 57 | [1.3.3]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=133 58 | [1.4.1]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=141 59 | [2.1.1]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=211 60 | [2.1.2]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=212 61 | [2.2.1]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=221 62 | [2.2.2]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=222 63 | [2.3.1]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=231 64 | [2.4.1]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=241 65 | [2.4.2]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=242 66 | [2.4.3]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=243 67 | [2.4.4]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=244 68 | [3.1.1]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=311 69 | [3.2.1]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=321 70 | [3.2.2]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=322 71 | [3.3.1]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=331 72 | [3.3.2]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=332 73 | [4.1.1]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=411 74 | [4.1.2]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=412 75 | 76 |
77 | 78 | ## Level AA 79 | Deals with the biggest and most common barriers for disabled users 80 | 81 | | Guideline | Section | Status | Difficulty | 82 | | :------------------------ |:------- | :----- | :--------- | 83 | | 1.4 – Distinguishable | [1.4.3][] [Contrast (Minimum)](#143-contrast-minimum) | FAILED | 3 84 | | | [1.4.4][] [Resize Text](#144-resize-text) | FAILED | 3 85 | | | [1.4.5][] [Images of Text](#145-images-of-text) | FAILED | 2 86 | | 2.4 – Navigable | [2.4.5][] [Multiple Ways](#245-multiple-ways) | FAILED | 2 87 | | | [2.4.6][] [Headings and Labels](#246-headings-and-labels) | PARTIAL | 2 88 | | | [2.4.7][] [Focus Visible](#247-focus-visible) | PASSED | 2 89 | | 3.1 – Readable | [3.1.2][] [Language of Parts](#312-language-of-parts) | FAILED | 2 90 | | 3.2 – Predictable | [3.2.3][] [Consistent Navigation](#323-consistent-navigation) | PARTIAL | 3 91 | | | [3.2.4][] [Consistent Identification](#324-consistent-identification) | PARTIAL | 2 92 | | 3.3 – Input Assistance | [3.3.3][] [Error Suggestion](#333-error-suggestion) | PARTIAL | 3 93 | | | [3.3.4][] [Error Prevention](#334-error-prevention) | PARTIAL | 3 94 | 95 | 96 | [1.4.3]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=143 97 | [1.4.4]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=144 98 | [1.4.5]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=145 99 | [2.4.5]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=245 100 | [2.4.6]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=246 101 | [2.4.7]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=247 102 | [3.1.2]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=312 103 | [3.2.3]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=323 104 | [3.2.4]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=324 105 | [3.3.3]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=333 106 | [3.3.4]: https://www.w3.org/WAI/WCAG20/quickref/?showtechniques=334 107 | 108 | ## Detail 109 | 110 | ### [1.1.1][] Non-text Content 111 | 112 | All images and other non-textual items should have a text alternative that describes what it is, so that blind users are able to understand these items. 113 | 114 | > **Required** 115 | 116 | - Provide all images with a descriptive ALT attribute, or an empty string (alt="") if it is a purely decorative image. 117 | - Provide a descriptive TITLE attribute for all embedded audio/video, non-image charts, Flash, form elements and other items that require textual explanation in order to be understood. 118 | - Do not use CAPTCHA that relies on visual identification 119 | - Decorative images such as icons should preferably be displayed using CSS rather than directly in HTML 120 | 121 | > **Must Fix** 122 | 123 | - [F3][]: Should not use CSS to include images that convey important information 124 | - [F13][]: Should not have a text alternative that does not include information that is conveyed by color differences in the image 125 | - [F20][]: Text alternatives does not reflect changes 126 | - [F30][]: Using text alternatives that are not alternatives (e.g., filenames or placeholder text) 127 | - [F38][]: Not marking up decorative images in HTML in a way that allows assistive technology to ignore them (aria-hidden, role) 128 | - [F39][]: Providing a text alternative that is not null (e.g., alt="spacer" or alt="image") for images that should be ignored by assistive technology 129 | - [F65][]: Missing the alt attribute or text alternative on img elements, area elements, and input elements of type "image" 130 | - [F67][]: Providing long descriptions for non-text content that does not serve the same purpose or does not present the same information 131 | - [F71][]: Using text look-alikes to represent text without providing a text alternative 132 | - [F72][]: Using ASCII art without providing a text alternative 133 | 134 | 135 | ### [1.3.1][] Info and Relationships 136 | 137 | Info, structure and relationships can be programmatically determined. 138 | 139 | > **Required** 140 | 141 | - The structure and meaning of the page can still be understood when all CSS styling is removed. 142 | - HTML elements should be used to define the structure and meaning of the elements on the page, including headings, lists, paragraphs, and table elements (including row and column headers). 143 | - Color is not used as the only means to convey meaning. For example, required fields in a form can also be indicated using text labels ("Required") or asterisks (provided an explanation is given of these asterisks) 144 | 145 | > **Must Fix** 146 | 147 | - [F2][]: Using changes in text presentation to convey information without using the appropriate markup or text 148 | - [F33][]: Using white space characters to create multiple columns in plain text content 149 | - [F34][]: Using white space characters to format tables in plain text content 150 | - [F42][]: Emulating links (not using ) 151 | - [F43][]: Using structural markup in a way that does not represent relationships in the content 152 | - [F46][]: Using th elements, caption elements, or non-empty summary attributes in layout tables 153 | - [F48][]: Using the pre element to markup tabular information 154 | - [F68][]: User interface control not having a programmatically determined name 155 | - [F87][]: Inserting non-decorative content by using :before and :after pseudo-elements and the 'content' property in CSS 156 | - [F90][]: Incorrectly associating table headers and content via the headers and id attributes 157 | - [F91][]: Not correctly marking up table headers 158 | - [F92][]: Use of role presentation on content which conveys semantic information 159 | 160 | ### [1.3.2][] Meaningful Sequence 161 | 162 | The correct reading sequence can be programmatically determined. 163 | 164 | > **Required** 165 | 166 | - When all CSS styling of the page is removed, the elements on the page are still in a logical reading order in the HTML code. 167 | - Make sure the tabbing order of the page elements is logical. If necessary, use the tabIndex property to enforce the correct tabbing order. 168 | 169 | > **Must Fix** 170 | 171 | - [F34][]: Using white space characters to format tables in plain text content 172 | - [F33][]: Using white space characters to create multiple columns in plain text content 173 | - [F32][]: Using white space characters to control spacing within a word 174 | - [F49][]: Using an HTML layout table that does not make sense when linearized 175 | - [F1][]: Changing the meaning of content by positioning information with CSS 176 | 177 | ### [1.3.3][] Sensory Characteristics 178 | 179 | Users should not be required to identify elements solely by their shape or their position on the page. 180 | 181 | > **Required** 182 | 183 | - Some examples of what NOT to say: "the button on the right", "the left-hand sidebar", "the round button", "the sounds that chimes". 184 | - In on-screen help texts and instructions, identify elements by multiple characteristics, such as the label, color and position, e.g. "the green button 'Next' on the right" 185 | - When using beeps or other sound cues to inform the user of an event, display a textual message as well. 186 | 187 | > **Must Fix** 188 | 189 | - [F14][]: Identifying content only by its shape or location 190 | - [F26][]: Using a graphical symbol alone to convey information 191 | 192 | ### [1.4.1][] Use of Color 193 | 194 | Color should not be used as the only means of conveying information, because blind users are not able to see colors, and colorblind or older users may not see colors correctly. 195 | 196 | > **Required** 197 | 198 | - When using color to convey information, use another means (like text) to convey the same information in another way 199 | - Do not rely solely on color to identify links. Distinguish links from regular text by underlining them, bolding them, showing an icon next to each link, or some other means other than color. 200 | - In forms, use not just color but also text labels to identify required fields or fields with errors 201 | 202 | > **Must Fix** 203 | 204 | - [F13][]: Having a text alternative that does not include information that is conveyed by color differences in the image 205 | - [F73][]: Creating links that are not visually evident without color vision 206 | - [F81][]: Identifying required or error fields using color differences only 207 | 208 | ### [1.4.3][] Contrast (Minimum) 209 | 210 | The visual presentation of text and images of text has a contrast ratio of at least 4.5:1, except for the following: 211 | 212 | - Large Text: Large-scale text and images of large-scale text have a contrast ratio of at least 3:1; 213 | - Text or images of text that are part of an inactive user interface component, that are pure decoration, that are not visible to anyone, or that are part of a picture that contains significant other visual content, have no contrast requirement. 214 | - Text that is part of a logo or brand name has no minimum contrast requirement. 215 | 216 | > **Required** 217 | 218 | > **Must Fix** 219 | 220 | - [F24][]: Specifying foreground colors without specifying background colors or vice versa 221 | - [F83][]: Using background images that do not provide sufficient contrast with foreground text (or images of text) 222 | 223 | ### [1.4.4][] Resize Text 224 | 225 | Except for captions and images of text, text can be resized without assistive technology up to 200 percent without loss of content or functionality. 226 | 227 | > **Required** 228 | 229 | > **Must Fix** 230 | 231 | - [F69][]: Resizing visually rendered text up to 200 percent causes the text, image or controls to be clipped, truncated or obscured 232 | - [F80][]: Text-based form controls do not resize when visually rendered text is resized up to 200% 233 | 234 | ### [1.4.5][] Images of Text 235 | 236 | > **Required** 237 | 238 | > **Must Fix** 239 | 240 | ### [2.1.1][] Keyboard 241 | 242 | Ensures that the site can be accessed using a keyboard only. 243 | 244 | > **Required** 245 | 246 | - All clickable items should also be selectable using the keyboard 247 | - Where "drag and drop" functionality is used, a keyboard-based "cut and paste" alternative should be offered 248 | - Do not use non-standard interface elements that are not keyboard-accessible but can be controlled with a mouse only 249 | 250 | > **Must Fix** 251 | 252 | - [F54][]: Using only pointing-device-specific event handlers (including gesture) for a function 253 | - [F55][]: Using script to remove focus when focus is received 254 | - [F42][]: Emulating links (not using ) 255 | 256 | ### [2.1.2][] No Keyboard Trap 257 | 258 | Users navigating a Web page using the keyboard should not become trapped on a particular element or section of the page. 259 | 260 | > **Required** 261 | 262 | > **Must Fix** 263 | 264 | - [F10][]: Combining multiple content formats in a way that traps users inside one format type 265 | 266 | ### [2.2.1][] Timing Adjustable 267 | 268 | Users are warned of time limits shorter than 20 hours and time limits can be turned off or extended. 269 | 270 | > **Required** 271 | 272 | - The time limit can be turned off beforehand 273 | - The time limit can be extended beforehand 274 | - The user is warned before a time limit expires and given at least 20 seconds to extend the time limit 275 | 276 | > **Must Fix** 277 | 278 | - [F40][]: Uing meta redirect with a time limit 279 | - [F41][]: Using meta refresh to reload the page 280 | - [F58][]: Using server-side techniques to automatically redirect pages after a time-out 281 | 282 | ### [2.2.2][] Pause, Stop, Hide 283 | 284 | Users should be able to pause, stop or hide any moving, blinking or automatically updating content on the page. 285 | 286 | Content that is constantly changing can be problematic for users who have trouble reading text quickly as well as anyone who has trouble tracking moving objects. It can also cause problems for screen reader software. 287 | 288 | > **Required** 289 | 290 | - This pertains to content that starts automatically and lasts more than five seconds 291 | - This can be onscreen text as well as video, audio or animation 292 | 293 | > **Must Fix** 294 | 295 | - [F16][]: Including scrolling content where movement is not essential to the activity without also including a mechanism to pause and restart the content 296 | 297 | ### [2.3.1][] Three Flashes or Below 298 | 299 | Ensures that users with epilepsy and other who have photosensitive seizure disorders do not get seizures from content that flashes onscreen. 300 | 301 | > **Required** 302 | 303 | - Onscreen content should not flash more than 3 times per second, and flashes fall below the general flash thresholds. 304 | 305 | > **Must Fix** 306 | 307 | ### [2.4.1][] Bypass Blocks 308 | 309 | Allows blind users, who use screen reader software, to skip the page header, navigation menus and other content that is repeated on every page, and go straight to the main content on the page. 310 | 311 | > **Required** 312 | 313 | - Offer a "Skip to main content" link at the top of page 314 | 315 | > **Must Fix** 316 | 317 | ### [2.4.2][] Page Titled 318 | 319 | Each page should have a title clearly describing the topic or purpose of that page. 320 | 321 | > **Required** 322 | 323 | - Use the `` tag in the HTML page header 324 | 325 | > **Must Fix** 326 | 327 | - [F25][]: Title of a Web page not identifying the contents 328 | 329 | ### [2.4.3][] Focus Order 330 | 331 | Users can tab through the elements of a page in a logical order. 332 | 333 | > **Required** 334 | 335 | - The tabIndex property can be used to enforce a certain tabbing order 336 | - When the user leaves a modal dialog box on the page, they should not lose their focus on the page and have to start from the top of the page again. Instead, the element that had the focus when the modal dialog opened should get the focus again 337 | 338 | > **Must Fix** 339 | 340 | - [F44][]: Using tabindex to create a tab order that does not preserve meaning and operability 341 | - [F85][]: Using dialogs or menus that are not adjacent to their trigger control in the sequential navigation order 342 | 343 | ### [2.4.4][] Link Purpose (In Context) 344 | 345 | The purpose or target of each link should be clear from the text (label) of that link, or from the sentence in which the link appears. 346 | 347 | > **Required** 348 | 349 | - Make sure each link is clearly labeled 350 | - When the link text or context is not clear enough, give the link a title property with a clear description of the link purpose or target, e.g. `<a href="page.html" title="View more details about this person">John Smith</a>` 351 | 352 | > **Must Fix** 353 | 354 | - [F63][]: Providing link context only in content that is not related to the link 355 | - [F89][]: Not providing an accessible name for an image which is the only content in a link 356 | 357 | ### [2.4.5][] Multiple Ways 358 | 359 | More than one way is available to navigate to other pages, such as a sitemap. 360 | 361 | > **Required** 362 | 363 | > **Must Fix** 364 | 365 | ### [2.4.6][] Headings and Labels 366 | 367 | The headings and labels are clear and consistent, accurately describing the topic or purpose. 368 | 369 | > **Required** 370 | 371 | > **Must Fix** 372 | 373 | ### [2.4.7][] Focus Visible 374 | 375 | The page element with the current keyboard focus has a visible focus indicator. 376 | 377 | > **Required** 378 | 379 | > **Must Fix** 380 | 381 | - [F55][]: Using script to remove focus when focus is received 382 | - [F78][]: Styling element outlines and borders in a way that removes or renders non-visible the visual focus indicator 383 | 384 | ### [3.1.1][] Language of Page 385 | 386 | Specify the language (e.g. English) of the Web page. 387 | 388 | > **Required** 389 | 390 | - Identify the primary language of a Web page in the HTML page header, e.g. `<html lang="en">` for English in HTML5. 391 | 392 | > **Must Fix** 393 | 394 | ### [3.1.2][] Language of Parts 395 | 396 | Specify the language (e.g. English) of each text phrase or passage that is in a language other than the default language specified for the entire page. 397 | 398 | > **Required** 399 | 400 | > **Must Fix** 401 | 402 | ### [3.2.1][] On Focus 403 | 404 | When a UI component receives focus, this does not trigger unexpected actions such as automatically submitting a form, opening a new window or switching focus to another element. 405 | 406 | > **Required** 407 | 408 | > **Must Fix** 409 | 410 | - [F52][]: Redirect, opening a new window as soon as a new page is loaded 411 | - [F55][]: Using script to remove focus when focus is received 412 | 413 | ### [3.2.2][] On Input 414 | 415 | Changing the setting of a checkbox, radio button or other UI component does not trigger unexpected changes in context, such as causing significant changes to the page content or opening a new window. 416 | 417 | No unexpected actions should occur when the user makes changes to a particular UI element. This can be very confusing to blind users and other keyboard-only users. Some examples of changes to a UI element are: 418 | 419 | - turning a checkbox or radio button on or off 420 | - selecting a different item from a dropdown menu 421 | - entering text into a text field 422 | 423 | Some examples of what should NOT happen: 424 | 425 | - a new window is openened 426 | - the content on the page changes 427 | 428 | How to avoid unexpected actions: 429 | 430 | - Provide a submit button. Do not perform any actions until this button is clicked by the user 431 | 432 | > **Required** 433 | 434 | > **Must Fix** 435 | 436 | - [F36][]: Automatically submitting a form and presenting new content without prior warning when the last field in the form is given a value 437 | - [F37][]: Launching a new window without prior warning when the selection of a radio button, check box or select list is changed 438 | 439 | ### [3.2.3][] Consistent Navigation 440 | 441 | Navigation menus are in the same location and order on every page. 442 | 443 | > **Required** 444 | 445 | - a search box 446 | - login/registration and links to edit your user account or preferences 447 | - a "Skip to content" link 448 | 449 | > **Must Fix** 450 | 451 | - [F66][]: Presenting navigation links in a different relative order on different pages 452 | 453 | ### [3.2.4][] Consistent Identification 454 | 455 | UI components used across the Web site are identified consistently on every page. 456 | 457 | > **Required** 458 | 459 | > **Must Fix** 460 | 461 | - [F31][]: Using two different labels for the same function on different Web pages within a set of Web pages 462 | 463 | ### [3.3.1][] Error Identification 464 | 465 | Input errors are clearly marked and described to the user. 466 | 467 | > **Required** 468 | 469 | - Display an error message with text alerting the user to the specific fields (or other form elements) containing errors and describing the specific errors in the input 470 | - Color or images can be used in addition to the text to mark the form elements containing errors 471 | 472 | > **Must Fix** 473 | 474 | ### [3.3.2][] Labels or Instructions 475 | 476 | Items requiring user input are clearly labeled or have clear instructions. 477 | 478 | > **Required** 479 | 480 | - Use the `<label for="[element ID]">` HTML tag to associate a form element with its label 481 | - Label all form elements. Use clear, unambiguous labels 482 | - Identify required (mandatory) fields with a text label. Do not use color or images only to identify required fields. 483 | - Display the label for an element in close proximity to that element 484 | - Provide examples of correct input, such as the correct date format 485 | 486 | > **Must Fix** 487 | 488 | - [F82][]: Visually formatting a set of phone number fields but not including a text label 489 | 490 | ### [3.3.3][] Error Suggestion 491 | 492 | When the user makes an input error, give suggestions for valid input. 493 | 494 | > **Required** 495 | 496 | > **Must Fix** 497 | 498 | ### [3.3.4][] Error Prevention 499 | 500 | For Web pages causes legal or financial commitments, input can be reviewed and corrected before final submission, and submissions can be be reverted. 501 | 502 | > **Required** 503 | 504 | > **Must Fix** 505 | 506 | ### [4.1.1][] Parsing 507 | 508 | Use valid, error-free HTML, including unique (non-duplicate) element IDs. 509 | 510 | > **Required** 511 | 512 | - HTML code should pass W3C's HTML validation tool 513 | - Use unique IDs - no two elements on the same page should have the same ID 514 | - Browser add-ons like Firebug can be used for quick HTML validation during development 515 | - HTML5 is recommended because it is a lot more forgiving than previous versions of HTML 516 | 517 | > **Must Fix** 518 | 519 | - [F70][]: Incorrect use of start and end tags or attribute markup 520 | - [F77][]: Duplicate values of type ID 521 | 522 | ### [4.1.2][] Name, Role, Value 523 | 524 | For all UI components, the name, value and role can be programmatically determined. 525 | 526 | The name and state of all form elements, links and other UI components can be determined and the state can be changed. This ensures compatibility with assistive technology such as screen readers, screen magnifiers, and speech recognition software. 527 | 528 | > **Required** 529 | 530 | - Avoid using non-standard controls such as those created by Flash, Java or other plugins, components that are created using scripting, or clickable `<div>`s and `<span>`s 531 | - When using non-standard controls, make sure that it is keyboard accessible - it can receive focus and its state can be changed using the keyboard 532 | 533 | > **Must Fix** 534 | 535 | - [F59][]: Using script to make div or span a user interface control in HTML without providing a role for the control 536 | - [F15][]: Implementing custom controls that do not use an accessibility API for the technology, or do so incompletely 537 | - [F20][]: Not updating text alternatives when changes to non-text content occur 538 | - [F68][]: User interface control not having a programmatically determined name 539 | - [F79][]: Focus state of a user interface component not being programmatically determinable or no notification of change of focus state available 540 | - [F86][]: Not providing names for each part of a multi-part form field, such as a US telephone number 541 | - [F89][]: Not providing an accessible name for an image which is the only content in a link 542 | 543 | ## Testing 544 | 545 | Chrome has a built-in page you can access to view accessibility internals and toggle accessibility support on or off on a per-tab basis. Just visit this url: 546 | 547 | ` 548 | chrome://accessibility 549 | ` 550 | 551 | <br/> 552 | 553 | ## Resources 554 | 555 | - [How to Meet WCAG 2.0](https://www.w3.org/WAI/WCAG20/quickref) 556 | - [WCAG 2.0 Conformance](https://www.section508.gov/content/build/website-accessibility-improvement/WCAG-conformance) 557 | - [WebAIM](http://webaim.org/) 558 | - [Color Contrast for Better Readability](https://www.viget.com/articles/color-contrast) 559 | - [Chrome Accessibility (a11y)](https://developer.chrome.com/extensions/a11y) 560 | - [Chrome Accessibility Technical Documentation](https://www.chromium.org/developers/design-documents/accessibility#TOC-Testing) 561 | - [Stanford Online Accessibility Program](https://soap.stanford.edu/) 562 | - [WAVE Chrome Extension](https://chrome.google.com/webstore/detail/wave-evaluation-tool/jbbplnpkjmmeebjpijfedlgcdilocofh) 563 | - [Web Accessibility Evaluation Tools List](https://www.w3.org/WAI/ER/tools/) 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | [F1]: https://www.w3.org/TR/WCAG20-TECHS/F1.html 573 | [F10]: https://www.w3.org/TR/WCAG20-TECHS/F10.html 574 | [F13]: https://www.w3.org/TR/WCAG20-TECHS/F13.html 575 | [F14]: https://www.w3.org/TR/WCAG20-TECHS/F14.html 576 | [F15]: https://www.w3.org/TR/WCAG20-TECHS/F15.html 577 | [F16]: https://www.w3.org/TR/WCAG20-TECHS/F16.html 578 | 579 | [F2]: https://www.w3.org/TR/WCAG20-TECHS/F2.html 580 | [F20]: https://www.w3.org/TR/WCAG20-TECHS/F20.html 581 | [F24]: https://www.w3.org/TR/WCAG20-TECHS/F24.html 582 | [F25]: https://www.w3.org/TR/WCAG20-TECHS/F25.html 583 | [F26]: https://www.w3.org/TR/WCAG20-TECHS/F26.html 584 | 585 | [F3]: https://www.w3.org/TR/WCAG20-TECHS/F3.html 586 | [F30]: https://www.w3.org/TR/WCAG20-TECHS/F30.html 587 | [F31]: https://www.w3.org/TR/WCAG20-TECHS/F31.html 588 | [F32]: https://www.w3.org/TR/WCAG20-TECHS/F32.html 589 | [F33]: https://www.w3.org/TR/WCAG20-TECHS/F33.html 590 | [F34]: https://www.w3.org/TR/WCAG20-TECHS/F34.html 591 | [F36]: https://www.w3.org/TR/WCAG20-TECHS/F36.html 592 | [F37]: https://www.w3.org/TR/WCAG20-TECHS/F37.html 593 | [F38]: https://www.w3.org/TR/WCAG20-TECHS/F38.html 594 | [F39]: https://www.w3.org/TR/WCAG20-TECHS/F39.html 595 | 596 | [F40]: https://www.w3.org/TR/WCAG20-TECHS/F40.html 597 | [F41]: https://www.w3.org/TR/WCAG20-TECHS/F41.html 598 | [F42]: https://www.w3.org/TR/WCAG20-TECHS/F42.html 599 | [F43]: https://www.w3.org/TR/WCAG20-TECHS/F43.html 600 | [F44]: https://www.w3.org/TR/WCAG20-TECHS/F44.html 601 | [F46]: https://www.w3.org/TR/WCAG20-TECHS/F46.html 602 | [F48]: https://www.w3.org/TR/WCAG20-TECHS/F48.html 603 | [F49]: https://www.w3.org/TR/WCAG20-TECHS/F49.html 604 | 605 | [F52]: https://www.w3.org/TR/WCAG20-TECHS/F52.html 606 | [F54]: https://www.w3.org/TR/WCAG20-TECHS/F54.html 607 | [F55]: https://www.w3.org/TR/WCAG20-TECHS/F55.html 608 | [F58]: https://www.w3.org/TR/WCAG20-TECHS/F58.html 609 | [F59]: https://www.w3.org/TR/WCAG20-TECHS/F59.html 610 | 611 | [F63]: https://www.w3.org/TR/WCAG20-TECHS/F63.html 612 | [F65]: https://www.w3.org/TR/WCAG20-TECHS/F65.html 613 | [F66]: https://www.w3.org/TR/WCAG20-TECHS/F66.html 614 | [F67]: https://www.w3.org/TR/WCAG20-TECHS/F67.html 615 | [F68]: https://www.w3.org/TR/WCAG20-TECHS/F68.html 616 | [F69]: https://www.w3.org/TR/WCAG20-TECHS/F69.html 617 | 618 | [F70]: https://www.w3.org/TR/WCAG20-TECHS/F70.html 619 | [F71]: https://www.w3.org/TR/WCAG20-TECHS/F71.html 620 | [F72]: https://www.w3.org/TR/WCAG20-TECHS/F72.html 621 | [F73]: https://www.w3.org/TR/WCAG20-TECHS/F73.html 622 | [F77]: https://www.w3.org/TR/WCAG20-TECHS/F77.html 623 | [F78]: https://www.w3.org/TR/WCAG20-TECHS/F78.html 624 | [F79]: https://www.w3.org/TR/WCAG20-TECHS/F79.html 625 | 626 | [F80]: https://www.w3.org/TR/WCAG20-TECHS/F80.html 627 | [F81]: https://www.w3.org/TR/WCAG20-TECHS/F81.html 628 | [F82]: https://www.w3.org/TR/WCAG20-TECHS/F82.html 629 | [F83]: https://www.w3.org/TR/WCAG20-TECHS/F83.html 630 | [F85]: https://www.w3.org/TR/WCAG20-TECHS/F85.html 631 | [F86]: https://www.w3.org/TR/WCAG20-TECHS/F86.html 632 | [F87]: https://www.w3.org/TR/WCAG20-TECHS/F87.html 633 | [F89]: https://www.w3.org/TR/WCAG20-TECHS/F89.html 634 | 635 | [F90]: https://www.w3.org/TR/WCAG20-TECHS/F90.html 636 | [F91]: https://www.w3.org/TR/WCAG20-TECHS/F91.html 637 | [F92]: https://www.w3.org/TR/WCAG20-TECHS/F92.html 638 | -------------------------------------------------------------------------------- /documentation/client_scripting.md: -------------------------------------------------------------------------------- 1 | 2 | # Service Portal & Client Scripts 3 | 4 | Service Portal runs client scripts & catalog client scripts as long as the UI Type is set to "Mobile" or "Both". Many of your existing client scripts can be set to "Both" as long as the api calls are supported by the mobile client scripting environment. 5 | 6 | Please note: This document applies to the Form widget and SC Catalog Item widget. Client Scripts are different than a widget's client controller & link script blocks. 7 | 8 | #### Unsupported client scripting globals 9 | 10 | The following globals and APIs are unavailable in service portal client script: 11 | 12 | * window 13 | * document 14 | * $ 15 | * jQuery 16 | * $$ 17 | * $j 18 | * angular 19 | 20 | #### Client scripting in widgets 21 | 22 | Widget client controllers are full angular controllers and are not subject to the restrictions listed above. Feel free to use jQuery and Angular as needed. 23 | 24 | #### Embedded widgets & g_form 25 | 26 | When using the Service Catalog variable type "Macro" and "Macro with Label" you can pick a widget to embed in a catalog item form. Within that embedded widget's client controller you can access the field object and catalog item g_form instance using: 27 | 28 | * $scope.page.field 29 | * $scope.page.g_form() 30 | 31 | #### Checking desktop vs mobile runtime 32 | 33 | You might want to mark a client script compatible with both Desktop and Mobile but still do something different depending on the runtime use this: 34 | 35 | ```javascript 36 | if (window === null) 37 | // Write your mobile compatible code here 38 | else 39 | // Write your desktop compatible code here 40 | ``` 41 | 42 | ## Supported client scripting APIs 43 | 44 | These are the officially supported client scripting APIs you can use in onLoad, onChange, and onSubmit client scripts. 45 | 46 | ### g_form 47 | 48 | * addDecoration(fieldName, icon, title) 49 | * addErrorMessage(message) 50 | * addInfoMessage(message) 51 | * addOption(fieldName, value, label, index) 52 | * clearMessages() 53 | * clearOptions(fieldName) 54 | * clearValue(fieldName) 55 | * getActionName() 56 | * getBooleanValue(fieldName) 57 | * getDecimalValue(fieldName) 58 | * getDisplayValue(fieldName) 59 | * getEncodedRecord() 60 | * getFieldNames() 61 | * getIntValue(fieldName) 62 | * getLabel(fieldName) 63 | * getReference(fieldName, callback) 64 | * getRelatedListNames() 65 | * getSectionNames() 66 | * getSysId() 67 | * getTableName() 68 | * getValue(fieldName) 69 | * hasField(fieldName) 70 | * hideAllFieldMsgs(type: "info | error") 71 | * hideErrorBox(fieldName) 72 | * hideFieldMsg(fieldName, clearAll) 73 | * hideRelatedList(listTableName) 74 | * hideRelatedLists() 75 | * isMandatory(fieldName) 76 | * isNewRecord() 77 | * isReadOnly(fieldName) 78 | * isVisible(fieldName) 79 | * removeDecoration(fieldName, icon, title) 80 | * removeOption(fieldName, value) 81 | * save() 82 | * serialize(onlyDirtyFields) 83 | * setFieldPlaceholder(fieldName, placeholder) 84 | * setLabel(fieldName, label) 85 | * setMandatory(fieldName, isMandatory) 86 | * setReadOnly(fieldName, isReadOnly) 87 | * setSectionDisplay(sectionName, isVisible) 88 | * setValue(fieldName, value, displayValue) 89 | * setVisible(fieldName, isVisible) 90 | * showErrorBox(fieldName, message, scrollForm) 91 | * showFieldMsg(fieldName, message, type: "info | error", scrollForm) 92 | * showRelatedList(relatedTableName) 93 | * showRelatedLists() 94 | * submit(submitActionName) 95 | 96 | ### g_list 97 | * [get(fieldName)](#g_list) 98 | * addItem(value, displayValue) 99 | * removeItem(value) 100 | * reset() 101 | * setQuery(queryString) 102 | * setDefaultOperator(operator) 103 | * getDefaultOperator() 104 | 105 | 106 | ### g_service_catalog 107 | * [isOrderGuide()](#g_service_catalog) 108 | 109 | ### GlideAjax 110 | 111 | * new GlideAjax(scriptIncludeName) 112 | * addParam (name, value) 113 | * getParam (name) 114 | * getXML(callback) 115 | * getXMLAnswer(callback) 116 | * getJSON(callback) 117 | * setErrorCallback(errorCallback) 118 | * getURL() 119 | * getParams() 120 | * execute() 121 | * successCalback(data, status, xhr) 122 | * errorCallback(xhr) 123 | * setScope(scope) 124 | 125 | 126 | ### GlideRecord 127 | * new GlideRecord(tableName) 128 | * addQuery(encodedQuery) 129 | * addQuery(fieldName, operator, value) 130 | * getEncodedQuery() 131 | * deleteRecord(callback) 132 | * get(id) 133 | * getTableName() 134 | * hasNext() 135 | * insert(callback) 136 | * gotoTop() 137 | * next() 138 | * loadRow(rowObj) 139 | * getValue(fieldName) 140 | * setValue(fieldName, value) 141 | * isDotWalkField(fieldName) 142 | * addOrderBy(fieldName) 143 | * orderBy(fieldName) 144 | * orderByDesc(fieldName) 145 | * setDisplayFields(fieldNames) 146 | * query(callback) 147 | * setRows(rowsArray) 148 | * setTableName(tableName) 149 | * update(callback) 150 | * setLimit(maxInt) 151 | * getLimit() 152 | 153 | 154 | ### getMessage(messageKey, callback) 155 | 156 | 157 | # Usage examples 158 | 159 | <a name="g_list"></a>g_list 160 | ----- 161 | g_list helps you set the filter of a glide list element or a list collector variable. Use this api in place of the "g_filter" api on desktop client scripts. 162 | 163 | ```javascript 164 | function onLoad() { 165 | var myListCollector = g_list.get("my_list_collector"); 166 | myListCollector.reset(); 167 | myListCollector.setQuery("active=true^category=8c7b22230b402200b0b02c6317673a62"); 168 | myListCollector.addItem('3a700d39af5f4fc0aab978df90f4c692', 'Power Supply'); 169 | myListCollector.addItem('1cb93419a3a248318da8f814140b42f6', 'Backpack'); 170 | } 171 | ``` 172 | 173 | <a name="g_service_catalog"></a>g_service_catalog 174 | ----- 175 | g_service_catalog is only available in Service Portal service catalog item scripts. Use this API to know if your catalog item script is being run as part of an order guide or on its own. 176 | 177 | ```javascript 178 | function onLoad() { 179 | if (window) // if CMS don't run this 180 | return; 181 | 182 | // g_service_catalog api for Service Portal and Mobile 183 | var isOrderGuide = g_service_catalog.isOrderGuide(); 184 | g_form.setValue("is_order_guide", isOrderGuide ? "Yes!" : "Nope :("); 185 | } 186 | ``` 187 | -------------------------------------------------------------------------------- /documentation/cms.md: -------------------------------------------------------------------------------- 1 | # CMS and Service Portal 2 | Although Service Portal was designed to address many of the use cases and pain points of CMS, they are entirely different products. 3 | 4 | ### What is going to happen to my CMS site when I switch to Helsinki? 5 | Nothing - all your CMS projects will be completely unaffected by Service Portal. Service Portal is not an "upgrade" of CMS, it is an entirely different product. 6 | 7 | ### Is there a migration path from CMS to Service Portal? 8 | First, the bad news: there is no direct migration path from CMS to Service Portal. 9 | 10 | Now, the good news: Service Portal comes with widgets for many components such as Catalog, Knowledge, and Incidents. These components should work as you expect out of the box. 11 | Additionally, the Service Portal developer framework makes component development much easier than it was in CMS, which means that you will be able to build any functionality you had in CMS portals into Service Portal with relative ease. 12 | 13 | The difficulty of a migration from CMS to Service Portal will depend mostly on the customizations made to the components in CMS. 14 | -------------------------------------------------------------------------------- /documentation/css.md: -------------------------------------------------------------------------------- 1 | 2 | # Service Portal CSS 3 | 4 | CSS rules for pages and widgets can be written using regular [CSS][10] or as [SCSS][20] syntax. Rules are scoped to the page or widget–this means that rules defined here affect just the page or widget and nothing else. 5 | 6 | 7 | Table of Contents 8 | ----------- 9 | 1. [Service Portal Layout Model](#layout) 10 | * [Portal CSS](#portal) 11 | * [Page CSS](#page) 12 | * [Containers and Rows CSS](#container) 13 | * [Instances and Widget CSS](#instance-widget) 14 | 2. [SCSS Basic](#scss) 15 | 3. [List of functions][30] 16 | 4. [List of mixins][31] 17 | 18 | Service Portal Layout Model <a name="layout"></a> 19 | ----------- 20 | A portal is represented by pages with containers, rows and instances. 21 | 22 | ![Layout Model](../assets/css/css-layout.png) 23 | 24 | In /sp_config, the page edit tree will show the layout model hierarchy. 25 | 26 | ![Page Edit](../assets/css/css-layout-tree.png) 27 | 28 | ##### <a name="portal">Portal</a> 29 | 30 | Portal CSS are editable in /sp_config portal edit. CSS variables and rules that are defined here are scoped and available to pages, containers, rows, and instances. Use portal css for global definitions shared by all pages. 31 | 32 | ![Portal](../assets/css/css-portal.png) 33 | 34 | ##### <a name="page">Page</a> 35 | 36 | Page CSS variables and rules are scoped and affects the page and all elements below. 37 | 38 | ![Page](../assets/css/css-page.png) 39 | 40 | 41 | 42 | ##### <a name="container">Container</a> 43 | 44 | Container CSS are defined by specificing a parent class or css class. 45 | 46 | ![Container](../assets/css/css-container.png) 47 | 48 | 49 | 50 | ##### <a name="container-row">Row</a> 51 | 52 | Row CSS are defined by specificing a CSS class. 53 | 54 | ![Container Row](../assets/css/css-container-row.png) 55 | 56 | 57 | 58 | ##### <a name="container-column">Column</a> 59 | 60 | Column CSS are defined by specificing a CSS class. 61 | 62 | ![Container Column](../assets/css/css-container-column.png) 63 | 64 | 65 | 66 | ##### <a name="intance-widget">Widget Instance</a> 67 | 68 | Instance CSS variables and rules are scoped and affects the widget instance. 69 | 70 | ![Widget Instance](../assets/css/css-widget-instance.png) 71 | 72 | 73 | 74 | ##### <a name="widget">Widget</a> 75 | 76 | Widget CSS variables and rules are scoped and affects the widget and all instances. 77 | 78 | ![Widget](../assets/css/css-widget.png) 79 | 80 | <a name="scss">SCSS Primer</a> 81 | ----------- 82 | 83 | Service Portal SCSS is a subset of the [SASS Specification][20], the following are supported: 84 | - [Variables](#variables) 85 | - [Nesting](#nesting) 86 | - [Operators](#operators) 87 | - [Mixins](#mixins) 88 | 89 | ##### <a name="variables">Variables</a> 90 | 91 | SCSS variables are a way to store information that you want to reuse throughout your stylesheet. You can store things like colors, font stacks, or any CSS value you think you'll want to reuse. SCSS uses the `$` symbol to make something a variable. 92 | 93 | SCSS supports the follow data types: 94 | - Numbers (including units) 95 | - Strings (with quotes or without) 96 | - Colors (name, or names) 97 | - Booleans 98 | 99 | Variables can also be arguments to or results from one of several available [functions][30] or [mixins][31]. During translation, the values of the variables are inserted into the output CSS document. 100 | 101 | Here's an example: 102 | 103 | ``` scss 104 | $font-stack: Helvetica, sans-serif; 105 | $primary-color: #333; 106 | 107 | body { 108 | font: 100% $font-stack; 109 | color: $primary-color; 110 | } 111 | ``` 112 | 113 | ##### <a name="nesting">Nesting</a> 114 | 115 | SCSS will let you nest your CSS selectors in a way that follows the same visual hierarchy of your HTML. 116 | 117 | Here's an example of some typical styles: 118 | 119 | 120 | ``` scss 121 | nav { 122 | ul { 123 | margin: 0; 124 | padding: 0; 125 | list-style: none; 126 | } 127 | 128 | li { display: inline-block; } 129 | 130 | a { 131 | display: block; 132 | padding: 6px 12px; 133 | text-decoration: none; 134 | } 135 | } 136 | ``` 137 | 138 | You'll notice that the `ul`, `li`, and `a` selectors are nested inside the `nav` selector. This is a great way to organize your CSS and make it more readable. When the widget is rendered, the generated CSS would be something like this: 139 | 140 | ```scss 141 | nav ul { 142 | margin: 0; 143 | padding: 0; 144 | list-style: none; 145 | } 146 | 147 | nav li { 148 | display: inline-block; 149 | } 150 | 151 | nav a { 152 | display: block; 153 | padding: 6px 12px; 154 | text-decoration: none; 155 | } 156 | ``` 157 | 158 | ##### <a name="operators">Operators</a> 159 | 160 | SCSS has a handful of standard math operators like `+`, `-`, `*`, `/`, and `%`. In our example we're going to do some simple math to calculate widths for an aside `&` article. 161 | 162 | ```scss 163 | .container { width: 100%; } 164 | 165 | article[role="main"] { 166 | float: left; 167 | width: 600px / 960px * 100%; 168 | } 169 | 170 | aside[role="complementary"] { 171 | float: right; 172 | width: 300px / 960px * 100%; 173 | } 174 | ``` 175 | 176 | The generated CSS will look like: 177 | 178 | ```css 179 | .container { 180 | width: 100%; 181 | } 182 | 183 | article[role="main"] { 184 | float: left; 185 | width: 62.5%; 186 | } 187 | 188 | aside[role="complementary"] { 189 | float: right; 190 | width: 31.25%; 191 | } 192 | ``` 193 | 194 | ##### <a name="mixins">Mixins</a> 195 | 196 | A mixin lets you make groups of CSS declarations that you want to reuse throughout your site. You can even pass in values to make your mixin more flexible. Here's an example for `border-radius`. 197 | 198 | ```scss 199 | @mixin border-radius($radius) { 200 | -webkit-border-radius: $radius; 201 | -moz-border-radius: $radius; 202 | -ms-border-radius: $radius; 203 | border-radius: $radius; 204 | } 205 | 206 | .box { @include border-radius(10px); } 207 | ``` 208 | 209 | Here is the generated CSS: 210 | 211 | ```css 212 | .box { 213 | -webkit-border-radius: 10px; 214 | -moz-border-radius: 10px; 215 | -ms-border-radius: 10px; 216 | border-radius: 10px; 217 | } 218 | ``` 219 | 220 | Additional Resources 221 | ----------- 222 | * [MDN CSS Documentation][10] 223 | * [Sass/SCSS Reference][20] 224 | 225 | 226 | [10]: https://developer.mozilla.org/en-US/docs/Web/CSS 227 | 228 | [20]: http://sass-lang.com/documentation/file.SASS_REFERENCE.html 229 | 230 | [30]: css_functions.md 231 | [31]: css_mixins.md 232 | 233 | [40]: page_css.md 234 | [41]: widget_css.md 235 | -------------------------------------------------------------------------------- /documentation/css_functions.md: -------------------------------------------------------------------------------- 1 | # SCSS Functions 2 | 3 | List of functions for Service Portal SCSS compiler. 4 | 5 | ## RGB Functions 6 | 7 | | Function | Description || 8 | |---|---|---| 9 | | <div style="width:450px"/> | <div style="width:500px"/> | <div style="width:150px"/> | 10 | | `rgb($red, $green, $blue)` | Creates a Color from red, green, and blue values. | 11 | | `rgba($red, $green, $blue, $alpha)` | Creates a Color from red, green, blue, and alpha values. | 12 | | `red($color)` | Gets the red component of a color. | 13 | | `green($color)` | Gets the green component of a color. | 14 | | `blue($color)` | Gets the blue component of a color. | 15 | | `mix($color1, $color2, [$weight])` | Mixes two colors together. | 16 | 17 | 18 | ## HSL Functions 19 | 20 | | Function | Description || 21 | |---|---|---| 22 | | <div style="width:450px"/> | <div style="width:500px"/> | <div style="width:150px"/> | 23 | | `hsl($hue, $saturation, $lightness)` | Creates a Color from hue, saturation, and lightness values. | 24 | | `hsla($hue, $saturation, $lightness, $alpha)` | Creates a Color from hue, saturation, lightness, and alpha values. | 25 | | `hue($color)` | Gets the hue component of a color. | 26 | | `saturation($color)` | Gets the saturation component of a color. | 27 | | `lightness($color)` | Gets the lightness component of a color. | 28 | | `adjust-hue($color, $degrees)` | Changes the hue of a color. | 29 | | `lighten($color, $amount)` | Makes a color lighter. | 30 | | `darken($color, $amount)` | Makes a color darker. | 31 | | `saturate($color, $amount)` | Makes a color more saturated. | 32 | | `desaturate($color, $amount)` | Makes a color less saturated. | 33 | | `grayscale($color)` | Converts a color to grayscale. | 34 | | `complement($color)` | Returns the complement of a color. | NOT AVAILABLE | 35 | | `invert($color)` | Returns the inverse of a color. | NOT AVAILABLE | 36 | 37 | 38 | ## Opacity Functions 39 | 40 | | Function | Description || 41 | |---|---|---| 42 | | <div style="width:450px"/> | <div style="width:500px"/> | <div style="width:150px"/> | 43 | | `alpha($color)` | Gets the alpha component (opacity) of a color. | 44 | | `opacity($color)` | Gets the alpha component (opacity) of a color. | 45 | | `rgba($color, $alpha)` | Changes the alpha component for a color. | 46 | | `opacify($color, $amount)` | Makes a color more opaque. | NOT AVAILABLE | 47 | | `fade-in($color, $amount)` | Makes a color more opaque. | NOT AVAILABLE | 48 | | `transparentize($color, $amount)` | Makes a color more transparent. | NOT AVAILABLE | 49 | | `fade-out($color, $amount)` | Makes a color more transparent. | NOT AVAILABLE | 50 | 51 | 52 | ## Other Color Functions 53 | 54 | | Function | Description || 55 | |---|---|---| 56 | | <div style="width:450px"/> | <div style="width:500px"/> | <div style="width:150px"/> | 57 | | `adjust-color()` | Increases or decreases one or more components of a color. | 58 | | `scale-color()` | Fluidly scales one or more properties of a color. | 59 | | `change-color()` | Changes one or more properties of a color. | NOT AVAILABLE | 60 | | `ie-hex-str()` | Converts a color into the format understood by IE filters. | NOT AVAILABLE | 61 | 62 | ## String Functions 63 | 64 | | Function | Description || 65 | |---|---|---| 66 | | <div style="width:450px"/> | <div style="width:500px"/> | <div style="width:150px"/> | 67 | | `unquote($string)` | Removes quotes from a string. | 68 | | `quote($string)` | Adds quotes to a string. | 69 | | `str-length($string)` | Returns the number of characters in a string. | NOT AVAILABLE | 70 | | `str-insert($string, $insert, $index)` | Inserts `$insert` into $string at `$index`. | NOT AVAILABLE | 71 | | `str-index($string, $substring)` | Returns the index of the first occurrence of $substring in $string. | NOT AVAILABLE | 72 | | `str-slice($string, $start-at, [$end-at])` | Extracts a substring from `$string`. | NOT AVAILABLE | 73 | | `to-upper-case($string)` | Converts a string to upper case. | NOT AVAILABLE | 74 | | `to-lower-case($string)` | Converts a string to lower case. | NOT AVAILABLE | 75 | 76 | ## Number Functions 77 | 78 | | Function | Description || 79 | |---|---|---| 80 | | <div style="width:450px"/> | <div style="width:500px"/> | <div style="width:150px"/> | 81 | | `percentage($number)` | Converts a unitless number to a percentage. | 82 | | `round($number)` | Rounds a number to the nearest whole number. | 83 | | `ceil($number)` | Rounds a number up to the next whole number. | 84 | | `floor($number)` | Rounds a number down to the previous whole number. | 85 | | `abs($number)` | Returns the absolute value of a number. | 86 | | `min($numbers…)` | Finds the minimum of several numbers. | 87 | | `max($numbers…)` | Finds the maximum of several numbers. | 88 | | `random([$limit])` | Returns a random number. | NOT AVAILABLE | 89 | 90 | ## List Functions 91 | 92 | Lists in SCSS are immutable; all list functions return a new list rather than updating the existing list in-place. 93 | 94 | All list functions work for maps as well, treating them as lists of pairs. 95 | 96 | | Function | Description | 97 | |---|---|---| 98 | | <div style="width:450px"/> | <div style="width:500px"/> | <div style="width:150px"/> | 99 | | `length($list)` | Returns the length of a list. | 100 | | `nth($list, $n)` | Returns a specific item in a list. | 101 | | `set-nth($list, $n, $value)` | Replaces the nth item in a list. | NOT AVAILABLE | 102 | | `join($list1, $list2)` | Joins together two lists into one. | 103 | | `append($list1, $val)` | Appends a single value onto the end of a list. | 104 | | `zip($lists…)` | Combines several lists into a single multidimensional list. | NOT AVAILABLE | 105 | | `index($list, $value)`| Returns the position of a value within a list. | 106 | | `list-separator($list)` | Returns the separator of a list. | NOT AVAILABLE | 107 | 108 | 109 | ## Map Functions 110 | 111 | | Function | Description | 112 | |---|---|---| 113 | | <div style="width:450px"/> | <div style="width:500px"/> | <div style="width:150px"/> | 114 | 115 | ## Selector Functions 116 | 117 | | Function | Description | 118 | |---|---|---| 119 | | <div style="width:450px"/> | <div style="width:500px"/> | <div style="width:150px"/> | 120 | 121 | ## Introspection Functions 122 | 123 | | Function | Description | 124 | |---|---|---| 125 | | <div style="width:450px"/> | <div style="width:500px"/> | <div style="width:150px"/> | 126 | 127 | ## Miscellaneous Functions 128 | 129 | | Function | Description | 130 | |---|---|---| 131 | | <div style="width:450px"/> | <div style="width:500px"/> | <div style="width:150px"/> | 132 | 133 | ## Adding Custom Functions 134 | 135 | scss 136 | @function my-calculation-function($some-number, $another-number){ 137 | @return $some-number + $another-number 138 | } 139 | -------------------------------------------------------------------------------- /documentation/css_mixins.md: -------------------------------------------------------------------------------- 1 | # Mixins 2 | 3 | Available mixins in Service Portal. 4 | -------------------------------------------------------------------------------- /documentation/css_scoped.md: -------------------------------------------------------------------------------- 1 | # Scoped Page/Widget CSS 2 | 3 | CSS Variable inclusion order: 4 | 1. sp_theme.css_variables 5 | 2. sp_portal.css_variables 6 | 3. sp_page.css 7 | 4. sp_widget.css 8 | 5. sp_instance.css 9 | 10 | 11 | Service Portal stylesheet inclusion order: 12 | 13 | 1. sp-bootstrap.scss (file from the file system, compiled with sass compiler) 14 | 2. sp-theme (css includes - asc order, css includes are not compiled) 15 | 3. sp_page.css (compiled with sass compiler) 16 | 4. sp_widget.css (compiled with sass compiler) 17 | 5. sp_instance.css (compiled with sass compiler) 18 | 19 | 20 | Note, the branding editor mainly writes to the sp_portal.css_variables field of whatever portal you have selected 21 | -------------------------------------------------------------------------------- /documentation/debugging.md: -------------------------------------------------------------------------------- 1 | # Debugging 2 | 3 | ## Client Side 4 | 5 | | Command / Function | Description | 6 | | :------ | :----------- | 7 | | `console.log(String|Object)` | Outputs to the browser console. When used in the Client Controller, this command is native to the browser. | 8 | | `<pre>{{data|json}}</pre>` | Add this to the template. Uses Angular [json filter](https://docs.angularjs.org/api/ng/filter/json) to display content of `data` object in an easy-to-read fashion | 9 | | `debugger;` | Native to Chrome and Firefox to set a browser breakpoint, letting an admin step through script line by line | 10 | 11 | 12 | ## Server Side 13 | 14 | 15 | | Command / Function | Description | 16 | | :------ | :----------- | 17 | | `console.log(String|Object)` | Outputs to the browser console. When used in the Server Script, can log server-side JavaScript Objects and Strings | 18 | | `$sp.log(String|Object)` | Outputs to a Service Portal page. Can log server-side JavaScript Objects and Strings. Similar to `gs.addInfoMessage(String)` but only outputs if user has `sp_admin` role or is impersonating. | 19 | | `gs.log(String)` | Normal ServiceNow function to output text to the `syslog` database table. | 20 | | `gs.warn(String)` | Normal ServiceNow function to output text to the `syslog` database table as a WARNING. | 21 | | `gs.error(String)` | Normal ServiceNow function to output text to the `syslog` database table as an ERROR.| 22 | | `gs.addInfoMessage(String)` | Normal ServiceNow function to output a message to the page in the browser, visible in the ServiceNow UI| 23 | | `gs.addErrorMessage(String)` | Normal ServiceNow function to output an error to the page in the browser, visible in the ServiceNow UI| 24 | -------------------------------------------------------------------------------- /documentation/faq.md: -------------------------------------------------------------------------------- 1 | ### Can unauthenticated users order items in the Service Catalog using Service Portal? 2 | No. Service Catalog ordering depends on an AngularProcessor transaction that currently requires documentation. Unauthenticated users will be allowed to see Catalog items, but ordering will not work as expected. 3 | 4 | ### Are Order Guides supported? 5 | Yes. Order Guides are supported on the sc_cat_item_guide page. 6 | 7 | ### Are Catalog Client Scripts supported? How can I make them work? 8 | Service Portal only executes client scripts with the UI Type of "Both" or "Mobile". Read more about what's supported and what's not in the Mobile client scripting runtime here: http://wiki.servicenow.com/index.php?title=Mobile_Client_GlideForm_(g_form)_Scripting#gsc.tab=0 9 | 10 | ### Is there a “Copy Portal” functionality similar to what we have for CMS? 11 | Unfortunately not. We have a tool for copying widgets, but nothing for pages or portals at the moment. It shouldn't be too difficult to manually copy what you need though, portals are easy to build up and you rarely want a full copy anyway. 12 | 13 | ### Can I use widgets out of the Service Portal? 14 | No. Widgets depend on the Service Portal Framework to render. 15 | 16 | ### I have a question about something, but it isn't documented anywhere. What do I do? 17 | Create an issue on this repository and we'll check it out! We want the best coverage we can manage, so if there is anything we're missing, please let us know. 18 | 19 | PLEASE NOTE: Only create issues in this repository for documentation problems. For issues with the Service Portal framework, please create an incident on HI and the Service Portal team will investigate from there. 20 | 21 | ### I've written a bit of documentation myself, can I contribute to this project? 22 | Of course! We love having help. Create a pull request with your updates and somebody on the documentation team will check it out. 23 | 24 | -------------------------------------------------------------------------------- /documentation/form.md: -------------------------------------------------------------------------------- 1 | # Form Widget 2 | Out of the box, Service Portal ships with an implementation of the ServiceNow Form, entirely contained within a widget. The Form widget works in much the same way as the forms you are probably already familiar with in the ServiceNow platform. 3 | 4 | However, there are a few caveats, which will be described in depth below. 5 | 6 | ___ 7 | 8 | ## Form Scripts 9 | Here, we will go over different types of form scripts and what is supported in Service Portal. 10 | 11 | ### Client Scripts 12 | Service Portal has support for Client Scripts that are marked with a UI Type of either **Mobile** or **Both**. Client Scripts marked Desktop will not be executed, as those scripts rely on legacy APIs that are not supported by Service Portal. 13 | 14 | ### UI Actions 15 | All **Server-side UI Actions** are supported, with one important distinction - setRedirectURL() operations are ignored, due to the fact that Service Portal forms do not handle redirection the same way that forms in the platform do. 16 | 17 | Any UI Actions marked Client are **not compatible with Service Portal** and will be ignored by the Form widget. 18 | 19 | ### UI Macros 20 | UI Macros are **not supported** in Service Portal (they use Jelly, and Service Portal doesn't). 21 | 22 | ### UI Policies 23 | UI Policies are supported in Service Portal forms. 24 | 25 | ### Formatters 26 | Formatters are **not supported** in Service Portal (they use Jelly, and Service Portal doesn't). 27 | 28 | -------------------------------------------------------------------------------- /documentation/page.md: -------------------------------------------------------------------------------- 1 | 2 | ### Page 3 | A page is a collection of [bootstrap](http://getbootstrap.com/css/#grid) containers rows and columns that contain widgets built using the Service Portal Designer. Pages are referenced to other pages using their `page id`. One page can be used on multiple portals. 4 | 5 | Learn more: 6 | - [Layout](page_layout.md) 7 | - [CSS](css.md#page) 8 | -------------------------------------------------------------------------------- /documentation/page_css.md: -------------------------------------------------------------------------------- 1 | # Page CSS 2 | -------------------------------------------------------------------------------- /documentation/page_layout.md: -------------------------------------------------------------------------------- 1 | ## Header and Footer 2 | Header and footer are set under the *theme*. Headers and footers are just a widget defined under the theme settings. 3 | 4 | ![theme](../assets/layout/theme.png) 5 | 6 | 7 | ## Subheader 8 | You can define a page container as a subheader like this: 9 | ![move to header](../assets/layout/move-to-header.png) 10 | 11 | 12 | ## Custom Layout 13 | Service Portal uses [Bootstrap](http://getbootstrap.com/css/) layout by default. In order to add a widget, you must add first a container and then a row and a set of columns. The bootstrap will work for most of the cases but if you needto have a custom layout, for example you want to use flexbox instead of containers you can. Mark the *bootstrap alternative* option. 14 | 15 | ![Bootstrap Alternative](../assets/layout/bootstrap-alternative.png) 16 | 17 | This option will get rid of the container class. Now you can add a *CSS class* to the container to have a different layout. 18 | -------------------------------------------------------------------------------- /documentation/portal.md: -------------------------------------------------------------------------------- 1 | # Portal 2 | 3 | These are the configuration settings when you create a new portal. 4 | 5 | | Property | Description | Portal Variable 6 | | :------ | :----------- | :----------- | 7 | | Title | The Portal title. This is how the page will render the title: `<title>{Portal Title} - {Page Title}` | title | 8 | | Url Suffix | The directory name: `[instance:port]/url_suffix/` to idenfity the portal | url_suffix | 9 | | Homepage | Index page associated to this portal | homepage, homepage_dv | 10 | | Knowledge base | Knowledge base home page |kb_knowledge_base, kb_knowledge_base_dv | 11 | | Social QA Knowledge Base| Default QA knowledge base | sqanda_knowledge_base_dv | 12 | | KB home page | Default KB home page | kb_knowledge_page, kb_knowledge_page_dv | 13 | | Login page| Default Login Page | login_page, login_page_dv | 14 | | Logo | Company logo | logo | 15 | | Icon| Company icon | icon | 16 | | Default | Default Portal | default | 17 | | Quick start config | Configuration settings generated by the Branding editor | quick_start_config | 18 | | CSS variables | Portal specific Sass variables. You can overwrite existing theme variables in here. | | 19 | | Application| Application scope | | 20 | | 404 page| Default 404 Page |notfound_page, notfound_page_dv | 21 | | Catalog| Service Catalog in use | | 22 | | Catalog home page | Catalog home page | sp_catalog, sp_catalog| 23 | | Main menu | Reference to widget used for the menu | sp_rectangle_menu, sp_rectangle_menu_dv | 24 | | Theme| Theme in use |theme, theme_dv | 25 | 26 | You can access to all these properties from the [Client Script](widget_client_script.md) using: `$scope.portal` 27 | -------------------------------------------------------------------------------- /documentation/portal_url.md: -------------------------------------------------------------------------------- 1 | 2 | ## Portal URL 3 | Navigation is possible to a page or portal, this explains the URL schema. 4 | 5 | ##Navigating by Portal 6 | Navigating by portal displays the portal including the header, footer, and theme defined by the [Portal](portal.md) 7 | 8 | `https:///?id=&` 9 | 10 | Elements: 11 | - **Base Instance URL:** unique, secure Web address for each instance. The default format is: `https://.service-now.com.` 12 | - **sp url suffix:** Suffix established for the Service [Portal](portal.md) 13 | - **id:** The id of the [Page](page.md) to navigate to within the portal frame 14 | - **page parameters:** Some pages require additional parameters to lookup a record (table, sys_id) 15 | 16 | ##Navigating by Page 17 | `https:///$sp.do?id=&` 18 | 19 | Elements: 20 | - **Base Instance URL:** unique, secure Web address for each instance. The default format is: `https://.service-now.com.` 21 | - **id:** The id of the [Page](page.md) to navigate to within the portal frame 22 | - **page parameters:** Some pages require additional parameters to lookup a record (table, sys_id) 23 | 24 | -------------------------------------------------------------------------------- /documentation/service_catalog_patch2_changes.md: -------------------------------------------------------------------------------- 1 | # Service Catalog Patch 2 Changes 2 | 3 | There have been a number of improvements made to Service Portal's Service Catalog offering with Helsinki Patch 2, which are be enumerated and documented below. 4 | 5 | 1. Values that have been assigned to variables in order guides now "cascade" down to catalog items within the order guide. 6 | 2. Variable Attributes defined on a Catalog item variable are now respected by Service Portal's Reference Element field. 7 | 3. Labels for Service Catalog items that contain HTML now render the HTML inside the tag, instead of showing the HTML in plain text. 8 | 9 | --- 10 | 11 | ## Cascading Variables 12 | In Helsinki Patch 2 and above, any variables defined within an Order Guide marked `Cascade Variables` will cascade their values down to variables within contained Catalog Items with the same name. Below is an example: 13 | 14 | 1. Create an order guide, make sure that the checkbox titled `Cascade Variables` is checked. 15 | 2. Create a variable within the order guide, give it the name `cascading_value`. The variable can be of any type. 16 | 3. Add a rule containing a Catalog Item with a variable in it of the name `cascading_value`. 17 | 4. Notice that when you populate the Order Guide variable with a value, that value will be carried to the equivalent variable to the individual ordered items. 18 | 19 | ## Variable Attributes 20 | In a reference element field on a Service Catalog item, you can optionally define several Variable Attributes on the variable. This give a Service Catalog administrator control over what fields to display in the autocomplete dropdown for a reference element, what fields to search over, and what order to display them in. These variables are now supported in Service Portal, and their usage is documented in full at [the ServiceNow documentation site](http://wiki.servicenow.com/index.php?title=Auto-Complete_for_Reference_Fields#gsc.tab=0). 21 | 22 | ## HTML in Labels 23 | In Helsinki Patch 2 and above, HTML written into a label field will be rendered as HTML in the label on a Service Catalog item. This means that tags such as `` and `
` will be rendered as HTML. 24 | 25 | So, for example, suppose you have a Service Catalog variable with it's Question field written as this: 26 | 27 | ``` HTML 28 |
29 | For remote employees:
30 | Please go to CDW to order headsets, USBs, etc.
31 |
CDW Link 32 |
33 | 34 | ``` 35 | 36 | That field will be rendered like this on the Service Catalog page: 37 | ![Service Catalog HTML in Label](../assets/service_catalog_patch2_changes/label-html.png) 38 | -------------------------------------------------------------------------------- /documentation/service_portal.md: -------------------------------------------------------------------------------- 1 | # Service Portal 2 | Service Portal contains of two parts: 3 | 4 | - *Framework*: a set of APIs, [Angular](https://angularjs.org/) services, directives and tools that help to build portals. 5 | 6 | ![Framework](../assets/home/sp-home.png) 7 | 8 | - [*Portals*](portal.md): a group of pages linked by their `page id`. For example: `[your instance]/sp` is the Default Service Portal. 9 | 10 | ![Service Portal](../assets/home/service-portal.png) 11 | 12 | ***Learn more:*** 13 | 14 | + [Portal](portal.md) 15 | + [Widget](widget.md) 16 | -------------------------------------------------------------------------------- /documentation/spModal.md: -------------------------------------------------------------------------------- 1 | # spModal api 2 | _Available in Helsinki Patch 5_ 3 | 4 | spModal provides an alternative way to show alerts, prompts, and confirmation dialogs. Additionally you can use spModal.open() to display a widget in a modal dialog. spModal is a lightweight wrapper for angular UI bootstrap's $uibModal. See here for more info: https://angular-ui.github.io/bootstrap/#/modal 5 | 6 | | Method | Description | 7 | | :------ | :----------- | 8 | | [alert](#alert)(message).then(fn) | Alert a message. The promise contains a single argument that returns true/false. | 9 | | [confirm](#confirm)(message).then(fn) | Display a confirmation message. The promise contains a boolean of the user's response. | 10 | | [prompt](#prompt)(message, *defaultValue*).then(fn) | Prompt the user for input. Provide a message and an optional default value for the input field. The promise contains the user's response as a string. | 11 | | [open](#open)(object options).then(fn) | Open a modal with a customized set of options. See the options table below. | 12 | 13 | **Options** object definition 14 | 15 | | Option | type | Default | Description | 16 | | :------ | :------ | :------ | :----------- | 17 | | title | string | empty | goes in header - can be HTML | 18 | | message | string | empty | goes in the body - can be HTML | 19 | | buttons | array | Cancel & OK | buttons to show on the dialog | 20 | | input | bool | false | if true, shows an input field on the dialog | 21 | | value | string | empty | The value of the input field | 22 | | widget | string | empty | The Widget Id or sys_id to embed in the modal | 23 | | widgetInput | object | null | An object to send to the embedded widget as input | 24 | | shared | object | null | A client-side object to share data with the embedded widget client script | 25 | | size | string | empty | 'sm' or 'lg' | 26 | 27 | ## Examples 28 | 29 | Alert 30 | ------ 31 | 32 | ![alert modal](/assets/spmodal/alert.png) 33 | 34 | **Html Template** 35 | ```html 36 | 39 | ``` 40 | 41 | **Client Script** 42 | ```javascript 43 | function(spModal) { 44 | var c = this; 45 | c.onAlert = function () { 46 | spModal.alert('How do you feel today?').then(function (answer) { 47 | c.simple = answer; 48 | }); 49 | } 50 | } 51 | ``` 52 |

53 | 54 | Confirm 55 | ------ 56 | 57 | ![confirm modal](/assets/spmodal/confirm.png) 58 | 59 | **Html Template** 60 | ```html 61 | 64 | {{c.confirmed}} 65 | ``` 66 | 67 | **Client Script** 68 | ```javascript 69 | function(spModal) { 70 | var c = this; 71 | c.onConfirm = function() { 72 | c.confirmed = "asking"; 73 | spModal.confirm("Can you confirm or deny this?").then(function(confirmed) { 74 | c.confirmed = confirmed; // true or false 75 | }) 76 | } 77 | } 78 | ``` 79 |

80 | 81 | Confirm with HTML message 82 | ------ 83 | 84 | ![confirm modal with html message](/assets/spmodal/confirm_html_message.png) 85 | 86 | **Html Template** 87 | ```html 88 | 91 | {{c.confirmed}} 92 | ``` 93 | 94 | **Client Script** 95 | ```javascript 96 | function(spModal) { 97 | var c = this; 98 | // more control, passing options 99 | c.onConfirmEx = function() { 100 | c.confirmed = "asking"; 101 | var warn = ''; 102 | spModal.open({ 103 | title: 'Delete this Thing?', 104 | message: warn + ' Are you sure you want to do that?' 105 | }).then(function(confirmed) { 106 | c.confirmed = confirmed; 107 | }) 108 | } 109 | } 110 | ``` 111 | 112 | 113 |

114 | 115 | Prompt 116 | ------ 117 | 118 | ![spModal prompt dialog](/assets/spmodal/prompt.png) 119 | 120 | **Html Template** 121 | ```html 122 | 125 |
126 | You answered {{c.name}} 127 |
128 | ``` 129 | 130 | **Client Script** 131 | ```javascript 132 | function(spModal) { 133 | var c = this; 134 | c.onPrompt = function() { 135 | spModal.prompt("Your name please", c.name).then(function(name) { 136 | c.name = name; 137 | }) 138 | } 139 | } 140 | ``` 141 | 142 | 143 |

144 | 145 | Open 146 | ------ 147 | 148 | ### Example 1: Prompt with label 149 | 150 | ![spModal prompt with message](/assets/spmodal/prompt_with_label.png) 151 | 152 | **Html Template** 153 | ```html 154 | 157 |
158 | You answered {{c.name}} 159 |
160 | ``` 161 | 162 | **Client Script** 163 | ```javascript 164 | function(spModal) { 165 | var c = this; 166 | c.onOpen = function() { 167 | //ask the user for a string 168 | spModal.open({ 169 | title: 'Give me a name', 170 | message: 'What would you like to name it?', 171 | input: true, 172 | value: c.name 173 | }).then(function(name) { 174 | c.name = name; 175 | }) 176 | } 177 | } 178 | ``` 179 | 180 | 181 |

182 | 183 | ### Example 2: Agree with custom buttons 184 | 185 | ![spModal agree dialog](/assets/spmodal/open_with_promise.png) 186 | 187 | **Html Template** 188 | ```html 189 | 192 |
193 | You answered {{c.agree}} 194 |
195 | ``` 196 | 197 | **Client Script** 198 | ```javascript 199 | function(spModal) { 200 | var c = this; 201 | c.onAgree = function() { 202 | // ask the user for a string 203 | // note embedded html in message 204 | var h = '

Apple likes people to agree to lots of stuff

' 205 | var m = 'Your use of Apple software or hardware products is based on the software license and other terms and conditions in effect for the product at the time of purchase. Your agreement to these terms is required to install or use the product. ' 206 | spModal.open({ 207 | title: 'Do you agree?', 208 | message: h + m, 209 | buttons: [ 210 | {label:'✘ ${No}', cancel: true}, 211 | {label:'✔ ${Yes}', primary: true} 212 | ] 213 | }).then(function() { 214 | c.agree = 'yes'; 215 | }, function() { 216 | c.agree = 'no'; 217 | }) 218 | } 219 | } 220 | ``` 221 | 222 | 223 |

224 | 225 | ### Example 3: Embedded widget 226 | 227 | ![spModal embedded widget](/assets/spmodal/embedded_widget.png) 228 | 229 | **Html Template** 230 | ```html 231 | 234 | ``` 235 | 236 | **Client Script** 237 | ```javascript 238 | function(spModal) { 239 | var c = this; 240 | c.onWidget = function(widgetId, widgetInput) { 241 | spModal.open({ 242 | title: 'Displaying widget ' + widgetId, 243 | widget: widgetId, 244 | widgetInput: widgetInput || {} 245 | }).then(function(){ 246 | console.log('widget dismissed'); 247 | }) 248 | } 249 | } 250 | ``` 251 | 252 |

253 | 254 | ### Example 4: Modal sizes 255 | 256 | ![spModal size small](/assets/spmodal/size_sm.png) 257 | ![spModal size medium](/assets/spmodal/size_md.png) 258 | ![spModal size large](/assets/spmodal/size_lg.png) 259 | 260 | **Html Template** 261 | ```html 262 | 265 | 268 | 271 | ``` 272 | 273 | **Client Script** 274 | ```javascript 275 | function(spModal) { 276 | var c = this; 277 | c.onSize = function(size) { 278 | spModal.open({ 279 | title: 'Bootstrap modal sizes, sm, lg', 280 | size: size, 281 | message: 'Size set to ' + size 282 | }) 283 | } 284 | } 285 | ``` 286 | 287 | 288 |

289 | 290 | ### Example 5: Embedded widget with shared data 291 | 292 | ![open_shared_data](/assets/spmodal/open_shared_data.gif) 293 | 294 | This example requires 2 widgets. 295 | 296 | #### Parent Widget 297 | 298 | **Html Template** 299 | ```html 300 |
301 | 304 | 305 |
306 | You picked: {{c.selectedValue.text}} 307 |
308 |
309 | ``` 310 | 311 | **Client Script** 312 | ```javascript 313 | function ($scope,spModal) { 314 | var c = this; 315 | var shared = {}; 316 | c.onChangeSchedule = function(){ 317 | spModal.open({ 318 | title: 'Select a value', 319 | widget: 'bec1438bdbf276009ed8f81d0f96193e', 320 | widgetInput: { hint: "Soup or Nuts?" }, 321 | shared: shared 322 | }).then(function() { 323 | // Shared object was updated 324 | c.selectedValue = shared.selection; 325 | }); 326 | } 327 | } 328 | ``` 329 | 330 | #### Embedded Widget 331 | 332 | Name: **bec1438bdbf276009ed8f81d0f96193e** 333 | 334 | **Html Template** 335 | ```html 336 |
337 | 340 |
341 | ``` 342 | 343 | **Client Script** 344 | ```javascript 345 | function() { 346 | var c = this; 347 | 348 | var shared = c.widget.options.shared; 349 | c.selection = function selection(newVal) { 350 | return angular.isDefined(newVal) ? (shared.selection = newVal) : shared.selection; 351 | } 352 | } 353 | ``` 354 | 355 | **Server Script** 356 | ```javascript 357 | (function() { 358 | data.hint = input.hint; 359 | data.questions=[]; 360 | data.questions.push({text: 'Soup', value: 'soup'}); 361 | data.questions.push({text: 'Nuts', value: 'nuts'}); 362 | })(); 363 | ``` 364 | -------------------------------------------------------------------------------- /documentation/sso_configuration.md: -------------------------------------------------------------------------------- 1 | # SSO, Login & Redirect 2 | 3 | _Working since Helsinki Patch 2_ 4 | 5 | #### A few words on SSO 6 | If you use SSO, Service Portal should just work like you would expect. If you are using the system property to automatically redirect to your primary IDP, then Service Portal will automatically redirect to that IDP. If you have multiple identity providers, Service Portal shows a link on the login page to "Use external login". You can conditionally redirect users to Service Portal after login by following the steps in this guide. 7 | 8 | * Require authentication for every Service Portal 9 | * Make Service Portal your default login page 10 | * Conditionally redirect to Service Portal after login 11 | 12 | ### Require authentication for every Service Portal 13 | 14 | Some companies want their portal content available to only authenticated users. To do this, create a record in the sys_public table with the following values: 15 | 16 | Page: $sp 17 | Active: false 18 | 19 | Now when you go to [instance]/sp or [instance]/$sp.do you will be redirected to the platform configured login page if you're unauthenticated. This may be useful for companies with more complex SSO environments. 20 | 21 | ### Make Service Portal your login page 22 | 23 | To make Service Portal the login page for your instance 24 | set the system property glide.entry.page.script = "new SPEntryPage().getLoginURL()" 25 | 26 | #### Configuring SPEntryPage 27 | 28 | **Setting the portal** 29 | 30 | SPEntryPage uses /sp/ as the portal path to redirect to. If you must, edit the SPEntryPage Script Include and change the assigned portal to any portal_suffix you want. (Once you make changes to this script include it won't be upgraded with future updates) 31 | 32 | ![Screenshot](../assets/sso/portal_suffix.png) 33 | 34 | 35 | ### Conditionally redirect to Service Portal after login 36 | 37 | To conditionally redirect a user to Service Portal after login, set the system property glide.entry.first.page.script = "new SPEntryPage().getFirstPageURL()" 38 | 39 | getFirstPageURL does 2 primary things: 40 | 41 | 1. Redirects to login_redirect.do in order to break out of the frameset (if there is one). 42 | 2. Redirects to Service Portal if the user has no roles, or the full platform for everyone else. 43 | 44 | You can customize this behavior within the "SPEntryPage" script include. (Once you make changes to this script include it won't be upgraded with future updates) 45 | 46 | ### Debugging 47 | 48 | To view debug output from SPEntryPage and see the session variables it redirects based on: 49 | 50 | 1. Make sure the system property "glide.entry.first.page.script" has the value: new SPEntryPage().getFirstPageURL() 51 | 52 | 2. Open the SPEntryPage script include and find and set "this.logVariables = true" 53 | 54 | 3. In a different browser, log in. 55 | 56 | 4. The log output can be viewed by going to "System Logs > System Log > All" in the navigator. 57 | 58 | Or by going directly to: /syslog_list.do?sysparm_query=level%3D0%5EORDERBYDESCsys_created_on&sysparm_first_row=1&sysparm_view= 59 | -------------------------------------------------------------------------------- /documentation/widget.md: -------------------------------------------------------------------------------- 1 | ### Widget 2 | 3 | A widget is a superset of an [Angular directive](https://docs.angularjs.org/guide/directive) that is tightly coupled to a server-side JavaScript code block powered by the Rhino engine under the ServiceNow platform. 4 | 5 | Since widgets are `read-only` to benefit from future updates, you can't update their code. If you need to make major changes, 6 | *clone* the widget and give it another `name` and `id`. 7 | 8 | ### Widget Instance 9 | Once you drop a widget into a column using the Service Portal Designer it will create a widget instance. 10 | A widget instace is a reference to a widget that contains: location, properties and CSS especific for that instance. A widget used multiple times in the same page, will use multiple instances. 11 | 12 | ![Widget Instance](../assets/widget/widget-instance.png) 13 | 14 | 15 | ***Learn more:*** 16 | 17 | - [HTML](widget_html.md) 18 | - [Client Script](widget_client_script.md) 19 | - [Server Script](widget_server_script.md) 20 | - [Dependencies](widget_dependencies.md) 21 | - [CSS/SCSS](css.md) 22 | - [Embedded Widgets](widget_embedded.md) 23 | - [Server Script APIs](widget_server_script_apis.md) 24 | - [Instances](widget_instances.md) 25 | - [Options](widget_options.md) 26 | -------------------------------------------------------------------------------- /documentation/widget_client_script.md: -------------------------------------------------------------------------------- 1 | #### Client Script 2 | This is the controller already linked to the widget. Consider every widget to be an Angular directive – you define the controller for that directive here. This is where you handle all the client-side logic and template binding for your widget. 3 | ```javascript 4 | function() { 5 | var c = this; 6 | c.update = function() { 7 | c.data.price = false; 8 | c.server.get({symbol: c.data.symbol}).then(function(r) { 9 | c.data.price = r.data.price; 10 | }); 11 | } 12 | } 13 | ``` 14 | 15 | | Property | Description | 16 | | :------ | :----------- | 17 | | `this.server.get([Object])` | Calls the server and sends custom `input`. Returns `Promise`. | 18 | | `this.server.update()` | Calls the server and `this.data` is automatically send to server side. Returns `Promise`. | 19 | | `this.server.refresh() ` | Calls the server and automatically replaces the current options and data from the server response. Returns `Promise` | 20 | -------------------------------------------------------------------------------- /documentation/widget_client_script_apis.md: -------------------------------------------------------------------------------- 1 | # spUtil 2 | 3 | Set of methods that perform common, often re-used functions. 4 | 5 | | Method | Description| 6 | | :------ | :----------- | 7 | | addErrorMessage(String message)| Displays a notification error message | 8 | 9 | ```javascript 10 | spUtil.addErrorMessage("There has been an error processing your request") 11 | ``` 12 | 13 |
14 | 15 | | Method | Description| 16 | | :------ | :----------- | 17 | | addInfoMessage(String message) | Displays a notification info message | 18 | 19 | ```javascript 20 | spUtil.addInfoMessage("Your order has been placed") 21 | ``` 22 | 23 |
24 | 25 | | Method | Description| 26 | | :------ | :----------- | 27 | | addTrivialMessage(String message)| Displays a notification trivial message | 28 | 29 | ```javascript 30 | spUtil.addTrivialMessage("Thanks for your order") 31 | ``` 32 | 33 |
34 | 35 | | Method | Description| 36 | | :------ | :----------- | 37 | | get(String widgetId) | Gets a widget model by id or sys_id. Returns Promise. | 38 | 39 | ```javascript 40 | spUtil.get("widget-cool-clock").then(function(response) { 41 | c.coolClock = response; 42 | }); 43 | ``` 44 | 45 |
46 | 47 | 48 | | Method | Description| 49 | | :------ | :----------- | 50 | | format(String, Object) | Alternative to string concatenation | 51 | 52 | Let's say you want to build a string with variables: `'An error occurred: ' + error + ' when loading ' + widget` 53 | instead of doing string concatenation you can use `format()`. 54 | ```javascript 55 | spUtil.format('An error ocurred: {error} when loading {widget}', {error: '404', widget: 'sp-widget'}) 56 | ``` 57 | 58 |
59 | 60 | | Method | Description| 61 | | :------ | :----------- | 62 | | refresh(Object $scope) | Calls the server and automatically replaces the current options and data from the server response. Returns Promise | 63 | 64 | Same as `server.refresh()` The diference is that you can define what $scope to pass over. 65 | 66 |
67 | 68 | | Method | Description| 69 | | :------ | :----------- | 70 | | recordWatch(Object $scope, String table, String filter, Function callback)| watch for a table / filter update - callback when it happens | 71 | 72 | ```javascript 73 | spUtil.recordWatch($scope, "live_profile", "sys_id=" + liveProfileId); 74 | ``` 75 | More documentation on recordWatch can be found [here](./widget_record_watch.md). 76 | 77 |
78 | 79 | | Method | Description| 80 | | :------ | :----------- | 81 | | update(Object $scope) | Calls the server and `this.data` is automatically send to server side. Returns Promise. | 82 | 83 | Same as `server.update()`. The diference is that you can define what $scope to pass over. 84 | 85 | `Do not try to use any other methods from spUtil() that are not listed here` 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /documentation/widget_css.md: -------------------------------------------------------------------------------- 1 | # Widget CSS 2 | -------------------------------------------------------------------------------- /documentation/widget_dependencies.md: -------------------------------------------------------------------------------- 1 | ## Widget Dependencies 2 | In Service Portal, it is possible to link Javascript and CSS files to widgets. This allows developers to create dependencies between their widgets and third party libraries, external style sheets, and angular modules. Dependencies are loaded asynchronous from the server at the time that they are needed. 3 | 4 | Following is a step-by-step guide on creating new dependency packages and associating them with widgets. 5 | 6 | ### Creating a Dependency Package 7 | A dependency package is a collection of Javascript and CSS files that can be then connected to a widget. Dependencies can be found in the table `sp_dependency`, or by navigating to the Service Portal module in the navigator and selecting the Dependencies submodule. 8 | 9 | In a dependency record, you will define the following: 10 | 11 | 1. Name - The name that your dependency will be referred to by (Useful for selecting a dependency from a dropdown list) 12 | 13 | 2. Include on page load - Select if you want your dependency to be loaded onto the page on initial page load of Service Portal, or leave unchecked to load the dependency only when the linked widget is loaded onto a page. 14 | 15 | 3. Angular module name - Only necessary if the linked Javascript is an Angular module. Provide the name of the Angular module name that you are loading in, so that it can be injected into the Service Portal angular application. Leave blank if not applicable. 16 | 17 | Once these fields are defined, you can start creating records in the `sp_js_include` and `sp_css_include` table and adding them to the JS Includes and CSS Includes related lists in a dependency record. 18 | 19 | ### Adding Files to a Dependency Package 20 | Here, we will quickly go over how to add files to a dependency package. Individual JS and CSS files can be found in the tables `sp_js_include` and `sp_css_include`, respectively. 21 | 22 | In a include record, you will define the following: 23 | 24 | 1. Display Name - The name of the include (Useful for selecting includes from a dropdown list). 25 | 26 | 2. Source - Your options here are going to depend on whether you are making a new JS include or a CSS include. 27 | 28 | Both JS and CSS includes have URL as an option, which is a way to provide a simple URL path to the file you want to include. ex. https://code.highcharts.com/highcharts.js 29 | 30 | The second option will depend on the file type. JS includes allow you to reference a UI Script record. CSS includes allow you to reference a SP CSS record, found in the table `sp_css`. 31 | 32 | Once you have created your include records, you can add them to your dependency package. Navigate back to your dependency record that you created earlier, and open up the related lists. In both the JS Includes and the CSS Includes related lists, you will do the following: 33 | 34 | 1. Select the tab for the related list 35 | 2. Click the Edit button 36 | 3. Using the slushbucket that has appeared on your screen, move any includes you with to add to your dependency package into the column on the right hand side of the screen. 37 | 4. Press Save 38 | 5. From the Related List on the Dependency record, update the Order field on each included file to specify what order the files should be loaded into the page. Files with lower Order values are loaded first. This is important if your fields depend on one another to be on the page to load correctly. 39 | 40 | ### Adding a Dependency Package to a Widget 41 | Finally, we can create a relationship between our new Dependency and a widget. To do this, follow these steps: 42 | 43 | 1. Navigate to the widget record you wish to update 44 | 2. Scroll to the bottom of the record, and open the Dependencies related list 45 | 3. Select the Edit button on the list 46 | 4. Find the dependency you want to add to the widget in the left column of the slushbucket, and move it to the right column. 47 | 5. Press Save 48 | 49 | That's it! Remember - a widget can have as many or as few dependencies as you want it to have, but the more you add, the more content your widget will need to download to render on the page. Keep the dependencies as small as possible for fast load times. 50 | -------------------------------------------------------------------------------- /documentation/widget_embedded.md: -------------------------------------------------------------------------------- 1 | 2 | # Embedded Widgets 3 | In Service Portal, widgets can be embedded inside other widgets. This technique is useful for creating more powerful widgets through the composition of other widgets. 4 | 5 | For a direct example of this, see the Social QA Question widget, which embeds a login widget next to the Answer Question section for an easy way to prompt users to login to answer questions. 6 | 7 | --- 8 | 9 | ## Widget Directive Syntax 10 | You can embed any widget inside of your widget’s [HTML template](widget_html.md) using the custom `` element. 11 | The basic usage looks like this: 12 | 13 | ###### HTML Template 14 | ```html 15 |
16 | 17 |
18 | ``` 19 | _The `id` parameter is simply the id of the widget you're trying to embed._ 20 | 21 | ## Widget Options 22 | 23 | Widgets might have [options](widget_options.md) that you can setup. You can define their values in JSON format: 24 | 25 | 26 | ### Providing options in the HTML template 27 | 28 | ###### HTML Template 29 | ```html 30 | 31 | ``` 32 | 33 | ![Clock Options](../assets/widget_embedded/clock-options.png) 34 | 35 | You don't necessarily need to provide options in the HTML template. 36 | 37 | ### Providing options server-side 38 | 39 | ###### HTML template 40 | ```html 41 | 42 | ``` 43 | ###### Server Script 44 | ```javascript 45 | (function() { 46 | data.clockOptions = {"zone": "America/Los_Angeles","title": "San Diego, CA"}; 47 | })(); 48 | ``` 49 | 50 | ### Embedded Widgets client-side 51 | 52 | ###### HTML Template 53 | ```html 54 | 55 | ``` 56 | 57 | ###### Client Script 58 | ```javascript 59 | function(spUtil) { 60 | var c = this; 61 | spUtil.get("widget-cool-clock").then(function(response) { 62 | c.myClockWidget = response; 63 | }); 64 | } 65 | ``` 66 | 67 | ------ 68 | 69 | 70 | ## Example: How to embed a widget multiple times with custom options 71 | 72 | Each instance of the clock is provided a different timezone and title. 73 | 74 | > To see what options are configurable in the cool clock widget, open it in the widget editor. It uses the options object for the title, second hand color, and the timezone. This screenshot shows you where they're hiding. 75 | 76 | > ![Cool clock client script](../assets/widget_embedded/example_clock_options_1.png) 77 | 78 | Edit the "Embedded clock" widget and replace with the following code blocks: 79 | 80 | ###### HTML Template 81 | ```html 82 |
83 |
Time across the US
84 |
85 |
86 |
87 | 88 |
89 |
90 |
91 |
92 | ``` 93 | 94 | ###### CSS 95 | ```css 96 | .panel { 97 | margin-top: 10px; 98 | } 99 | ``` 100 | 101 | ###### Client Script 102 | ```javascript 103 | function() { 104 | // nothing to do here... 105 | } 106 | ``` 107 | 108 | ###### Server Script 109 | ```javascript 110 | (function() { 111 | var options = [ 112 | {zone: "America/Los_Angeles", title: "San Diego"}, 113 | {zone: "America/Denver", title: "Denver"}, 114 | {zone: "America/Chicago", title: "Chicago"}, 115 | {zone: "America/New_York", title: "New York"} 116 | ]; 117 | 118 | data.clocks = []; 119 | for (var i in options) { 120 | data.clocks.push($sp.getWidget("widget-cool-clock", options[i])); 121 | } 122 | })(); 123 | ``` 124 | ### Result 125 | Each instance of the clock widget has a different timezone and title. 126 | 127 | ![Embedded clock](../assets/widget_embedded/example_clock_options_2.png) 128 | 129 | --- 130 | 131 | ## API Reference 132 | 133 | ### Client Side 134 | ##### spUtil.get() - Get a widget model via client script 135 | 136 | ```javascript 137 | spUtil.get("widget-sc-cat-item", {sys_id: "your_catalog_item_sys_id"}).then(function(response) { 138 | c.catalogItemWidget = response; 139 | }); 140 | ``` 141 | **Parameters** 142 | 143 | - (_string_) widget\_id 144 | Can be a widget_id or widget sys_id. 145 | - (_object_) data 146 | An object to post to the widget's server script. Refer to this object as **input** in your server script. 147 | 148 | **Callback** 149 | 150 | The callback function is called when the widget model is ready. The response object contains the full widget model. 151 | 152 | 153 | ### Server Side 154 | ##### $sp.getWidget() - Get a widget model via server script 155 | 156 | ```javascript 157 | data.catalogItemWidget = $sp.getWidget("widget-sc-cat-item", {sys_id: "your_catalog_item_sys_id"}); 158 | ``` 159 | **Parameters** 160 | 161 | - (*string*) widget\_id 162 | Can be a widget_id or widget sys_id. 163 | - (*object*) options 164 | An object to pass to the widget's server script. Refer to this object as **options** in your server script. 165 | 166 | **Note:** As of all versions of Helsinki, any options passed into this function will only be available in the embedded widget's server script on the **first execution** of that script. Any subsequent calls into the server script from the embedded widget will not contain the object properties passed in. This is something we are investigating for a future version of Helisinki or Istanbul. 167 | 168 | ## Widget Model in depth 169 | 170 | The widget model contains all of the client-side parts of a widget needed to create an angular directive. The HTML template, client script, and link function are loaded just as they are in the sp_widget record. The data property is the result of the widget's server script execution. Anything that you put on the data object on the server is available in the data object on the client. 171 | 172 | Here is a detailed look at some of the fields in the widget model: 173 | 174 | | Property name | Type | Description | 175 | | ------------- | ---- | ----------- | 176 | | client_script | string | The widget's client script field | 177 | | css | string | The compiled css output from the widget's sass field | 178 | | data | object | The data object containing all of the keys and values added to it in the widget's server script | 179 | | dependencies | array | A collection of javascript libraries to load before the widget executes | 180 | | options | object | The options used to initialize the widget | 181 | | template | string | The widget's HTML Template field | 182 | -------------------------------------------------------------------------------- /documentation/widget_html.md: -------------------------------------------------------------------------------- 1 | #### Widget HTML 2 | This is where the HTML markup for your widget goes. Inside the template , you can leverage AngularJS’s two-way binding to bind your controller variables to your markup. It uses the `controllerAs c` syntax for basic binding. 3 | ```html 4 |
5 | ${Symbol Lookup}: 6 | 8 |
9 |

${Stock Price}: 10 | ${Requesting stock price}{{c.data.price | currency:"$"}} 11 |

12 | 13 |
14 |
15 | ``` 16 | -------------------------------------------------------------------------------- /documentation/widget_instances.md: -------------------------------------------------------------------------------- 1 | ## Configuring Widgets with Instances 2 | In Service Portal, widgets are modular, configurable blocks of functionality and UI that are designed to be reusable. 3 | 4 | Whenever you embed a widget in a page, you are automatically creating an `sp_instance` record which contains three important things. 5 | 6 | 1. Reference to a column (where a widget is located) 7 | 2. Reference to a widget 8 | 3. Configuration for a widget in the form of pre-defined form fields and an Additional Options field in JSON format 9 | 10 | There are a number of ways that you can configure a widget, so we'll go through an example to get started with the basics. 11 | 12 | For information on working with instance options, read [Widget Options](widget_options.md) after you're done with this section. 13 | 14 | ### Configuring a Simple List Widget 15 | Let's try configuring a Simple List widget to show a list of problems from the `problem` table, and we will make each list entry link to a Form page. Start by embedding the Simple List widget in the index page, then navigate to that page URL either through a portal or by navigating to /$sp.do?id=index 16 | 17 | Now, let's start configuring the widget. Hold the CTRL button and right-click the widget from the page. If you are logged in as a SP Admin, you should see a context menu appear with a list of links, one of which should say **Instance Options**. Click that link, and you will see a modal appear on the screen containing all of the configuration options that the Simple List widget exposes to you. 18 | 19 | Now, from this modal, we will fill in the following fields: 20 | 21 | * Table - **Problem** 22 | * Display field - **Short description** 23 | * Link to this page - **form** 24 | * Secondary fields - **number**, **sys_updated_on** 25 | 26 | Hit **Save**, and the page will refresh with your newly-configured widget. Click on one of the List entries, and notice that you will be taken to a Form page for that record. 27 | 28 | ### The 'Link to this page' field is missing from my instance - what do I do? (Issue Fixed in Helsinki Patch 1) 29 | If you click on a record from the list and it does not open, type `sp_instance.list` in the left navigator, then find the instance of your Simple List widget. After you open the Widget Instance form, right click the header and select `Configure > Form Layout` from the context menu. Now find the 'Link to this page' field and add it to the Instance of Simple List view of the form. Click 'Save'. Go back to the Widget Instance form and select the page, that your Simple List needs to open records, by finding the page in the 'Link to this page' reference field. 30 | -------------------------------------------------------------------------------- /documentation/widget_internationalization.md: -------------------------------------------------------------------------------- 1 | # Internationalization 2 | 3 | To internationalize strings in a widget, use `${string}` or `gs.getMessage("message")`. See when to use one form or another below: 4 | 5 | [Translating strings in the HTML template](#translating-strings-in-the-html-template) 6 | 7 | [Translating strings in the Client Script](#translating-strings-in-the-client-script) 8 | 9 | [Translating strings in the Server Script](#translating-strings-in-the-server-script) 10 | 11 | [Safe translations](#safe-translations) 12 | 13 | [Language Switch Widget](#language-switch-widget) 14 | 15 | 16 | ### Translating strings in the HTML template 17 | #### HTML Template 18 | ```html 19 |
20 |

${This message will be internationalized.}

21 |

However, this will NOT be.

22 |
23 | ``` 24 | Writing text as ``${message}`` is the equivalent of writing ``${gs.getMessage("message")}`` in other parts of the system, but written as a more legible shorthand. 25 | 26 |
27 | 28 | ### Translating strings in the Client Script 29 | #### Client Script 30 | Text can be internationalized the same way inside a client script. 31 | ```javascript 32 | function() { 33 | var c = this; 34 | c.message = "${This message will be internationalized}"; 35 | } 36 | ``` 37 | #### HTML Template 38 | ```html 39 |
40 | 41 |

{{c.message}}

42 |
43 | ``` 44 | 45 |
46 | 47 | ### Translating strings in the Server Script 48 | 49 | Great for translating schema options and other values fetch during server-side runtime. 50 | 51 | #### Server Script 52 | ```javascript 53 | function() { 54 | data.message = gs.getMessage("this message contains 'quotes'"); 55 | } 56 | ``` 57 | 58 | ##### HTML Template 59 | ```html 60 |
61 |

{{c.data.message}}

62 |
63 | ``` 64 | 65 |
66 | 67 | ### Safe translations 68 | In some cases, the translation might have quotes or double quotes on it. That could lead to JavasScript errors if you are using the ${} syntax in the client script. 69 | The safest way to fetch a translated message is to do it in the server script. 70 | Then, assign the value to a client-side angular binding. 71 | 72 |
73 | 74 | ### Language Switch Widget 75 | 76 | Users might want to change the language on the portal. The following Widget can be used as template to implement a customized language switch: 77 | 78 | ##### HTML Template: 79 | ```html 80 |
81 | ${Change Language}: 82 | 88 | 89 |
90 | ``` 91 | 92 | ##### Client Script: 93 | ```javascript 94 | function($window) { 95 | var c = this; 96 | c.language = {value: 'en', displayValue: 'English'}; 97 | c.changed = function(a) { 98 | c.server.get(c.language).then(function() { 99 | $window.location.reload(); 100 | }) 101 | } 102 | } 103 | ``` 104 | 105 | ##### Server Script: 106 | ```javascript 107 | (function() { 108 | if (input) { 109 | var user = gs.getUser(); 110 | user.setPreference("user.language", input.value); 111 | user.savePreferences(); 112 | } 113 | })(); 114 | ``` 115 | -------------------------------------------------------------------------------- /documentation/widget_link.md: -------------------------------------------------------------------------------- 1 | # Link Function (Advanced) 2 | Since widgets are basically augmented Angular directives, the Link function is used in exactly the same way that Link functions on directives are used in Angular: http://stackoverflow.com/questions/20018507/angularjs-what-is-the-need-of-the-directives-link-function-when-we-already-had 3 | 4 | We don't do any additional things with them, and they aren't necessary for 99% of what you probably want to do in your widget. Sometimes, it makes sense to do direct DOM manipulation in a Link function instead of your controller. See the Angular docs for more info! 5 | -------------------------------------------------------------------------------- /documentation/widget_options.md: -------------------------------------------------------------------------------- 1 | # Widget Options 2 | In Service Portal, users can configure widgets embedded on pages through the power of **Widget Instances** (for more on this topic, read [Widget Instances](widget_instances.md) and return here for more). 3 | 4 | Now, let's go over how a Widget Developer could define an option schema within their own widgets to enable this level of configurability. 5 | 6 | ### Defining Option Schemas 7 | An **option schema** is a way of defining what properties users of your widgets can define. Any properties declared here will be surfaced when a user is editing the instance of a widget. Here, you can enable users to declare many types of fields, from primitive String and Numbers to reference fields. 8 | 9 | To do this, you will need to navigate to the Widget Editor and select the widget you wish to edit. In the top-right corner of the screen, select the hamburger icon and click the item called **Edit Option Schema**. 10 | 11 | You should be presented with something that looks like this: 12 | 13 | ![Edit Option Schema](../assets/widget_options/widget_options_schema_modal.png) 14 | 15 | This is where you can add and subtract widget options, along with types and hints. From here, press the + icon and give it a label, a name (snakecase, like_this), a type, and a hint. Depending on the type you select, you may be prompted to provide additional fields. 16 | 17 | Once you have provided your option(s), you can click the **Save** button and begin using them. 18 | 19 | To see your options in action, navigate to an instance of the widget on a page, hold CTRL and right-click the widget. Select the option titled **Instance Options**. In the modal popover, you will see your new option. 20 | 21 | ### Using Options in a Widget 22 | Now, let's go over how to access options in a widget, as well as some best practices. 23 | 24 | When developing a widget, you can access options from both the Server Script and the Client Script in the following way: 25 | 26 | ##### Client Script 27 | ```javascript 28 | function() { 29 | /* widget controller */ 30 | var c = this; 31 | console.log(c.options.text_color) //Outputs the text_color option for this instance 32 | } 33 | ``` 34 | 35 | ##### Server Script 36 | ```javascript 37 | (function() { 38 | $sp.log(options.text_color) //Logs the value of the text_color option to the browser console. 39 | })(); 40 | ``` 41 | 42 | #### Default Options 43 | 44 | Before an option value is set on an instance, it will appear as an undefined value when you access that option variable. Therefore, it's a good idea to specify default values for your options in the server script of a widget (to handle the situation where those option values haven't been provided yet). 45 | 46 | Luckily, in Javascript, that's easy: 47 | 48 | ##### Server Script 49 | ```javascript 50 | (function() { 51 | options.text_color = options.text_color || "blue"; 52 | options.maximum_entry_count = options.maximum_entry_count || 5; 53 | }) 54 | ``` 55 | -------------------------------------------------------------------------------- /documentation/widget_record_watch.md: -------------------------------------------------------------------------------- 1 | # Record Watch 2 | Record Watch is a tool that allows a widget developer to respond to table updates in real-time. For instance, by using Record Watch, the Simple List widget can listen for changes to its data table and if new records are added, removed, or updated, the widget can update itself in real-time. 3 | 4 | Below is an example of how to use Record Watch in a widget's Client Script. 5 | 6 | ##### Client Script 7 | ```javascript 8 | function(spUtil, $scope) { 9 | /* widget controller */ 10 | var c = this; 11 | 12 | spUtil.recordWatch($scope, "incident", "active=true", function(name, data) { 13 | console.log(name); //Returns information about the event that has occurred 14 | console.log(data); //Returns the data inserted or updated on the table 15 | }); 16 | } 17 | ``` 18 | 19 | The above code is registering a listener on the incident table with the filter "active=true", meaning that whenever something changes on that table with that filter, our callback function will be executed. 20 | 21 | The callback function takes two parameters: 22 | * `name` - An object which contains information about the scope of the update. 23 | * `data` - An object containing information about the operation that has taken place ('insert', 'update', or 'delete'), as well as the data for the record itself and, if applicable, a list of the changes that have occurred on that record. 24 | 25 | ### Usage Notes 26 | * When passing the `$scope` argument into the `spUtil.recordWatch` function, be sure to inject `$scope` into the parameters of your Client Script function. For details, see the code snippet above. 27 | * For a real example of using Record Watch, see the **Simple List Widget**. 28 | * Tables that are (periodically) subject to a high frequency of database events are blacklisted from Record Watcher to prevent event storms. 29 | -------------------------------------------------------------------------------- /documentation/widget_server_script.md: -------------------------------------------------------------------------------- 1 | ## Widget Server Script 2 | This is where you put the server-side logic for your widget. This is helpful primarily with interacting with the Glide platform through ServiceNow [server-side APIs](https://developer.servicenow.com/app.do#!/api_doc?id=server). 3 | 4 | ```javascript 5 | if (input) { 6 | var r = new RESTMessage('Yahoo Finance', 'get'); 7 | r.setStringParameter('symbol', input.symbol); 8 | var response = r.execute(); 9 | data.price = response.getBody(); 10 | } 11 | ``` 12 | 13 | This code will be executed within the context of the widget instance related to it. 14 | 15 | ### Server-side properties and helpers 16 | 17 | | Property | Description | 18 | | :------ | :----------- | 19 | | `input` | An object containing client-side properties set under `c.data`. It will have an `undefined` value until the client-side controller calls `c.server.update()` | 20 | | `data` | An object containing properties set during server-side execution | 21 | | `options` | An object containing the schema option properties | 22 | | [`$sp`](widget_server_script_apis.md#sp-api) | Helper class used to access server script API | 23 | -------------------------------------------------------------------------------- /documentation/widget_server_script_apis.md: -------------------------------------------------------------------------------- 1 | ### $sp API 2 | Service Portal provides a set of convenience methods found on the global `$sp` object, which is available in any widget server script. 3 | 4 | | Method | Description | 5 | | :----------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | 6 | | [canReadRecord](#canReadRecord)(Mixed, *opt String*): boolean | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-canReadRecord_GR) Returns true if the user can read the specified GlideRecord. | 7 | | [getCatalogItem](#getCatalogItem)(String): Object | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getCatalogItem_S) Returns a model and view model for a sc_cat_item or sc_cat_item_guide. | 8 | | [getDisplayValue](#getDisplayValue)(String): String | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getDisplayValue_S) Returns a display value from a field on a record in this order:
1. The widget's sp_instance* record
2. 9 | | [getField](#getField)(GlideRecord, String): Object | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getField_GR_S) Returns {display_value, label, type, value} for a given field on a GlideRecord. | 10 | | [getFields](#getFields)(GlideRecord, String): Array | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getFields_GR_S) Like getField Checks the specified field names, and returns a comma seperated list of valid names. | 11 | | [getFieldsObject](#getFieldsObject)(GlideRecord, String) | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getFieldsObject_GR_S) Checks the specified field names, and returns an object containing the valid names. | 12 | | [getForm](#getForm)(String table, String sys_id, /*Optional String*/ encodedQuery, /*Optional String*/ view) | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getForm_S_S) Returns the form| 13 | | [getListColumns](#getListColumns)(String tableName, String view): | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getListColumns_S_S) Returns a list of the specified table's columns in the specified view| 14 | | [getMenuHREF](#getMenuHREF)(GlideRecord): String | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getMenuHREF_GR) Returns the (?id=) portion of the URL based on the sp_menu type. | 15 | | [getMenuItems](#getMenuItems)(String sys_id): Array | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getMenuItems_S) Returns the menu items for the specified instance | 16 | | [getParameter](#getParameter)(String): Object | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getParameter_S) Returns the value of a given key from the query string or post body. | 17 | | [getPortalRecord](#getPortalRecord)(): GlideRecord | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getPortalRecord) Returns the portal's GlideRecord. | 18 | | [getRecord](#getRecord)(): Glide | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getRecord) Returns the GlideRecord for the current sp_instance\*. Returns null if the widget is embedded by another widget. | 19 | | [getRecordDisplayValues](#getRecordDisplayValues) (Object, GlideRecord, String): void | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getRecordDispValues_O_GR_S) Copies display values for the specified field names from a GlideRecord into the data parameter. | 20 | | [getRecordElements](#getRecordElements)(Object, GlideRecord, String): void | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getRecordElements_O_GR_S) Copies the value and display value for the specified field names from a GlideRecord into the data parameter. | 21 | | [getRecordValues](#getRecordValues) (Object, GlideRecord, String): void | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getRecordValues_O_GR_S) Copies values for the specified field names from a GlideRecord into the data parameter. | 22 | | getStream(String, String): Object | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getStream_S_S) Get the activity stream for a record. | 23 | | getUserInitials() | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getUserInitials) Returns the user's initials as a string. | 24 | | [getValue](#getValue)(String): Object | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getValue_S) Like [getDisplayValue](#getDisplayValue) except that it returns the value instead of the display value. | 25 | | [getValues](#getValues)(Object, String): void | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getValues_O_S) Copies values from the request or instance into the data parameter. | 26 | | [getValues](#getValues)(Object): void | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getValues_O_S) Copies values from the widget's sp_instance GlideRecord into the data parameter. | 27 | | [getWidget](#getWidget)(String, Object): Object | [Official Documentation](https://developer.servicenow.com/app.do#!/api_doc?v=jakarta&id=r_GSPS-getWidget_S__O) Returns a widget model for embedding a widget inside another widget. | 28 | | getKBRecord(): Unknown | Not documented - Returns the portal's KB record where the workflow state is published. | 29 | | getKBCount(): Unknown | Not documented - Returns the number of Knowledge Base articles. | 30 | | getKBCategoryArticles(): Unknown | Not documented - Returns KB articles in the specified category and its subcategories. Pass 'limit' to limit the number of articles returned. | 31 | | getKBTopicArticles(): Unknown | Not documented | 32 | | getKBTopCategoryID(): Unknown | Not documented - Returns the top category in the hierarchy containing the specified category. | 33 | | getKBSiblingCategories(): Unknown | Not documented - Returns KB categories with same parent as the specified category.| 34 | | getSCRecord(): Object | Returns sc_cat_item record for the portal's catalog with sys_class_name != sc_cat_item_wizard and active = true in the query. GlideRecord returned has not yet triggered the query. | 35 | | showCatalogPrices(): Unknown | Not documented - Is an object| 36 | | saveVariables(): Unknown | Not documented | 37 | | buildThemeVariableModel(): Unknown | Not documented | 38 | | getVariablesArray(): Unknown | Not documented - Returns the tables variables as an object. | 39 | | getWidgetFromInstance(): Unknown | Not documented - Returns a widget from the specified widget instance. | 40 | | getRecordVariablesArray(): Unknown | Not documented - Returns the records variables. | 41 | | getFilterBreadcrumbs(): Unknown | Not documented - Returns an array of objects where each object contains the breadcrumb label, value, and flags for if fixed and if removed| 42 | | logStat(String type, String table, String id, *opt String comments*): void | Create a new entry in the `sp_log` table with a table name, a record sys_id from that name, and some type and optional comments. Handy for doing things like logging searches or visits to pages, etc. | 43 | | getInstanceRecord(): Unknown | Not documented - Returns the widget instances GlideRecord| 44 | | log(): Unknown | Not documented - Sends the specified message to the log console. | 45 | | saveRecord(): Unknown | Not documented - Saves or updates the current record. | 46 | | logSearch(): Unknown | Not documented - Adds a record to the Service Portal Statistics logs. | 47 | 48 | 49 | 50 | $sp.getPortalRecord() 51 | ------ 52 | Useful for getting the current portal context. It returns the sp_portal GlideRecord if there is one. 53 | 54 | - $sp.getPortalRecord( ) 55 | - **Parameters** 56 | - None 57 | - **Returns** 58 | - (*GlideRecord*) The sp_portal record of the current portal context or null. 59 | 60 | Server Script 61 | 62 | ```javascript 63 | (function() { 64 | var portalGr = $sp.getPortalRecord(); 65 | data.logo = portalGr.getDisplayValue("logo"); 66 | data.homepage = portalGr.getDisplayValue("homepage.id"); 67 | })(); 68 | ``` 69 |
70 | HTML Template 71 | 72 | ```html 73 |
74 | 75 | Click here to go home 76 |
77 | ``` 78 |
79 | Result 80 | ![Screenshot](../assets/widget_server_script_apis/getPortalRecord.png) 81 | 82 | $sp.getWidget() 83 | ----- 84 | Gets a widget by id or sys_id, executes that widget's server script using the provided options, then returns the widget model. 85 | 86 | - $sp.getWidget( widget_id, options ): Object 87 | - **Parameters** 88 | - (*String*) widget\_id 89 | Can be a widget_id or widget sys_id. 90 | - (*Object*) options 91 | An object to pass to the widget's server script. Refer to this object as **options** in your server script. 92 | - **Returns** 93 | - (*Object*) A widget model to be used with \. 94 | 95 | Server Script 96 | 97 | ```javascript 98 | data.myWidget = $sp.getWidget('widget_id', {p1: param1, p2: param2}); 99 | ``` 100 |
101 | HTML Template 102 | 103 | ```html 104 | 105 | ``` 106 |
107 | For more information and examples refer to the [Embedded Widgets guide](widget_embedded.md). 108 | 109 | $sp.canReadRecord() 110 | ----- 111 | Useful for quickly determining if a record is valid and if the logged-in user has access to it. 112 | 113 | > If the record type is kb_knowledge, sc_cat_item, or sc_category it also checks if the user can view that item. 114 | 115 | - $sp.canReadRecord( gr ): Boolean 116 | - **Parameters** 117 | - (*GlideRecord*) gr 118 | A glide record 119 | - **Returns** 120 | - (*Boolean*) True if the record is valid and readable 121 | - $sp.canReadRecord( table, sys_id ): Boolean 122 | - **Parameters** 123 | - (*String*) table 124 | A table name to query. 125 | - (*String*) sys_id 126 | The record sys_id to query. 127 | - **Returns** 128 | - (*Boolean*) True if the record is valid and readable 129 | 130 | Server Script 131 | 132 | ```javascript 133 | data.items = []; 134 | data.userName = gs.getUserDisplayName(); 135 | var gr = new GlideRecord("sc_cat_item"); 136 | gr.query(); 137 | while(gr.next() && data.items.length < 10) { 138 | if ($sp.canReadRecord(gr)) { 139 | data.items.push(gr.getDisplayValue("name")); 140 | } 141 | } 142 | ``` 143 |
144 | HTML Template 145 | 146 | ```html 147 |
148 |
Hi, {{c.data.userName}}!
149 |
150 | Here are some things you can order: 151 |
  • {{item}}
152 |
153 |
154 | ``` 155 |
156 | Result 157 | ![Screenshot](../assets/widget_server_script_apis/canReadRecord.png) 158 | 159 | > Notice how the list of items is different based on the logged in user 160 | 161 | $sp.getCatalogItem() 162 | ----- 163 | A quick way to get all of the data necessary to render and order a catalog item using \. If you just need to get a catalog item to show its picture or name, consider using GlideRecord to query the sp_cat_item table. 164 | 165 | The following example demonstrates how to use getCatalogItem and \ together. 166 | 167 | - $sp.getCatalogItem( sys_id ): Object 168 | - **Parameters** 169 | - (*String*) sys_id 170 | The sys_id of the catalog item(sc_cat_item) or order guide(sc_cat_item_guide). 171 | - **Returns** 172 | - (*Object*) An object containing the catalog item variable model, view, sections, pricing and client scripts. 173 | 174 | Server Script 175 | 176 | ```javascript 177 | (function() { 178 | var sys_id = $sp.getParameter("sys_id") 179 | data.catItem = $sp.getCatalogItem(sys_id); 180 | })(); 181 | ``` 182 |
183 | Client Script 184 | 185 | ```javascript 186 | function($http, spUtil) { 187 | var c = this; 188 | var submitting = false; 189 | c.getIt = function() { 190 | if (submitting) return; 191 | $http.post(spUtil.getURL('sc_cat_item'), c.data.catItem).success(function(response) { 192 | if (response.answer) { 193 | c.req = response.answer; 194 | c.req.page = c.req.table == 'sc_request' ? 'sc_request' : 'ticket'; 195 | } 196 | }); 197 | } 198 | } 199 | ``` 200 | 201 |
202 | SCSS 203 | 204 | ```css 205 | 206 | .img-bg { 207 | padding: 5px; 208 | background-color: $brand-primary; 209 | } 210 | 211 | .img-responsive { 212 | margin: 0 auto; 213 | } 214 | 215 | .cat-icon { 216 | display: block; 217 | margin: -40px auto 0; 218 | } 219 | ``` 220 |
221 | 222 | HTML Template 223 | 224 | ```html 225 |
226 |
227 |
228 | 229 |
230 | 234 |
235 |

{{::data.catItem.name}}

236 |
    237 |
  • ${Price}: {{::data.catItem.price}}
  • 238 |
239 | 240 |

241 | ${Request created!} {{c.req.number}} 242 |

243 | 244 |
245 |
246 |
247 | ``` 248 | 249 |
250 | 251 | Result 252 | 253 | ![Screenshot](../assets/widget_server_script_apis/getCatalogItem.png) 254 | 255 | 256 | $sp.getDisplayValue() 257 | ----- 258 | Returns the display value of a given field (if it exists and has a value) from either the widget's sp_instance or the sp_portal record. Refer to the following diagram: 259 | 260 | ![Page map with widget instance](/assets/widget_server_script_apis/getDisplayValue_pagemap.png) 261 | 262 | This map visualizes a service portal page with one widget on it. Calling $sp.getDisplayValue("title") would return the display value of the title field on the widget's sp_instance record. If the title field didn't exist or was empty, then it would try the same operation on the the sp_portal record for the current portal context. 263 | 264 | > Note - Embedded widgets do not have sp_instance records. 265 | 266 |
267 | 268 | - $sp.getDisplayValue( fieldName ): String 269 | - **Parameters** 270 | - (*String*) fieldName 271 | The field name to get the display value of. 272 | - **Returns** 273 | - (*String*) A display value from either the sp_instance record or sp_portal record. 274 | 275 |
276 | Server Script 277 | 278 | ```javascript 279 | (function() { 280 | data.title = $sp.getDisplayValue("title"); 281 | data.catalog = $sp.getDisplayValue("sc_catalog"); 282 | })(); 283 | ``` 284 | 285 |
286 | HTML Template 287 | 288 | ```html 289 |
290 |

sp_instance.title: {{::data.title}}

291 |

sp_portal.sc_catalog: {{::data.catalog}}

292 |
293 | ``` 294 | 295 |
296 | Result 297 | 298 | ![Screenshot](../assets/widget_server_script_apis/getDisplayValue.png) 299 | 300 | $sp.getRecordElements() 301 | ----- 302 | Copies display values for the specified field names from a GlideRecord into the data parameter. 303 | 304 | 305 | - $sp.getRecordElements( Object, GlideRecord, String ): void 306 | - **Parameters** 307 | - (*Object*) data 308 | Must pass data object instantiated by the server. 309 | - (*GlideRecord*) GlideRecord 310 | Any GlideRecord of data 311 | - (*String*) String 312 | Comma-delimited string of fieldnames 313 | 314 | - **Returns** 315 | - (*Void*) 316 | Field objects will be added to data 317 |
318 | Server Script 319 | 320 | ```javascript 321 | (function($sp) { 322 | var gr = new GlideRecord("tablename"); 323 | var fieldnames = "sys_id,field_name"; 324 | $sp.getRecordElements(data, gr, fieldnames); 325 | })($sp); 326 | ``` 327 | 328 | $sp.getValue() 329 | ----- 330 | Returns the value of a given field (if it exists and has a value) from either the widget's sp_instance or the sp_portal record. See [getDisplayValue](#getDisplayValue) for more info. 331 | 332 | 333 | - $sp.getValue( fieldName ): Object 334 | - **Parameters** 335 | - (*String*) fieldName 336 | The field name to get the value of. 337 | - **Returns** 338 | - (*Object*) A value from either the sp_instance record or sp_portal record. 339 | 340 |
341 | Server Script 342 | 343 | ```javascript 344 | (function() { 345 | data.title = $sp.getValue("title"); 346 | data.catalog = $sp.getValue("sc_catalog"); 347 | })(); 348 | ``` 349 | 350 |
351 | HTML Template 352 | 353 | ```html 354 |
355 |

sp_instance.title: {{::data.title}}

356 |

sp_portal.sc_catalog: {{::data.catalog}}

357 |
358 | ``` 359 | 360 |
361 | Result 362 | 363 | ![Screenshot](../assets/widget_server_script_apis/getValue.png) 364 | -------------------------------------------------------------------------------- /release-notes/helsinki.md: -------------------------------------------------------------------------------- 1 | # Helsinki change log 2 | 3 | 4 | ## Helsinki Patch 6 Changes 5 | 6 | * The Variable type checkbox value needs to be string "true"||"false" so glideform apis and ui policy conditions can work 7 | * External content item should open in a new tab from SC category page 8 | * g_form.setValue to empty is broken for reference fields in Service Portal 9 | * evaluate order guide rule base condition from database, not client 10 | * Formatter type variables like container_start would cause order guide eval fail 11 | 12 |


13 | 14 | ## Helsinki Patch 5 Changes 15 | * Added a limit to typeahead search (defaults to 15) 16 | * Several fixes for permissions and element access on search results page 17 | * URL routing fix. When the path or portal changes, redirect to that new page 18 | * KB article attachments moved to bottom for consistency w/ platform UI 19 | * Clicking on links from the sc-category widget can now be intercepted and changed by a parent widget. Added the event name to the widget options schema. 20 | * KB category article count might show -1, it shouldn't; $sp.getKBCount now only counts published articles 21 | * Check_can_view widget option for SC Categories widget wasn't evaluated correctly after being set from true to false 22 | * sp_admin role should be able to CRUD sp_ng_template records 23 | * List widget did not honor glide.security.ui.filter system property or Dictionary attribute for table to force use of FilteredGlideRecord in lists 24 | * Added spModal api for a nicer alert, confirm, prompt: 25 | * spModel.alert(title) 26 | * spModel.confirm(title) 27 | * spModel.prompt(title, defaultValue) 28 | * **Form Widget** 29 | * In the activity stream, added a color bar to distinguish journal fields. Uses the accompanying system property (e.g., glide.ui.activity_stream.style.work_notes) 30 | * Support for journal stream for non-tasks 31 | * Pick the first choice in a choice list if none are selected 32 | * Don't expose short_description in ticket_conversation widget if user can't read that field 33 | * Don't show attachment icon or Edit link if user can't do attachments 34 | * Dont show 'record not found' once the form loads a record that DOES exist 35 | * Choice list now sets the value & displayValue 36 | * long, unbroken title is not wrapped in ticket conversation widget header 37 | * At mobile device width, the activity stream was unusable 38 | * Fixing some edge cases while using g_form.setValue() and the glide_list element. Like setting multiple display values at the same time. 39 | * Making the variable editor show display values for reference fields and list collector fields 40 | * Prevent duplicate --None-- in choice list 41 | * **Catalog support** 42 | * Order Guide description isn't being shown 43 | * Fixing reference qualifiers for list collector variable types 44 | * Quantity picker wasn't wide enough 45 | * For SP catalog item requests, Attachments are now attached to the sc_req_item instead of the sc_request 46 | * Order Guide didn't show images for guide or included items 47 | * Adding support for catalog item variable and variable set layouts: 2down, 2across. 48 | 49 | 50 |


51 | 52 | ## Helsinki Patch 4 Changes 53 | 54 | * Every out-of-box widget translated 55 | * Service Portal Designer translated 56 | * spPanel directive failed if title attribute had a single quote 57 | * Fixing JS error on toolip close 58 | * Fix to make sure a utc date is passed into the directive. Otherwise a dd/mm/yy date format will throw it off 59 | * Keyboard shortcuts do not work on Service portal designer 60 | * In the widget editor, if you open a widget that has dependencies a JavaScript error might appear in the console 61 | * SQANDA - Subscribed Questions. Header color can't be set from instance options 62 | * Fixing bug with glyphicon element in platform ui because value changes weren't saved 63 | * De-duplicate page load dependencies 64 | * Added "Include on page load" to dependency 65 | * If checked, shows optional glide_list of portals; if none selected, dependency loads for all 66 | * applies to angular dependencies too 67 | * Couldn't remove Glyph in widget instance options 68 | * spGlyphPicker directive wrongly removed first three characters even if value didn't start with "fa-" 69 | * Adding sc_cat_item_content items to search results and doing all of the special handling 70 | * Oracle needs larger sp_widget script fields or OOB scripts get truncated 71 | * Uploading a logo in the branding editor doesn't change the logo in the portal 72 | * **Catalog support** 73 | * Prevent duplicate labels showing up in a choice list 74 | * variables max_length inconsistent with normal Catalog UI. single line text should allow more than 40 characters, and field-mapped vars should honor target field max_length 75 | * variables use maxlength="-1" but that's not supported by IE 76 | * Changing the sp_ref_list_data processor so that it uses the VariableModel to get Variable Choice List items, and adding pricing support to the reference variable type 77 | * Variable read_roles not being honored 78 | * ref_ac_columns attribute for reference variables ignored fields not in the "mobile" list view 79 | * Record Producers are not mapping variables to fields unless "Map to field" is selected, should also map if variable name matches a target field 80 | * Added option to sc_cat_item widget to allow redirecting after ordering a catalog item 81 | * auto_redirect (bool) 82 | * url (string) 83 | * Adding the variable editor formatter/widget 84 | * The Service Catalog category list widget now has the ability to show a hierarchical view of categories. Great for usability, great for performance 85 | * Configuring the SC Category widget to default to Nested if layout is not specified 86 | * Render description as HTML in sc_cat_item widget 87 | * **Form Widget** 88 | * Related list links should inherit view param 89 | * Now you can add an attachment to a new record 90 | * Reference icon on service portal was enabled regardless of readOnly status of the reference field - should honor system property and dictionary attribute 91 | * ref_ac_columns doesn't work for reference fields in Form widget 92 | * Adding ui formatters to form model 93 | * Adding variable editor as an oob sp_ui_formatter 94 | * Making g_form available to formatter widgets as $scope.page.g_form 95 | * Choice list will now clear the old value if it isn't in the list of choices. 96 | * Allow scoped apps to use/clone the form widget. Fix to get the client scripts and ui policy in a scoped app. 97 | * Adding placeholder attribute to text fields. 98 | * **Service Portal Designer** 99 | * Now rendering page specific CSS 100 | 101 | 102 | 103 | 104 |


105 | 106 | ## Helsinki Patch 3 Changes 107 | 108 | * Dozens of translations added 109 | * Don't base64 encode record values when saving a form 110 | * Removed spnavto processor 111 | * Honor glide.sc.price.display when set to "never" (search results) 112 | * My Requests widget should show same query as Requests in header 113 | * Services Status page shows wrong/missing dates with custom date format 114 | * link-button widget didn't let you set color in Widget Options 115 | * Setting glide.spform.log_sql to false by default 116 | * CSS class names were not being set on nested rows 117 | * Typeahead search wrongly shows no_search=true and visible_standalone=false catalog items 118 | * /sp portal homepage has no search input in mobile (xs) view 119 | * data table widget might fail to show column label 120 | * New portal should have out of the box Bootstrap colors and settings 121 | * g_user_date_time_format and other globals were not available 122 | * **Catalog support** 123 | * Bringing variable type "label" into the form field model so you can show/hide it using g_form.setDisplay() or ui policy actions 124 | * Don't show price/submit/attachments footer for Content Item catalog item, it's HTML only 125 | * Conversation stream didn't show image attachments added before insert (e.g., from the Create a New Incident catalog item) 126 | * If a catalog item has no short description it wouldn't show up on an order guide 127 | * Catalog variable Help Text isn't shown when specified 128 | * Catalog variable tooltip isn't shown 129 | * Fix for cascading variables. Reference field display values were using the wrong model property 130 | * Cleaning up the mandatory field processing in order guides 131 | * Update Price/Recurring when checkbox variable is unchecked 132 | * Firing submitted events from "SC Order Guide" and "SC Cat Item" 133 | * $sp.sc_order_guide.submitted 134 | * $sp.sc_cat_item.submitted 135 | * **Service Portal Designer** 136 | * Fix: When you drag and drop a widget to another location it will copy the widget instead of moving it 137 | * Fix: Widget code is running twice 138 | --------------------------------------------------------------------------------