Service Portal Archives - ServiceNow Guru https://servicenowguru.com/tag/service-portal/ ServiceNow Consulting Scripting Administration Development Mon, 30 Sep 2024 23:29:33 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.2 https://servicenowguru.com/wp-content/uploads/2024/05/cropped-SNGuru-Icon-32x32.png Service Portal Archives - ServiceNow Guru https://servicenowguru.com/tag/service-portal/ 32 32 Leveraging ServiceNow with Highcharts: Transforming Data into Insight https://servicenowguru.com/service-portal/leveraging-servicenow-with-highcharts-transforming-data-into-insight/ https://servicenowguru.com/service-portal/leveraging-servicenow-with-highcharts-transforming-data-into-insight/#comments Tue, 08 Oct 2024 10:00:44 +0000 https://servicenowguru.com/?p=15549 In today's data-driven world, organizations are constantly seeking innovative solutions to transform complex datasets into actionable insights. ServiceNow, a leading cloud-based platform for digital workflows, provides extensive data handling and management capabilities. However, to truly leverage the power of data visualized effectively, integrating a robust tool like Highcharts can elevate the presentation and interpretation of

The post Leveraging ServiceNow with Highcharts: Transforming Data into Insight appeared first on ServiceNow Guru.

]]>
In today’s data-driven world, organizations are constantly seeking innovative solutions to transform complex datasets into actionable insights. ServiceNow, a leading cloud-based platform for digital workflows, provides extensive data handling and management capabilities. However, to truly leverage the power of data visualized effectively, integrating a robust tool like Highcharts can elevate the presentation and interpretation of data. This article explores how combining ServiceNow with Highcharts can transform raw data into clear, insightful visual representations, aiding businesses in making better-informed decisions. We’ll delve into the benefits of this integration, practical use cases, and tips for seamless implementation, setting the stage for a more intuitive and strategic approach to enterprise data analysis.

Highcharts is a flexible, feature-rich JavaScript library that allows developers to create interactive charts for the web. By integrating Highcharts with ServiceNow, you can transform static data into engaging visualizations, providing your users with a more intuitive, interactive experience. In this article, I’ll walk you through the process of integrating Highcharts with ServiceNow, showcasing use cases, and tips to get the most out of this powerful combination.

Why Integrate Highcharts with ServiceNow?

ServiceNow provides basic reporting and visualization features, but for more advanced charting needs—such as interactive dashboards or detailed drill-down capabilities—Highcharts offers several advantages:

  • Customization: Highcharts offers a wide range of chart types (line, bar, pie, scatter, etc.), and the ability to customize almost every aspect of the chart.
  • Interactivity: With Highcharts, users can interact with charts by zooming, clicking data points, and receiving real-time feedback, making data exploration more engaging.
  • Real-time Data: You can easily configure charts to update in real-time, providing up-to-the-minute insights.
  • Extensibility: Highcharts offers numerous plugins and extensions, allowing you to extend functionality as needed.

By combining ServiceNow’s robust data management with Highcharts’ visualization capabilities, organizations can create more effective reports and dashboards that drive better decision-making.

 

 

Licensing:

For this article, which has educational purposes, I will download version 11.4.3 of the library and use it in my PDI. For commercial use, it is recommended that you purchase licenses directly through their website. Another option is to use the version available within the platform, which in my research (<instance-name>/scripts/glide-highcharts.js) is 9.3.2.

Using the paid version:

In my article “Importing Excel to Servinow” I showed how to import a library into SN. Just follow the same steps to import the Highcharts library.

Using the version available on the platform:

Just create a JS Include in the Portal Theme added to the library already available on the platform:

 

Basic usage example:

For this first example I will create a simple widget with hard-coded data just to show how to use the library. To make things easier I will use a basic example that can be found in the documentation. This example was made using the version of the library that already comes with the platform.

 

Widget Basic Highchart Example
Widget Component: Client Script
Script:

<div class="page-header">
  <h1>ServiceNow Guru - Basic Highchart Example</h1>
</div>

<div id="container" style="width:100%; height:400px;"></div>

 

Widget Basic Highchart Example
Widget Component: HTML Template
Script:

var chartConfirObj = {
  chart: {
    type: 'bar',
  },
  title: {
    text: 'Fruit Consumption',
  },
  xAxis: {
    categories: ['Apples', 'Bananas', 'Oranges'],
  },
  yAxis: {
    title: {
      text: 'Fruit eaten',
    },
  },
  series: [
    {
      name: 'Jane',
      data: [1, 0, 4],
    },
    {
      name: 'John',
      data: [5, 7, 3],
    },
  ],
};

var chart = Highcharts.chart('container', chartConfirObj);

 

In this example, we see that to build the chart we need to pass an object containing the chart settings we want. The library is huge and I could spend hours here talking about each item in this object and also about each customization possibility, but the library documentation is incredibly complete and can answer all questions:

 

Now let’s give our graph a bit more reality and bring real data to it.

 

Widget Highchart Pie Example
Widget Component: Server Script
Script:

//variables that will be used to customize the graph
data.font_family = options.font_family || 'SourceSansPro,Helvetica,Arial,sans-serif';
data.fill_color = options.fill_color || '#fff';

data.title = options.title || 'Chart Title';
data.title_color = options.title_color || '#fff';
data.title_size = options.title_size || '14px';
data.title_weight = options.title_weight || 'normal';

data.label_color = options.label_color || '#fff';
data.label_size = options.label_size || '12px';
data.label_weight = options.label_weight || 'normal';
data.label_connector_color = options.label_connector_color || '#fff';

data.slice_label_size = options.slice_label_size || '14px';
data.slice_label_outline = options.slice_label_outline || 'transparent';
data.slice_label_opacity = options.slice_label_opacity || 1;
data.slice_label_weight = options.bar_label_weight || 'bold';

data.table = options.table || 'change_request';
data.agg_field = options.agg_field || 'risk';

data.graphData = [];

//get total requests
var reqCount = new global.GlideQuery(data.table).count();

// get the total requests by risk
var agg = new GlideAggregate(data.table);
agg.addAggregate('COUNT', data.agg_field);
agg.orderBy(data.agg_field);
agg.query();
while (agg.next()) {

    var count = parseInt(agg.getAggregate('COUNT', data.agg_field));
    var percentTemp = 100 * count / reqCount;
    var percent = Math.round(percentTemp * 100) / 100;

    var objReq = {
        name: agg.getDisplayValue(data.agg_field),
        y: count,
        percent: percent.toFixed(2)
    };

    // if the risk is Very High the pie should be sliced and red
    if (agg.getValue(data.agg_field) == 1) {
        objReq.sliced = true;
        objReq.selected = true;
        objReq.color = 'red';
    }

    data.graphData.push(objReq);

}

 

Widget Highchart Pie Example
Widget Component: Client Script
Script:

var chartConfirObj = {
  chart: {
    type: "pie",
    backgroundColor: c.data.fill_color,
  },
  title: {
    text: c.data.title,
    style: {
      fontFamily: c.data.font_family,
      color: c.data.title_color,
      fontSize: c.data.title_size,
      fontWeight: c.data.title_weight,
    },
  },
  tooltip: {
    formatter: function () {
      return (
        "<b>" +
        this.point.name +
        " </b>: " +
        this.y +
        " </b> (" +
        this.point.percent +
        "%)"
      );
    },
  },
  plotOptions: {
    series: {
      allowPointSelect: true,
      cursor: "pointer",
      dataLabels: [
        {
          enabled: true,
          distance: 20,
          connectorColor: c.data.label_connector_color,
          formatter: function () {
            return this.point.name + " </br>" + this.point.percent + "%";
          },
          style: {
            fontFamily: c.data.font_family,
            color: c.data.label_color,
            fontSize: c.data.label_size,
            fontWeight: c.data.label_weight,
            textOutline: c.data.bar_label_outline,
          },
        },
        {
          enabled: true,
          distance: -30,
          format: "{y}",
          style: {
            textOutline: c.data.slice_label_outline,
            fontSize: c.data.slice_label_size,
            opacity: c.data.slice_label_opacity,
            fontWeight: c.data.slice_label_weight,
            textAling: "center",
          },
        },
      ],
    },
  },
  series: [
    {
      name: "Percentage",
      colorByPoint: true,
      data: c.data.graphData,
      dataLabels: {
        style: {
          color: c.data.bar_label_color,
          fontSize: c.data.bar_label_size,
          textOutline: c.data.bar_label_outline,
          fontWeight: c.data.bar_label_weight,
        },
      },
    },
  ],
};

var chart = Highcharts.chart("containerPie", chartConfirObj);

 

Widget Highchart Pie Example
Widget Component: HTML Template
Script:

<div id="containerPie"></div>

 

Widget Highchart Pie Example
Widget Component: Option Schema
JSON:

[
    {
        "name": "table",
        "section": "other",
        "default_value": "change_request",
        "label": "Table",
        "type": "string"
    },
    {
        "name": "agg_field",
        "section": "other",
        "default_value": "risk",
        "label": "Field used to aggregate",
        "type": "string"
    },
    {
        "name": "font_family",
        "section": "other",
        "default_value": "SourceSansPro,Helvetica,Arial,sans-serif",
        "label": "Font family",
        "type": "string"
    },
    {
        "name": "fill_color",
        "section": "other",
        "default_value": "#fff",
        "label": "Fill color",
        "type": "string"
    },
    {
        "name": "title",
        "section": "other",
        "default_value": "Chart title",
        "label": "Title",
        "type": "string"
    },
    {
        "name": "title_color",
        "section": "other",
        "default_value": "#fff",
        "label": "Title color",
        "type": "string"
    },
    {
        "name": "title_size",
        "section": "other",
        "default_value": "14px",
        "label": "Title Size",
        "type": "string"
    },
    {
        "name": "title_weight",
        "section": "other",
        "default_value": "normal",
        "label": "Title weight",
        "type": "string"
    },
    {
        "name": "label_color",
        "section": "other",
        "default_value": "#fff",
        "label": "Label Color",
        "type": "string"
    },
    {
        "name": "label_size",
        "section": "other",
        "default_value": "11px",
        "label": "Label size",
        "type": "string"
    },
    {
        "name": "label_weight",
        "section": "other",
        "default_value": "normal",
        "label": "Label weight",
        "type": "string"
    },
    {
        "name": "label_connector_color",
        "section": "other",
        "default_value": "#fff",
        "label": "Label connector color",
        "type": "string"
    }
]

 

Now, with everything we have shown in this article, we have the possibility of building complex dashboards like the one we saw at the beginning of this article.

 

Conclusion

Integrating Highcharts with ServiceNow allows you to take your data visualization to the next level, enabling more interactive, detailed, and dynamic reporting. With its wide range of customization options and ability to handle real-time data, Highcharts is an ideal tool for organizations looking to enhance their ServiceNow dashboards and reports. Whether you’re visualizing incident trends, service performance, or asset utilization, this integration can provide critical insights to drive better decision-making.

By following the steps in this article, you’ll be well on your way to creating powerful, interactive charts in ServiceNow, enabling users to explore and understand complex data sets with ease.

The post Leveraging ServiceNow with Highcharts: Transforming Data into Insight appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/service-portal/leveraging-servicenow-with-highcharts-transforming-data-into-insight/feed/ 3
Service Portal and DatePicker Field https://servicenowguru.com/service-portal/service-portal-datepicker-field/ Wed, 03 Jul 2024 18:23:43 +0000 https://servicenowguru.com/?p=15498 In the previous article, when creating the form with the fields that will be used when importing the Excel file, I chose to use a library that provides many different configuration options: Bootstrap Datepicker In the same way we did with the SheetJS library, the first thing we need to do is download the necessary

The post Service Portal and DatePicker Field appeared first on ServiceNow Guru.

]]>
In the previous article, when creating the form with the fields that will be used when importing the Excel file, I chose to use a library that provides many different configuration options: Bootstrap Datepicker

In the same way we did with the SheetJS library, the first thing we need to do is download the necessary files. On GitHub you will find the link to download the “.js” and “.css” in cdnjs and some online demos.

The library’s documentation is very complete and contains several styling options and methods to use.

After downloading the files, create a dependency on the widget that will use the library:

 

 

After creating the dependency, the library will be ready to be used. We just need to start it and configure it according to our needs (in my case I just wanted the MM/YYYY information)

HTML

<!-- Field Period -->
<label class="control-label" for="monthYear">Month/Year</label>
<input id="monthYear" name="monthYear" class="form-control" placeholder="MM/YYYY" ng-model="c.model.monthYear.displayValue" readonly>

Link Function

$(document).ready(function(){

    setTimeout(function(){
            
        $('#monthYear').datepicker({
            format: "mm/yyyy",
            startDate: "-22m",				
            endDate: "-1m",
            startView: 1,
            minViewMode: 1,
            maxViewMode: 2,
            autoclose: true,
            toggleActive: true,
            language: "pt-BR"
        });

    },300);

});
The above script must be used in the “Link Function” as it is not a good practice to use jQuery in the Client Script.

After initialization and configuration as desired, it will be ready for use:

The post Service Portal and DatePicker Field appeared first on ServiceNow Guru.

]]>
Load Excel files to ServiceNow using Portal https://servicenowguru.com/service-portal/load-excel-files-to-servicenow-using-portal/ https://servicenowguru.com/service-portal/load-excel-files-to-servicenow-using-portal/#comments Tue, 28 May 2024 16:28:39 +0000 https://servicenowguru.com/?p=15379 As platform administrators we know that there are many ways to import an Excel file to ServiceNow. But what if you need to provide your client a way to load data without accessing one of these tools? When we talk about importing data to ServiceNow, the SheetJS library can be extremely useful in helping us

The post Load Excel files to ServiceNow using Portal appeared first on ServiceNow Guru.

]]>
As platform administrators we know that there are many ways to import an Excel file to ServiceNow. But what if you need to provide your client a way to load data without accessing one of these tools?

When we talk about importing data to ServiceNow, the SheetJS library can be extremely useful in helping us with this process (manipulating spreadsheets in the browser). Developers can create custom integrations to transfer data between ServiceNow and other applications. For example, a developer might build a custom integration that allows data to be imported from an external Excel spreadsheet into ServiceNow.

SheetJS: https://git.sheetjs.com/sheetjs/sheetjs

Business Use Case

In this article, we will use as an example an outsourced company that needs to import the hours worked by its employees to the platform so that these hours can be processed and paid. All records must be associated with a department. All necessary validations will be described in a future article. At this point we will only talk about importing the data.

The person in charge of the company will have to access the portal and upload an Excel file with the employees hours following the following model:

 

exemple table

 

 

The Solution

The first thing we need is to import the standalone version of SheetJS into ServiceNow. Open the link to the xlsx.full.min.js file and copy all the code. After that, we will create a UI Script to import this file into the platform:

 

UI Script

 

The next step is to associate this script with the portal. To do this, open the theme used, go to the ‘JS Includes’ related list and click on ‘New’. In the ‘UI Script’ field, select the script created in the previous step and click ‘Submit.’

 

JS Include

 

Now, let’s start developing the widget that will import the data. We will start by creating the form where the file will be uploaded. Using Bootstrap’s grid system and some CSS changes (which we won’t cover in this article) we have the following result:

Widget
Widget Component: HTML Template
Script:

<form ng-submit="c.submitFile()" name="form" id="my-form">
  <fieldset class="form-row">
    <div class="form-group col-md-3">
      <!-- Field Period -->
      <label class="control-label" for="monthYear">Month/Year</label>
    </div>
    <div class="form-group col-md-3">
      <!-- Field Department -->
      <label for="department">Department</label>
    </div>
    <div class="form-group col-md-3">
      <!-- Input file -->
      <label for="department">Attach File</label>
    </div>
    <div class="form-group col-md-3">
      <!-- Buttom submit -->
      <button
        type="submit"
        id="submit"
        class="btn submit-btn btn-block btn-primary"
      >
        Submit
      </button>
    </div>
  </fieldset>
</form>

This is the code preview:

 

 

Now let’s insert the fields. The final HTML should look like this:

Widget
Widget Component: HTML Template
Script:

<form ng-submit="c.submitFile()" name="form" id="my-form">

  <fieldset class="form-row">

    <div class="form-group col-md-3">
      
      <!-- Field Period -->
      <label class="control-label" for="monthYear">Month/Year</label>
      <input id="monthYear" name="monthYear" placeholder="MM/YYYY" ng-model="c.model.monthYear.displayValue"
             class="form-control" readonly>

    </div>
    
    <div class="form-group col-md-3">
      
      <!-- Field Department -->
      <label for="department">Department</label>
      <sn-record-picker name="department"
                        field="c.model.department"
                        table="c.recordPicker.table"
                        default-query="c.recordPicker.query"
                        display-field="c.recordPicker.display.field"
                        display-fields="c.recordPicker.display.fields"
                        value-field="c.recordPicker.value"
                        search-fields="c.recordPicker.search"
                        page-size="c.recordPicker.size"
                        >
      </sn-record-picker>
      
    </div>
    
    <div class="form-group col-md-3">
      
      <!-- Input file -->
      <label for="attachment" class="btn btn-block btn-primary" ng-hide="c.haveAttachment">
        <span class="glyphicon glyphicon-paperclip"></span> Attach File
      </label>
      
      <div ng-show="c.haveAttachment" class="file-attached">
        {{c.fileName}} <a id="clear" href="" ng-click="c.removeAttachment()">
        <span class="glyphicon glyphicon-remove"></span></a>
      </div>
      
      <input type="file" name="attachment" id="attachment" accept=".xls,.xlsx" 
             onchange="angular.element(this).scope().readAttachment(angular.element(this)[0].files[0])"  
             >
    </div>
    
    <div class="form-group col-md-3">
      
      <!-- Buttom submit -->
      <button type="submit" id="submit" class="btn submit-btn btn-block btn-primary">Submit</button>
      
    </div>
    
  </fieldset>
  
</form>

Regarding HTML, I will leave two points for the next articles:

  • The field Department will be created using the snRecordPicker directive:

 

Now we have the form with all its components:

Now that we have our HTML built, let’s move on to the Client Script and create the functions that will be used. This will be the most important part of the article because it is here that we will read the file. Once the file has been selected using the button on the form, we need a script to read, process, and insert the data into the table (for this article we will not perform any type of validation on the data).

Widget
Widget Component: Client Script
Script:

api.controller=function($scope, spUtil) {
    
  var c = this;

    c.model = {};
    
    c.hoursToSubmit = [];
    
    /* 
        read the file
        the function get the attached file as a blob
        https://developer.mozilla.org/en-US/docs/Web/API/Blob
    */
    $scope.readAttachment = function(blob) {

        //check if the file is XLS or XLSX
        var isXLSX = blob.name.endsWith('.xlsx') || blob.name.endsWith('.xls');

        // If not an Excel file the function fails
        if (!isXLSX) {
            spUtil.addErrorMessage("The file must be .xlxs or .xls");
            //c.removeAttachment();
            return;
        }

        c.fileName = blob.name;

        /* star the reader */
        var myReader = new FileReader();

        /* function that will be executed when the reader is called	*/
        myReader.onload = function(e) {

            var data = e.target.result;

            /* get the workbook */
            var workbook = XLSX.read(data, {
                type: "binary"
            });
            var o = {};

            /* get the first sheet name */
            var name = workbook.SheetNames[0];

            /* obtain the JSON object of the sheet and stringify */
            var work_hours = XLSX.utils.sheet_to_json(workbook.Sheets[name], {header: "A"});

            /* remove the first line (columns titles) using Lodash*/
            work_hours = _.drop(work_hours, 1);

            if (work_hours.length == 0) {

                spUtil.addErrorMessage("Nothing to import!");
                //c.removeAttachment();
                return;

            } else {

                /* For this article we will not do any type of validation */
                c.hoursToSubmit = work_hours;
                return;

            }

        }

        /* stars the reader */
        myReader.readAsBinaryString(blob);
    }
    
    c.submitFile = function() {
                
        $scope.server.get({
            action: "insert-hours",
            monthYear: c.model.monthYear,
            department: c.model.department,
            hoursToSubmit: c.hoursToSubmit
        }).then(function(resp) {
            
            spUtil.addInfoMessage("Sucess! Good job!! :)");
            c.hoursToSubmit = [];
            c.model = {};
            //c.removeAttachment();
            
        });
        
    }

};
Widget
Widget Component: Server Script
Script:

(function() {
    
    if(input && input.action == 'insert-hours') {
        
        var grWH = new GlideRecord('x_529701_snguru_worked_hours');
        
        for (var i = 0; i < input.hoursToSubmit.length ; i++) {
            
            grWH.initialize();			
            grWH.setValue('id', input.hoursToSubmit[i]['A'].toString());
            grWH.setValue('name', input.hoursToSubmit[i]['B']);
            grWH.setValue('u_departament', input.department.value);			
            grWH.setValue('period', input.monthYear.displayValue);
            grWH.setValue('u_type', input.hoursToSubmit[i]['C']);
            grWH.setValue('hours', parseInt(input.hoursToSubmit[i]['D']));
            grWH.insert();
            
        }
        
    }

})();

Now our widget is ready to make the magic happen! Fill in the fields, select the file, and click ‘Submit’.

 

 

If everything goes well, the data will be written to the table:

 

 

Conclusion

By leveraging the SheetJS library and custom ServiceNow widgets, we have created a streamlined solution for importing employee work hours from Excel files directly into ServiceNow. This approach eliminates the need for users to access external tools, simplifying the process and enhancing user experience. Such integrations not only save time, but also reduce errors associated with manual data entry, ensuring that the data processing is efficient and accurate.

The post Load Excel files to ServiceNow using Portal appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/service-portal/load-excel-files-to-servicenow-using-portal/feed/ 4
Service Portal-style Homepage Widgets https://servicenowguru.com/system-ui/service-portalstyle-homepage-widgets/ https://servicenowguru.com/system-ui/service-portalstyle-homepage-widgets/#comments Thu, 27 Apr 2017 18:13:43 +0000 https://servicenowguru.wpengine.com/?p=12469 ServiceNow has done a good job in creating a nice-looking customer service portal in recent releases. Although there are still some frustrating API limitations, overall it’s a nice improvement and is a good choice if you’re looking to roll out a customer service portal in ServiceNow. Depending on your organization, you may not be ready

The post Service Portal-style Homepage Widgets appeared first on ServiceNow Guru.

]]>
ServiceNow has done a good job in creating a nice-looking customer service portal in recent releases. Although there are still some frustrating API limitations, overall it’s a nice improvement and is a good choice if you’re looking to roll out a customer service portal in ServiceNow. Depending on your organization, you may not be ready to roll this out…or just wish you could replicate some of that nice-looking interface in the standard back-end where you get a more fully-featured experience. In this post I’ll show you how you can accomplish this with a couple of homepage widgets with Service Portal styling!


The first example is the full set of blocks on the Service Portal homepage as shown in this screenshot.

This can be replicated by taking the following steps…

1) Create a new UI page with the following settings

‘welcome_to_servicenow’ UI Page
Name: welcome_to_servicenow
HTML

<!-- Contains the HTML and CSS necessary for all styling and layout. Feel free to modify if need be. --> <style type="text/css">
    .homepage-quicklinks {<br />        background-color: #ffffff;<br />	    font-family: "SourceSansPro", Helvetica, Arial, sans-serif;<br />        font-size: 14px;<br />    }<br />	.text-info {<br />        color: #31708f;<br />    }<br />	a.text-info:hover, a.text-info:focus {<br />        color: #245269;<br />    }<br />	.text-success {<br />        color: #5cb85c;<br />    }<br />	a.text-success:hover, a.text-success:focus {<br />        color: #449d44;<br />    }<br />	.text-warning {<br />        color: #f0ad4e;<br />    }<br />	a.text-warning:hover, a.text-warning:focus {<br />        color: #ec971f;<br />    }<br />	.text-danger {<br />        color: #d9534f;<br />    }<br />    a.text-danger:hover, a.text-danger:focus {<br />        color: #c9302c;<br />    }<br />	.text-muted {<br />        color: #979797;<br />    }<br />	a.circle_icon {<br />        display: block;<br />        padding: 20px 0px 20px 70px;<br />        position: relative;<br />    }<br />	a.circle_icon .fa {<br />        position: absolute;<br />        left: 0px;<br />        top: 10px;<br />    }<br />	a.circle_icon h3 {<br />        font-weight: 300 !important;<br />        padding: 0;<br />        margin: 0 0 10px 0;<br />    }<br />	a:hover {<br />        text-decoration: none;<br />    }<br />	a:visited {<br />        text-decoration: none;<br />    }<br /></style>
<h1 style="color: #717171; font-size: 3em; text-align: center;">Welcome to ServiceNow!</h1>
<div class="homepage-quicklinks" style="background-size: initial; background-position: center center;">
<div>
<div class="row">
<div class="col-sm-6 col-md-3">
<div>
<div><a class="circle_icon text-info" href="catalog_home.do?sysparm_view=catalog_default" target="" rel="noopener">
<span class="fa fa-stack fa-2x">
<i class="fa fa-circle fa-stack-2x"></i>
<i class="fa fa-shopping-basket fa-stack-1x fa-inverse"></i>
</span></a>
<h3>Order Something</h3>
<span class="text-muted">Browse the catalog for services and items you need</span>

</div>
</div>
 

</div>
<div class="col-sm-6 col-md-3">
<div>
<div><a class="circle_icon text-success" href="kb_home.do" target="" rel="noopener">
<span class="fa fa-stack fa-2x">
<i class="fa fa-circle fa-stack-2x"></i>
<i class="fa fa-book fa-stack-1x fa-inverse"></i>
</span></a>
<h3>Knowledge Base</h3>
<span class="text-muted">Browse and search for articles, rate or submit feedback</span>

</div>
</div>
 

</div>
<div class="col-sm-6 col-md-3">
<div>
<div><a class="circle_icon text-warning" href="com.glideapp.servicecatalog_cat_item_view.do?sysparm_id=3f1dd0320a0a0b99000a53f7604a2ef9" target="" rel="noopener">
<span class="fa fa-stack fa-2x">
<i class="fa fa-circle fa-stack-2x"></i>
<i class="fa fa-fire fa-stack-1x fa-inverse"></i>
</span></a>
<h3>Report an Issue</h3>
<span class="text-muted">Contact support to make a request, or report a problem</span>

</div>
</div>
 

</div>
<div class="col-sm-6 col-md-3">
<div>
<div><a class="circle_icon text-danger" href="#" target="" rel="noopener">
<span class="fa fa-stack fa-2x">
<i class="fa fa-circle fa-stack-2x"></i>
<i class="fa fa-comments-o fa-stack-1x fa-inverse"></i>
</span></a>
<h3>Live Chat</h3>
<span class="text-muted">Start a chat conversation with customer service agents</span>

</div>
</div>
 

</div>
</div>
</div>
</div>

2) Create (or edit if you’ve already go one) a widget record

The widget record is what will allow you to add the widget to a ServiceNow homepage. The following example could be used in your system. You can add multiple widgets to the script of any widget record. The key is to include your widget UI page by referencing it in the widget ‘Script’ field. You can access widget records by navigating to ‘System UI -> Widgets’.

‘welcome_to_servicenow’ Widget
Name: Custom Widgets
Renderer type: JavaScript
Script:

function sections() {
return {
'Welcome to ServiceNow!' : { 'name' : 'welcome_to_servicenow'},
'EXAMPLE LINE 2' : { 'name' : 'other_ui_page_name_here'},
};
}function render() {
var name = renderer.getPreferences().get("name");
var gf = new GlideForm(renderer.getGC(), name, 0);
gf.setDirect(true);
gf.setRenderProperties(renderer.getRenderProperties());
return gf.getRenderedPage();
}function getEditLink() {
if (!gs.hasRole('admin'))
return '';return "sys_ui_page.do?sysparm_query=name=" + renderer.getPreferences().get("name");
}

3) Add the widget to your homepage

Once you’ve created your widget you should be able to navigate to your homepage and select and add the widget in the same way you’ve added other widgets in the past.

Including a single-block widget

You may also want to do the same thing with only one block of the widget. For example, maybe you want a standalone chat widget for the Service Portal that you can use from a homepage. The process there is the same; just a different UI page.

‘service_portal_chat’ UI Page
Name: service_portal_chat
HTML

<!-- Contains the HTML and CSS necessary for all styling and layout. Feel free to modify if need be. --> <style type="text/css">
    .homepage-quicklinks {<br />        background-color: #ffffff;<br />	    font-family: "SourceSansPro", Helvetica, Arial, sans-serif;<br />        font-size: 14px;<br />    }<br />	.text-info {<br />        color: #31708f;<br />    }<br />	a.text-info:hover, a.text-info:focus {<br />        color: #245269;<br />    }<br />	.text-success {<br />        color: #5cb85c;<br />    }<br />	a.text-success:hover, a.text-success:focus {<br />        color: #449d44;<br />    }<br />	.text-warning {<br />        color: #f0ad4e;<br />    }<br />	a.text-warning:hover, a.text-warning:focus {<br />        color: #ec971f;<br />    }<br />	.text-danger {<br />        color: #d9534f;<br />    }<br />    a.text-danger:hover, a.text-danger:focus {<br />        color: #c9302c;<br />    }<br />	.text-muted {<br />        color: #979797;<br />    }<br />	a.circle_icon {<br />        display: block;<br />        padding: 20px 0px 20px 70px;<br />        position: relative;<br />    }<br />	a.circle_icon .fa {<br />        position: absolute;<br />        left: 0px;<br />        top: 10px;<br />    }<br />	a.circle_icon h3 {<br />        font-weight: 300 !important;<br />        padding: 0;<br />        margin: 0 0 10px 0;<br />    }<br />	a:hover {<br />        text-decoration: none;<br />    }<br />	a:visited {<br />        text-decoration: none;<br />    }<br /></style>
<div class="homepage-quicklinks" style="background-size: initial; background-position: center center;">
<div>
<div class="row">
<div class="col-lg-6">
<div>
<div><a class="circle_icon text-danger" href="#" target="" rel="noopener">
<span class="fa fa-stack fa-2x">
<i class="fa fa-circle fa-stack-2x"></i>
<i class="fa fa-comments-o fa-stack-1x fa-inverse"></i>
</span></a>
<h3>Live Chat</h3>
<span class="text-muted">Start a chat conversation with customer service agents</span>

</div>
</div>
 

</div>
</div>
</div>
</div>

The post Service Portal-style Homepage Widgets appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-ui/service-portalstyle-homepage-widgets/feed/ 3