Emit and Response to Events (SP Widgets)

Exercise: Emit and Respond to Events

In this exercise, you will emit an event from the Notes List widget to the Notes Body widget when a user selects a record. The Notes Body widget will respond to the event by displaying record information.

Edit the Notes List HTML Template to Respond to a Click

  1. In the HTML Template, locate this line:

    Locate the line which iterates through the records
  2. Edit the line by adding an ng-click for when a user clicks a Note record in the list:

    Add ng-click to the line.
  3. Click the Save button.

Edit the Notes List Client Script to Emit an Event

  1. If the Client Script pane is not open in the Widget Editor, enable it by clicking Client Script in the Widget Editor header.

    Enable the Client Script Pane
  2. Replace the Client Script with this script:

    function($rootScope,$scope) {
    	/* widget controller */
    	var c = this;
    	c.selectItem = function(idx) {
    		var id = c.data.notes[idx].sys_id;
    		console.log('Note ID: ' + id);
    		$rootScope.noteID = id;
    		$rootScope.$emit('selectNote', id);
    	}
    }
  3. If needed, apply indentation using <Shift> + <tab>.

  4. Examine the script to see what it does.
  5. Click the Save button.

Test the Notes List Widget

  1. You will soon be working with two widgets so instead of testing with the Preview pane, open a new browser tab or window and navigate to:

    https://<your_instance>.service-now.com/notes?id=notes_home
  2. Using the appropriate strategy for your browser, open the JavaScript console.

  3. Click a record in the Notes List widget.
  4. Examine the console for a log message. The message is written when the event is emitted.
    The Client Script logs the selected record’s sys_id.
  5. Leave the testing tab/window open and return to the Widget Editor.

Edit the Notes Body Widget Client Script

  1. In the Widget Editor, use the Widget list to switch to editing the Notes Body Widget.

    Switch to the Notes Body widget using the choice list
  2. Replace the Client Script with this script:

    function($scope,$rootScope) {
    		/* widget controller */
    		var c = this;
    
    		$rootScope.$on('selectNote', function(event,data) { 
    			console.log('Listener caught NoteID: ' + $rootScope.noteID); 
    		});
    	}
  3. Examine the Client Script to make sure you understand what it does. Notice, in particular, that the script responds when the selectNote event is emitted.
  4. Click the Save button.

Test Receiving the Event

  1. Switch back to the testing tab/window you have open and reload the page.
  2. If you closed the JavaScript console, open it now.
  3. Click a note in the Notes List. You should see log messages for when the event is emitted and when it is received.
    The console has log messages for when the event is emitted and when it is received.
  4. Leave the testing tab/window open and return to the Widget Editor.

Edit the Notes Body Client Script Again

Instead of logging a sys_id to the JavaScript console when an event is received, the Client Script should get the selected record’s field values from the server to display in the Notes Body Widget.

  1. Replace the Client Script with this script:

    function($scope,$rootScope) {
    		/* widget controller */
    		var c = this;
    
    		$rootScope.$on('selectNote', function(event,data) {
    			c.server.get({
    				action: 'getNote',
    				noteID: $rootScope.noteID
    			}).then(function(r) {
    				c.data.title = r.data.note.title;
    				c.data.note = r.data.note.note;
    				c.data.noteID = r.data.note.sys_id;
    			});
    		});
    	}
  2. Examine the script to make sure you understand what it does.

    • this.server.get() calls the Server script and passes custom input
    • this.server.get() returns a promise. When the response is received from the server, the .then() function logic executes.
  3. Click the Save button.

Edit the Notes Body Widget Server Script

In the Notes Body widget Server Script, write the logic to respond to the getNote action called from the Client Script.

  1. In the Script Editor pane, replace the existing Server Script with this script:

    (function() {
    		/* populate the 'data' object */
    
    		if (input && input.noteID) {
    			var note = new GlideRecord('x_snc_createnotes_note');
    			if (note.get(input.noteID)) {
    				if (input.action == 'getNote') {
    					data.note = {};
    					$sp.getRecordValues(data.note, note, "title, note, sys_id");
    				}
    			}
    		}
    	})();
  2. Examine the script to make sure you understand what it does:

    • Recall that the input object is the data object received from the Client Script’s controller.
    • What does the GlideSPScriptable getRecordValues() method do?
  3. Click the Save button.

Edit the Notes Body Widget HTML Template

  1. In the HTML Template pane, replace the existing HTML with this HTML:

    <div class="panel panel-default" ng-show="c.data.noteID">
    	  <div class="panel-heading clearfix">
    	    <div class="row">
    	      <div class="col-md-12">
    	        <input class="form-control" id="note-title" ng-model="c.data.title" />
    	      </div>
    	    </div>
    	  </div>
    	  <div class="panel-body">
    	    <textarea class="form-control" id="note-body" ng-model="c.data.note" ></textarea>
    	  </div>
    	</div>
  2. Examine the HTML to make sure you understand what it does.

  3. Click the Save button.

Test the Notes Body Widget Logic

  1. Switch back to the testing tab/window you have open and reload the page.

    QUESTION: The Notes Body Widget has an HTML Template but is not rendered on the portal page until you select a record in the Notes List. Why not? If you aren’t sure, scroll to the Answers section at the bottom of this page.

  2. Click a note in the Notes List. You should see the record’s Title and Description in the Notes Body widget.

    The Notes List and Notes Body widgets work together.