Blog

Service Portal: Watchlist Widget

Add a watchlist widget to your Ticket form in Service Portal.  Allow self service users to add email addresses to the watchlist.

This just allows watchlist users to get emails on the ticket.  To allow watchlist users view the ticket in the Service Portal, you'll have to adjust your ACLs and SP configuration.

Email Format Check

Auto Complete

Confirmation Message

Widget V1

This one doesn’t allow the user to view users in the system

Name: Ticket Watchlist
ID: ticket_watchlist

HTML

<div class="panel panel-{{::options.color}} b">
<div class="panel-heading">
<h4 class="panel-title"><fa ng-if="::options.glyph.length" name="{{::options.glyph}}" class="m-r-sm" />Add to Watchlist</h4>
</div>
<div class="panel-body">
<form ng-submit="server.update()">
${Enter an email address to follow}
<div class="textbox_space">
<input ng-model="data.watch_list" id="watch_list" class="form-control" type="email" maxlength="50" />
</div>
<input type="submit" id="submit" value="{{data.submitMsg}}" class="btn btn-primary" style="margin-top: 5px;margin-bottom: 5px;"/>
<div ng-if="data.response" class="alert alert-success">{{::data.response}}</div>
</form>
</div>
</div>

CSS

.textbox_space {
margin-top: 10px;
margin-bottom: 10px;
}

Client Script

function() {
/* widget controller */
var c = this;
}


Server Script

(function() {
data.submitMsg = gs.getMessage("Add");
data.sys_id = $sp.getParameter('sys_id');
if (input) {
data.sys_id = input.sys_id;
data.watch_list = "";
var grTask = GlideRecord("task");
grTask.query("sys_id", data.sys_id);
grTask.query();
data.response = gs.getMessage('Thank you, email was added.');
//console.log('grTask Query: ' + grTask.getEncodedQuery() + ' = ' + grTask.getRowCount());
if (grTask.next()) {
var wList = grTask.watch_list;
var wEmail = input.watch_list;
var grUser = new GlideRecord('sys_user');
grUser.addQuery('email', wEmail);
grUser.query();
if (grUser.next()) {
// It's a user
if(wList != "") {
wList = (wList + "," + grUser.sys_id);
} else {
wList = grUser.sys_id;
}
} else {
//It's not a user either...so just add the address to the list...except instance email address
wList = (wList + "," + wEmail);
}
grTask.watch_list = wList;
grTask.update();
}
}
})();

Widget V2

This version allows a user to view users and select them. Someone posted this version on the community.

Name: Ticket Watchlist
ID: ticket_watchlist

HTML

<div class="panel panel-primary" ng-if="data.canRead">       
  <div class="panel-heading">       
    <h4 class="panel-title pull-left">       
      ${Watch list}       
    </h4>       
    <div class="clearfix"></div>       
  </div>                   
  <div class="panel-body">
    <form ng-submit="save()">
      <div class="text-center text-italic text-muted">
        <div>
          <sn-record-picker field="watch_list" sn-disabled="!data.canWrite" table="'sys_user'" display-field="'email'" display-fields="'name'" search-fields="'email'" value-field="'sys_id'" default-query="'active=true^web_service_access_only=false^user_nameISNOTEMPTY^emailISNOTEMPTY'" page-size="10" multiple="true"></sn-record-picker>   </div>
        <div style="margin-top:15px; float: right;">
          <button type="submit" class="btn btn-success btn-sm">${Update}</button>
        </div>
      </div>
    </form>
  </div>
</div>

CSS

Client Script

function($scope, spUtil, $http) {   
	var c = this;   

	$scope.watch_list = {   
		displayValue: c.data.displayValue,   
		value: c.data.value,   
		name: 'watch_list'
	};   
	$scope.save = function(){   
		c.data.watchList = $scope.watch_list.value;   
		c.server.update().then(function(){   
		});   
	};   
	spUtil.recordWatch($scope, c.data.table, "sys_id=" + c.data.sys_id, function(name, data) {   
		if(name.name == 'record.updated' && data.operation == 'update'){   
			$scope.watch_list.value = data.record.watch_list.value;   
			$scope.watch_list.displayValue = data.record.watch_list.display_value;   
			$scope.$apply();   
		} 
	});   
	$scope.$on("field.change", function(evt, parms) {
		if (parms.field.name == 'watch_list'){
		}
	});
}   


Server Script

(function() {   
	var gr;   
	if(input){   
		gr = new GlideRecord(input.table);   
		if(gr.get(input.sys_id)){   
			if(gr.watch_list.canWrite()){   
				gr.watch_list = input.watchList;   
				gr.update();   
				gs.addInfoMessage('Updated');   
			}   
			else{   
				gs.addErrorMessage("Update failed, you don't have the required access");   
			}   
		}   
	}   
	else{   
		var table = $sp.getParameter('table');   
		var sys_id = $sp.getParameter('sys_id');   
		gr = new GlideRecord(table);   
		if(gr.get(sys_id)){   
			data.table = table;   
			data.sys_id = sys_id;   
			data.canRead = gr.watch_list.canRead();   
			data.canWrite = gr.watch_list.canWrite();   
			if(data.canRead){   
				var dV = gr.getDisplayValue('watch_list');   
				var sV = gr.getValue('watch_list');   
				//data.displayValue = dV == '' ? [] : dV;   
				//data.value = sV == null ? [] : sV;   
				data.displayValue = dV;
				data.value = sV;
			}   
		}   
	}   
})();

Fields: Bootstrap color, Glyph