Warning: Cannot modify header information - headers already sent by (output started at /home/snowguy9/public_html/wp-content/themes/snowguy/functions.php:460) in /home/snowguy9/public_html/wp-content/plugins/sg-cachepress/core/Supercacher/Supercacher_Helper.php on line 77
SnowGuy http://snowguy.co.uk Dan Gibbard Tue, 13 Aug 2019 06:37:51 +0000 en-US hourly 1 https://wordpress.org/?v=5.4 161538719 Automated Test Framework (ATF): custom Step Configuration http://snowguy.co.uk/2019/08/13/automated-test-framework-atf-custom-step-configuration/?utm_source=rss&utm_medium=rss&utm_campaign=automated-test-framework-atf-custom-step-configuration Tue, 13 Aug 2019 06:37:51 +0000 http://snowguy.co.uk/?p=2026 Automated Test Framework: custom Step Configuration Step Configurations allow you to create custom test steps above and beyond what is included with ServiceNow. Step Configurations are server-side meaning you have the full power of server-side scripting at your disposal. We’ll create a Step Configuration that checks if the ‘Incident opened on my behalf’ Notification has... View Article

The post Automated Test Framework (ATF): custom Step Configuration appeared first on SnowGuy.

]]>
Automated Test Framework: custom Step Configuration

Step Configurations allow you to create custom test steps above and beyond what is included with ServiceNow. Step Configurations are server-side meaning you have the full power of server-side scripting at your disposal.

We’ll create a Step Configuration that checks if the ‘Incident opened on my behalf’ Notification has been correctly sent after a self-service user has opened an incident. Our test case might be something like this:

When a new Incident is created, the ‘Incident opened on my behalf’ Notification should be sent to the user who opened the Incident

Create a new Test

ATF Tests should be small and specific to your stories/test cases so we’ll create a new Test for the test case we defined above. To save us some time and work, we can copy an existing demo/example test to use as a template.

  1. Go to Automated Test Framework > Tests
  2. Open INCIDENT MGMT: Incident creation – Self service
    Note: these demo data tests are read only examples only but we can use them as a template for our own tests
  3. Click the Copy Test UI Action
  4. Complete the form
    • Name: Incident Creation – Self service: notification
    • Description: Check for notification on creation of incident
  5. Save

Our custom Step Configuration will need to know the sys_id of the record that gets inserted when the the Record Producer is submitted. This sys_id will be available in an Output Variable on the Submit Record Producer Test Step – take a look at it now:

  1. Scroll down to the Test Steps related list and open Test Step: Submit Record Producer
  2. Click the info icon next to the Step Config field to open the baseline Submit record producer Step Configuration
  3. Scroll down to the Output Variables related list
  4. Note the Type of the record_id Output variable

Create a new Step Configuration

We now need to create a new Step Configuration that will check for our notification

  1. Go to Automated Test Framework > Step Configurations > New
  2. Complete the form
    • Name: INCIDENT: Check opened notification
    • Category: Server
    • Order: 1000
    • Template reminder: INCIDENT: Check opened notification
    • HTML Description: INCIDENT: Check opened notification
  3. Save

Before we write the script that will actually check for the notification we need to define an input variable so our script will have access to the sys_id of the record that was created earlier in the test

  1. Scroll down to Input Variable related list > New
  2. Click on the Advanced view UI action
  3. Complete the form
    • Type: Document ID (this should match the Type of the Output Variable we checked earlier)
    • Label: Document ID
    • Column name (autofills): u_record_id
    • Attributes: element_mapping_provider=com.glide.automated_testing_framework.ATFVariableElementMapper
  4. Submit

The Attribute we added allows us to map the value of an Output Variable into our Input Variable.

Now we can write the script that will actually check for the notification. Take a moment to review the comment in the Step execution script field, it contains some example of how to use the default attributes that are passed to the script. Add the following script and Save:

(function executeStep(inputs, outputs, stepResult, timeout) {
  //get the value passed into the Record ID input variable
  var inc = inputs.u_record_id;

  //sys_id of the Notification we are checking for 
  var created_notification = '8f9389b5c0a8016401715c208ff9bf48';

  //wait ~30 seconds to ensure that the email has enough time to be generated
  var seconds = parseInt(30) * 1000;
  var start = parseInt(new Date().getTime()) + seconds;
  while(start>parseInt(new Date().getTime())){
    // do nothing
  }

  //get all emails associated with the record that was inserted
  var incEmails = new GlideRecord('sys_email');
  incEmails.addQuery('instance', inc);
  incEmails.query();
  while(incEmails.next()){

    //if an email log record exists that matches the email on the ticket and the 
    //specified notification, the email was sent correctly 
    var emailId = incEmails.getUniqueValue();
    var grEmailLog = new GlideRecord('sys_email_log');
    grEmailLog.addQuery('email', emailId);
    grEmailLog.addQuery('notification', created_notification);
    grEmailLog.query();
    if(grEmailLog.next()){
      //output message that will appear in test results
      stepResult.setOutputMessage('TEST STEP: email was sent');
      //the result of this Test Step will be successfull, any subsequent steps
      //in the Test will be processed
      stepResult.setSuccess();
      return;
    }

  }

  stepResult.setOutputMessage('TEST STEP: email was NOT sent');
  //the result of this Test Step will be failure, the Test will halt and fail
  stepResult.setFailed();


}(inputs, outputs, stepResult, timeout));

Create a new Test Step

  1. Go to Automated Test Framework > Tests > open the Test created earlier
  2. Scroll down to Test Steps related list
  3. Select all Test Steps from Execution order 5 and onwards – delete or inactivate these Test Steps
  4. Click Add Test Step
  5. Select the Server category > INCIDENT: Check opened notification
  6. Insert after: 4 – Submit Record Producer
  7. Click Next

This creates a new Test Step in our Test based on our custom Step Configuration.

Important: We must pass the sys_id of the created record from the Output Variable of Step 4 into the Record ID Input Variable of Step 5

  1. Click the Element Mapping icon  next to the Record ID field at the bottom of the form
  2. Select Step 4 Submit Record Producer
  3. Select Record ID
  4. Submit

Test your Test

  1. Go to Automated Test Framework > Tests > open your Test record
  2. Click the Run Test UI action in your Test record. This will open a new Client Test Runner in a new browser tab that will run your Test. Observe the Record producer opening and submitting.
  3. Go back to tab with your Test Record open and you will see the progress of your test execution
  4. The final bar (independent steps with order 5-5) should show green and the Test will complete successfully!

We must also check that the test will correctly fail if the notification is NOT sent

  1. Go to System Notification > Notifications > Open Notification: Incident opened for me
  2. Set active: false and Save
  3. Repeat the steps above to run the Test again – this time the final bar should show red and the test should fail as the Notification was not sent
  4. Click on Go to results to see why the test failed, you should see the ’email NOT sent’ message we specified in the script of our Test Configuration

Congratulations, you have created, used and tested a custom Step Configuration!

Training and Certification

If you’re not already familiar with the Automated Test Framework then it’s time to get up to speed! Implementing ATF as part of your development process is crucial to making sure platform upgrades go quickly and smoothly.

 

 

 

The post Automated Test Framework (ATF): custom Step Configuration appeared first on SnowGuy.

]]>
2026
New York New York – The release so good they named it twice http://snowguy.co.uk/2019/08/13/new-york-new-york-the-release-so-good-they-named-it-twice/?utm_source=rss&utm_medium=rss&utm_campaign=new-york-new-york-the-release-so-good-they-named-it-twice Tue, 13 Aug 2019 06:31:23 +0000 http://snowguy.co.uk/?p=2024 What features in New York are you most excited about?

The post New York New York – The release so good they named it twice appeared first on SnowGuy.

]]>
What features in New York are you most excited about?

The post New York New York – The release so good they named it twice appeared first on SnowGuy.

]]>
2024
Service Portal: Paste attachments in Service Catalog http://snowguy.co.uk/2019/06/29/service-portal-paste-attachments-in-service-catalog/?utm_source=rss&utm_medium=rss&utm_campaign=service-portal-paste-attachments-in-service-catalog http://snowguy.co.uk/2019/06/29/service-portal-paste-attachments-in-service-catalog/#respond Sat, 29 Jun 2019 20:11:26 +0000 http://snowguy.co.uk/?p=133 When a user needs to add a screenshot to a record (in this example we will use Incident) the process when using baseline widgets would be: Take screenshot Save file Upload saved file as an attachment on the Catalog Item/Record Producer It would be a much better User Experience to be able to take the... View Article

The post Service Portal: Paste attachments in Service Catalog appeared first on SnowGuy.

]]>
When a user needs to add a screenshot to a record (in this example we will use Incident) the process when using baseline widgets would be:

  1. Take screenshot
  2. Save file
  3. Upload saved file as an attachment on the Catalog Item/Record Producer

It would be a much better User Experience to be able to take the screenshot, copy it to the clipboard and then paste it directly to the record – you may recognize this functionality if you have ever used the ServiceNow HI portal. This functionality does not exist in the baseline platform but it is fairly easy to add!

This solution requires us to modify the baseline SC Catalog Item Widget to add a textarea input to the layout and event listener to react to a paste event – this will allow us to paste an image into any Catalog Item or Record Producer without having to create separate Variables on each item.

Modify the baseline SC Catalog Item Widget

  • In the Widget Editor, open SC Catalog Item [widget-sc-cat-item-v2]
  • Clone the Widget

Update the Link Function with the following. The HTML should be added before the <sp-attachment-button></sp-attachment-button> element around Line 97

//timeout waits for DOM to be fully rendered
setTimeout(function(){
  //find the element that we are pasting into
  elem.find('#imagepaste').on('paste', function(e){
    var files = [];
    var items = (event.clipboardData || event.originalEvent.clipboardData).items;
    angular.forEach(items, function(item,key){
      if(item.type.match(/image/)){
        files.push(item.getAsFile());
        scope.attachmentHandler.onFileSelect(files);
      }
    })
  })
},0)

 

<textarea id="imagepaste">
</textarea>

 

Add the new Widget to the sc_cat_item Page

  • In the Page Designer, open the sc_cat_item page
  • Remove the existing SC Catalog Item Widget from the page and replace it with the Widget created above

Testing

  • Go to the Service Portal > Service Catalog > Can We Help You? > Create Incident
  • Paste an image into the textarea that has been added next to the attachment button
  • Observe the image is added to the Record Producer

 

You can see the full solution in this Update Set: SnowGuy – Image paste

The post Service Portal: Paste attachments in Service Catalog appeared first on SnowGuy.

]]>
http://snowguy.co.uk/2019/06/29/service-portal-paste-attachments-in-service-catalog/feed/ 0 133
Y2.02K approaches… Thousands of Knowledge Articles are about to fall into the abyss! http://snowguy.co.uk/2019/06/29/knowledge-valid-to/?utm_source=rss&utm_medium=rss&utm_campaign=knowledge-valid-to http://snowguy.co.uk/2019/06/29/knowledge-valid-to/#respond Sat, 29 Jun 2019 09:30:14 +0000 http://snowguy.co.uk/?p=141 When you create a new Knowledge Article the Valid To field defaults to 01-01-2020. What does this mean? If you or your customers have created Knowledge Articles and left the Valid To field with its default value, those articles will no longer be accessible in six months time. Before we address this impending doom we... View Article

The post Y2.02K approaches… Thousands of Knowledge Articles are about to fall into the abyss! appeared first on SnowGuy.

]]>
When you create a new Knowledge Article the Valid To field defaults to 01-01-2020. What does this mean? If you or your customers have created Knowledge Articles and left the Valid To field with its default value, those articles will no longer be accessible in six months time.

Before we address this impending doom we need to ask: why are you leaving the Valid To date at its default value? Knowledge should be periodically reviewed to ensure it is still accurate and relevant, ideally we should be setting the Valid To field to a date relative to the publishing date, for example 6 months or 1 year from being published

Setting a relative Valid To date

An example of setting the Valid To field to 1 year after the creation of the article using a calculated value on the Valid To field

  1. Go to Knowledge > Articles> All
  2. Open any Knowledge Article
  3. Right click on the Valid To field, click on Configure Dictionary
  4. Complete the form
    • Dynamic Default: false
    • Calculated: true
    • Calculated value:
      (function calculatedFieldValue(current) {
      
        var validTo = new GlideDate();
        validTo.setValue(gs.yearsAgo(-1));
        return validTo.getValue();  
      
      })(current);

       

Fixing existing default values

We need to review the articles that are set to expire on 01-01-2020 and change the Valid To date of any articles that should continue to be available after that date

Report on existing articles with the default Valid To date

Review the articles that have been created with the default Valid To date.

Fixing existing articles with the default Valid To date

Run a background script to change the Valid To date of any articles that were created with the default value to another date in the future (in this example we set it to 01-01-2020)

var gd =new GlideDate();
gd.setValue('2021-01-01'); //set the new valid_to date value

var gr = new GlideRecord('kb_knowledge');
gr.addEncodedQuery("workflow_state=published^valid_toON2020-01-01@javascript:gs.dateGenerate('2020-01-01','start')@javascript:gs.dateGenerate('2020-01-01','end')");
gr.query();
while(gr.next()){
  gr.valid_to=gd.getValue();
  gr.update();
}

 

Conclusion

In six months time any articles that were created and left with the default value in Valid To will become unavailable. You and your customers need to review your Knowledge Bases to ensure that any articles that should still be available after 01-01-2020 have their Valid To values updated. Let’s make sure that 2020 gets off to a flying start!

 

The post Y2.02K approaches… Thousands of Knowledge Articles are about to fall into the abyss! appeared first on SnowGuy.

]]>
http://snowguy.co.uk/2019/06/29/knowledge-valid-to/feed/ 0 141
Service Portal: Widgets as Catalog Variables | Part 1 http://snowguy.co.uk/2019/05/24/service-portal-widgets-as-catalog-variables-part-1/?utm_source=rss&utm_medium=rss&utm_campaign=service-portal-widgets-as-catalog-variables-part-1 http://snowguy.co.uk/2019/05/24/service-portal-widgets-as-catalog-variables-part-1/#respond Fri, 24 May 2019 22:52:51 +0000 http://snowguy.co.uk/?p=115 When displaying Catalog Items through the Service Portal it is possible to include custom Service Portal Widgets as Variables on the item, these can then be used to control other Variables on the item, allowing us limitless flexibility on the design and functionality of our Catalog Items. Let’s take a simple Catalog Item with a... View Article

The post Service Portal: Widgets as Catalog Variables | Part 1 appeared first on SnowGuy.

]]>
When displaying Catalog Items through the Service Portal it is possible to include custom Service Portal Widgets as Variables on the item, these can then be used to control other Variables on the item, allowing us limitless flexibility on the design and functionality of our Catalog Items. Let’s take a simple Catalog Item with a Select Box variable and a Yes/No variable and replace them with custom Widgets

Create the Catalog Item

  1. Go to Service Catalog > Maintain Items
  2. Click New
  3. Complete the form:
    • Name: Add to DL
    • Catalog: Service Catalog
    • Category: How can we help
    • Short Description: Add to DL
  4. Save

Create the Catalog Variables

We’ll create two variables that will actually store the data we set through our Widgets, these will be hidden and not visible to the user

  1. Add a variable
    • Type: Select Box
    • Question: Type
    • Name: type
    • Question Choices:
      1. User
      2. Group
  2. Add a variable
    • Type: Yes/No
    • Question: Notify subject
    • Name: notify_subject
    • Default value: No

Create a Widget for the ‘type’ Variable

  1. Open the Widget Editor and create a new Widget:
    • Name: [Variable] Add to DL: Type
  2. Add the following HTML/CSS/Client Script
<div class="btn-group">
  <label class="btn btn-primary" 
         ng-model="c.type" 
         uib-btn-radio="'user'">
    <span class="fa fa-user"></span>
  </label>
  <label class="btn btn-primary" 
         ng-model="c.type" 
         uib-btn-radio="'group'" 
         uncheckable>
    <span class="fa fa-users"></span>
  </label>
</div>
.fa { 
  font-size: 64px;
  min-width: 128px;
}
function($scope) {
  /* widget controller */
  var c = this;
  var g_form = $scope.page.g_form;
  
  $scope.$watch('c.type', function(newVal,oldVal){
    if(typeof newVal == 'undefined')
      return;

    g_form.setValue('type', newVal)
  })
}


In the Widget we are simply setting some data based on which button the user clicks. The key element is in the Client Script where we take that value and set the value of the relevant variables on the Catalog Item 

Add the Widget to the Catalog Item

  1. Open the Add to DL item
  2. Add a new variable
    • Type: Macro
    • Label: Type widget
    • Name: type_widget
    • Order: 100
    • Widget: [Variable] Add to DL: Type
  3. Save

Verify that the Widget and Catalog Item are working correctly by viewing the Add to DL Catalog Item through the Service Portal. Clicking on the User or Group icon should set the value of the ‘Type’ variable, if it does not, debug your Widget and re-test.

For our second variable we want a toggle switch – The UI Bootstrap library that Service Portal uses does not include this functionality, so we will add it via a Dependency. The files required can be found at http://ziscloud.github.io/angular-bootstrap-toggle/. Note that this is the UI Bootstrap implementation of the toggle functionality, not the standard Bootstrap implementation.

Create a Widget for the ‘notify_subject’ Variable

  1. In the Widget Editor create a new Widget:
    • Name: [Variable] Add to DL: Notify subject
  2. Click Open in Platform from the options menu in the top right
  3. In the Dependencies related list click New
  4. Complete the form
    • Name: Bootstrap Toggle
  5. In the JS Includes related list click New
  6. Complete the form:
    1. Display Name: angular-bootstrap-toggle.min.js
    2. Source: URL
    3. JS file url: https://cdn.jsdelivr.net/npm/angular-bootstrap-toggle@0.4.0/dist/angular-bootstrap-toggle.min.js
  7. Repeat this process to add the CSS Include
  8. Close the widget record in the platform UI and open it in the Widget Editor 

    Best Practice: Remember, it is best practice to only edit a Widget in either the platform view or the Widget Editor at any one time – if you have the Widget open in both interfaces you can easily end up overwriting changes made in one interface from the other.

     

  9. Add the following HTML/Client script to the Widget
<toggle ng-model="c.notify_subject" 
        ng-change="c.changed()"
        on="Yes"
        off="No"></toggle>
function($scope) {
  /* widget controller */
  var c = this;
  var g_form = $scope.page.g_form;
  c.notify_subject=false; //Ensure this default value matches the default value of the variable

  c.changed=function(){
    if(c.notify_subject)
      g_form.setValue('notify_subject', 'Yes');
    else
      g_form.setValue('notify_subject', 'No');

  }
}

Add the widget as a variable

  1. Open the Add to DL item
  2. Add a new variable
    • Type: Macro with label
    • Label: Notify subject
    • Name: notify_subject_widget
    • Order: 200
    • Widget: [Variable] Add to DL: Notify subject
  3. Save

Verify that the widget is working by viewing the Add to DL Catalog Item through the Service Portal. Clicking on Notify subject toggle should set the value of the ‘Notify subject’ variable, if it does not, debug your widget and re-test.

Finally, we should complete our Catalog Item by hiding the actual variables so that only our Widget variables are displayed. Use a Catalog UI Policy to achieve this.

Conclusion

We have created two Service Portal Widgets that will replace two OOB Catalog Variables on a Catalog Item when the item is displayed through the Service Portal. At the moment the two Widgets are hard-coded to modify the values of two specific variable, it would be useful to extend the Widgets we’ve created to make them re-usable, for example we could add the Toggle Widget to any Catalog Item and have it target the value of any Yes/No variable – we will take a look at this in Part 2!

The post Service Portal: Widgets as Catalog Variables | Part 1 appeared first on SnowGuy.

]]>
http://snowguy.co.uk/2019/05/24/service-portal-widgets-as-catalog-variables-part-1/feed/ 0 210
Service Portal: Server update methods http://snowguy.co.uk/2019/05/13/service-portal-server-update-methods/?utm_source=rss&utm_medium=rss&utm_campaign=service-portal-server-update-methods http://snowguy.co.uk/2019/05/13/service-portal-server-update-methods/#respond Mon, 13 May 2019 04:49:18 +0000 http://snowguy.co.uk/?p=76 Within our Service Portal widgets there are two main ways we can send data from the client to the server, these are Method Description this.server.get([Object]) Calls the server and sends custom input. Returns Promise.   this.server.update() Calls the server and posts this.data to the server script. Returns Promise.   It’s important to understand the difference... View Article

The post Service Portal: Server update methods appeared first on SnowGuy.

]]>
Within our Service Portal widgets there are two main ways we can send data from the client to the server, these are

Method Description
this.server.get([Object]) Calls the server and sends custom input. Returns Promise.  
this.server.update() Calls the server and posts this.data to the server script. Returns Promise.  

It’s important to understand the difference between these two methods and when to use them. As an example we’re going to create a simple widget that will display unassigned incidents and allow a user to assign an incident to themselves or to one of their groups. The code for the initial widget is below or you can import the XML below into the Widget [sp_widget] table.

 

<ul class="list-group">
<li class="list-group-item list-group-header">
Incident
<span class="pull-right">
Assign to me/Assign to my group
</span>
</li>
<li class="list-group-item"
ng-repeat="inc in c.data.list">
{{inc.number.value}}
<br>
{{inc.short_description.value}}
<div class="btn-group pull-right" role="group" aria-label="...">
<button type="button" class="btn btn-default"
data-toggle="tooltip"
data-placement="left"
title="Assign to me"
ng-click="c.assignToMe(inc)">
<span class="fa fa-user"></span>
</button>
<button type="button" class="btn btn-default"
data-toggle="tooltip"
data-placement="left"
title="Assign to my group"
ng-click="c.assignToGroup(inc)">
<span class="fa fa-users"></span>
</button>
</div>
</li>
</ul>

 

 

function() {
  var c = this;
  
  c.assignToMe=function(inc){

  }
  c.assignToGroup=function(inc){
    
  }
}
(function() {
  /* populate the 'data' object */
  /* e.g., data.table = $sp.getValue('table'); */

  var list = [];
  var gr = new GlideRecord('incident');
  gr.addEncodedQuery('active=true^assigned_toISEMPTY');
  gr.query();
  while(gr.next()){
    var o = {};
    $sp.getRecordElements(o,gr,'sys_id,number,short_description')
    list.push(o)
  }
  
  data.list=list;
})();

We’ll focus on the ‘Assign to me’ functionality first. When a user clicks on the ‘Assign to me’ button we need to get the sys_id of the selected record and send it to the server script in order to assign that record to the user. View the Widget on a page and check the data object by hitting ctrl + right click on the Widget and then viewing the browser console. We can see that the data object contains the list of unassigned incidents that is displayed by the widget – so if we were to use this.server.update() we would be sending the list of incidents back to the server unnecessarily. So, in this case we’ll use this.server.get() so we are only sending data that is actually required by the server for this click action. 

Using this.server.get()

this.server.get() accepts a custom data object that will be sent to the server and returns a promise where we must process the response from the server.

  1. Update the Client script to send a sys_id of an Incident to the server using this.server.get() when ‘Assign to me’ is clicked and process the response from the server to move the status and message from the Promise callback to the main controller (update the existing assignToMe function with the below Step 1 code)
  2. Update the server script to respond to the action and return a status and message (add the below Step 2 code at the start of the Server script)
  3. Update the HTML to display the message and status to the user (add the below Step 3 code at the start of the HTML)
c.assignToMe=function(inc){
  //pass an incident sys_id and action id to the server
  c.server.get({
    action: 'assign_to_me',
    sys_id: inc.sys_id.value
  }).then(function(rsp){
    c.status=rsp.data.status;
    c.msg=rsp.data.msg;
  })
}
//respond to 'assign_to_me' action
if(input && input.action == 'assign_to_me'){

  var grInc = new GlideRecord('incident');
  grInc.get(input.sys_id);
  grInc.assigned_to=gs.getUserID();

  //return a status and message through the data object
  if(grInc.update()){
    data.status='success';
    data.msg=grInc.number + ' has been assigned to you!';			
  } else {
    data.status='warning';
    data.msg=grInc.number + ' could not be assigned to you!';			
  }
  return;
}
<div class="alert alert-{{c.status}}" 
     role="alert"
     ng-show="c.msg">
  {{c.msg}}
</div>

Conclusion

We have used this.server.get()to send a custom data object to the server rather than using this.server.update()which would send the entire data object from the client.

Best Practice

In any situation where we are sending data from client to server we should be sending as little data as possible in order to improve the performance of our app – as such we should be using this.server.get()wherever possible.

Challenge

  1. Use recordWatch functionality to remove an Incident from the list after it has been assigned
  2. Allow the user to assign an Incident to a group they are a member of

 

The post Service Portal: Server update methods appeared first on SnowGuy.

]]>
http://snowguy.co.uk/2019/05/13/service-portal-server-update-methods/feed/ 0 76
StarshipNow application http://snowguy.co.uk/2019/05/12/starshipnow-application/?utm_source=rss&utm_medium=rss&utm_campaign=starshipnow-application http://snowguy.co.uk/2019/05/12/starshipnow-application/#respond Sun, 12 May 2019 00:48:16 +0000 http://snowguy.co.uk/?p=72 What is StarshipNow StarshipNow is a scoped application that I use to demo ServiceNow functionality. In general, it allows you to manage the functionality of a fictional starship and its crew members among other things How do I install StarshipNow? You can install StarshipNow through GitHub or Update Sets. Install StarshipNow through GitHub Go to... View Article

The post StarshipNow application appeared first on SnowGuy.

]]>
What is StarshipNow

StarshipNow is a scoped application that I use to demo ServiceNow functionality. In general, it allows you to manage the functionality of a fictional starship and its crew members among other things

How do I install StarshipNow?

You can install StarshipNow through GitHub or Update Sets.

Install StarshipNow through GitHub

  1. Go to
    https://github.com/SNPresentNow/StarshipNow and fork the repository
  2. In your instance, go to System Applications > Studio
  3. Click Import from Source Control

Install StarshipNow with Update Sets

The post StarshipNow application appeared first on SnowGuy.

]]>
http://snowguy.co.uk/2019/05/12/starshipnow-application/feed/ 0 72
Service Portal: Syntax Editor Macros http://snowguy.co.uk/2019/04/27/service-portal-syntax-editor-macros/?utm_source=rss&utm_medium=rss&utm_campaign=service-portal-syntax-editor-macros http://snowguy.co.uk/2019/04/27/service-portal-syntax-editor-macros/#respond Sat, 27 Apr 2019 22:12:08 +0000 http://snowguy.co.uk/?p=37 Syntax Editor Macros… One of those things that you don’t realize you miss until they’re gone. And unfortunately in the Service Portal Widget Editor there is currently no support for them, so I created a small script to enable Syntax Editor Macros in the Service Portal Widget Editor. (function(){ //object to store macros in var... View Article

The post Service Portal: Syntax Editor Macros appeared first on SnowGuy.

]]>
Syntax Editor Macros… One of those things that you don’t realize you miss until they’re gone. And unfortunately in the Service Portal Widget Editor there is currently no support for them, so I created a small script to enable Syntax Editor Macros in the Service Portal Widget Editor.

(function(){

//object to store macros in

var macrosObj={

};

//add keyup event listener

jQuery(window).on('keyup', function(e) {

var keyCode = e.keyCode || e.which;

//check if key pressed is TAB

if (keyCode == 9) {

//get DOM element for active pane

var cmEl = jQuery(document.activeElement).parents('.CodeMirror')[0];

//get CodeMirror object for active pane. CodeMirror is the Syntax Editor library used in the Widget Editor

var cmObj = cmEl.CodeMirror;

//get position of cursor and end of line

var tmpCursor=cmObj.getCursor();

var eol=cmObj.getLine(tmpCursor.line).length;

//do nothing if cursor is not at end of line

//this allows users to continue using TAB key for formatting/indentation

if(tmpCursor.ch < eol){

return true;

}

//do nothing if any text is selected

if(cmObj.somethingSelected()){

return true;

}

//find the start and end position of the word preceeding the cursor

var wordObj = cmObj.findWordAt({

line: tmpCursor.line,

ch: tmpCursor.ch-2

});

//get the actual word preceeding the cursor

var word = cmObj.getRange(wordObj.anchor, wordObj.head);

//do nothing if a corresponding Syntax Editor Macro does not exist

if(typeof macrosObj[word]==='undefined')

return true;

//select the word preceeding the cursor

var sel = cmObj.setSelection(wordObj.anchor,wordObj.head);

//replace selection with the text of the Syntax Editor Macro

cmObj.replaceSelection( macrosObj[word].text );

}

});

//populate macrosObj with records from the Syntax Editor Macro table

var requestBody = "";

var client=new XMLHttpRequest();

client.open("get","/api/now/table/syntax_editor_macro?sysparm_fields=name%2Ctext");

client.setRequestHeader('Accept','application/json');

client.setRequestHeader('Content-Type','application/json');

client.setRequestHeader('X-UserToken',window.g_ck);

client.onreadystatechange = function() {

if(this.readyState == this.DONE) {

var rspObj=JSON.parse(this.response).result;

for(var macro in rspObj){

if(!rspObj.hasOwnProperty(macro))

continue;

var currentMacro=rspObj[macro];

macrosObj[currentMacro.name]=currentMacro;

}

}

};

client.send(requestBody);

})();

Create Widget Dependency

  1. Service Portal > Widgets
  2. Open: Widget Edit Panel
  3. Dependencies (related list) > New
    • Name: widgetMacros
  4. Save
  5. JS Includes (related list) > New
    • Display name: widgetMacros
    • Source: UI Script
    • UI Script: [UI Script created above]
  6. Submit

That’s it!

Service Portal Widget Editor now has full support for the Syntax Editor Macros used throughout the rest of the platform. This functionality is introduced in the ServiceNow Service Portal Advanced class – I’ll be teaching this class at Knowledge 19 this year!

The post Service Portal: Syntax Editor Macros appeared first on SnowGuy.

]]>
http://snowguy.co.uk/2019/04/27/service-portal-syntax-editor-macros/feed/ 0 37
WordPress Resources at SiteGround http://snowguy.co.uk/2018/08/15/wordpress-resources-at-siteground/?utm_source=rss&utm_medium=rss&utm_campaign=wordpress-resources-at-siteground http://snowguy.co.uk/2018/08/15/wordpress-resources-at-siteground/#comments Wed, 15 Aug 2018 11:50:35 +0000 http://snowguy.co.uk/2018/08/15/wordpress-resources-at-siteground/ WordPress is an award-winning web software, used by millions of webmasters worldwide for building their website or blog. SiteGround is proud to host this particular WordPress installation and provide users with multiple resources to facilitate the management of their WP websites: Expert WordPress Hosting SiteGround provides superior WordPress hosting focused on speed, security and customer... View Article

The post WordPress Resources at SiteGround appeared first on SnowGuy.

]]>
WordPress is an award-winning web software, used by millions of webmasters worldwide for building their website or blog. SiteGround is proud to host this particular WordPress installation and provide users with multiple resources to facilitate the management of their WP websites:

Expert WordPress Hosting

SiteGround provides superior WordPress hosting focused on speed, security and customer service. We take care of WordPress sites security with unique server-level customizations, WP auto-updates, and daily backups. We make them faster by regularly upgrading our hardware, offering free CDN with Railgun and developing our SuperCacher that speeds sites up to 100 times! And last but not least, we provide real WordPress help 24/7! Learn more about SiteGround WordPress hosting

WordPress tutorial and knowledgebase articles

WordPress is considered an easy to work with software. Yet, if you are a beginner you might need some help, or you might be looking for tweaks that do not come naturally even to more advanced users. SiteGround WordPress tutorial includes installation and theme change instructions, management of WordPress plugins, manual upgrade and backup creation, and more. If you are looking for a more rare setup or modification, you may visit SiteGround Knowledgebase.

Free WordPress themes

SiteGround experts not only develop various solutions for WordPress sites, but also create unique designs that you could download for free. SiteGround WordPress themes are easy to customize for the particular use of the webmaster.

The post WordPress Resources at SiteGround appeared first on SnowGuy.

]]>
http://snowguy.co.uk/2018/08/15/wordpress-resources-at-siteground/feed/ 1 1