Managing records in a UI page using AngularJS and GlideAjax without using REST

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎02-28-2017 07:30 AM
Hello Community,
Lately I have been doing some research on AngularJS and its capabilities in ServiceNow and I find to be very agile and powerful.
I came across alot of interesting topics and noticed alot of developers use REST Api with Angular to manage and manipulate data in a UI Page.
ServiceNow puts an interesting example on how to do it using GlideAjax and AngularJS implicit binding in a UI page:
I find that approach to be very interesting. Based on the example ServiceNow provided I wanted to share some of the scripting I have done on updating the data on the UI Page using GlideAjax without the need of REST API.
In this example I have added a value [u_value] we want to update in the item.
So Basically we are getting a page with a list of records and their input value.
We want the user to be able to update the value of the described item or Add a new one.
Using te angualr COntroller defined in our UI script we will be able to pass on the parameters by GLideAjax to the Server side to update the records on the Server,
I also recommend reading on Jeff's article on using GlideAjax with JSON, his technique uses JQuery:
GlideAjax and JSON | Jeff Benedict
Note: There is no scoping specified here:
UI Page: angular_todo
Direct: de-selected
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<script>
<script>
<script>
<div ng-app="todo">
<div class="col-md-6" ng-controller="TodoListCtrl" data-ng-init="getNewList()">
<h1>Todo List</h1>
<ul class="list-group">
<div class="list-group-item" ng-repeat="todoItem in todos">
{{todoItem.description}}:<br></br><input type="text" id="name" value="{{todoItem.value}}" ng-model="todoItem.value"/>
</div>
</ul>
<!--
<ul class="list-group">
<li class="list-group-item" ng-repeat="todoItem in todos" ng-bind="todoItem"></li>
</ul>
-->
<br></br>
<button ng-click="modify()" type="button" class="btn btn-primary">Save</button>
<div>
<label>Add new todo:
<input class="form-control" ng-model="newTodo"/>
</label>
<label>Add new Value:
<input class="form-control" ng-model="newValue"/>
</label>
<button ng-click="add(newTodo, newValue)" type="button" class="btn btn-primary">Add Todo</button>
</div>
</div>
</div>
</j:jelly>
You also need to specify the UI Scripts:
UI Script: Angular_1_3_framework
document.writeln('<script>https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>');
Your GlideAjax adapter for JSON parsing
UI Script: sn-glideAjax
angular.module('sn.glideAjax', []);
angular.module('sn.glideAjax').service('GlideAjax', function($rootScope) {
var glideAjax = window.GlideAjax;
glideAjax.prototype.getJSON = function(callback) {
this.getXMLAnswer(function(answer) {
var answerJSON = JSON.parse(answer);
callback(answerJSON);
$rootScope.$apply();
});
};
return glideAjax;
});
The main ui script for Angular Controller
UI Script: app_angular_todo
angular.module('todo', ['sn.glideAjax']);
angular.module('todo').controller('TodoListCtrl', function($scope, GlideAjax) {
$scope.todos = [];
$scope.getNewList = load();
//$scope.$apply(load());
$scope.add = function(newTodo, newValue) {
$scope.todos.push(newTodo);
var ga = new GlideAjax('ToDoListItems');
ga.addParam('sysparm_name', 'add');
ga.addParam('u_short_description', newTodo);
ga.addParam('u_value', newValue);
//ga.setScope(global);
ga.getJSON(function(response) {
// don't need to do anything here
});
};
$scope.modify = function() {
//alert("Here the TOdo Update 4" + JSON.stringify($scope.todos));
var ga = new GlideAjax('ToDoListItems');
ga.addParam('sysparm_name', 'modify');
ga.addParam('new_list', JSON.stringify($scope.todos));
ga.getJSON(function(response) {
ga.addParam('new_list', response);
});
};
function load() {
var ga = new GlideAjax('ToDoListItems');
ga.addParam('sysparm_name', 'getList');
//ga.setScope(global);
ga.getJSON(function(response) {
if (!response)
return;
$scope.todos = response;
});
}
});
FInally getting data back and forth from the server
Script Include: ToDoListItems
Client Callable: True
var ToDoListItems = Class.create();
ToDoListItems.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
getList: function() {
var todos = new GlideRecord('u_x_snc_marketing_ev_to_do_list_item');
todos.orderBy('u_short_description');
todos.query();
var list = [];
while (todos.next()) {
var listo = {};
listo.description = todos.u_short_description.toString();
listo.value = todos.u_value.toString();
listo.sysid = todos.sys_id.toString();
list.push(listo);
}
return new global.JSON().encodeArray(list);
},
modify: function() {
var newStuff = this.getParameter('new_list');
var recordObj = new JSON().decode(newStuff);
var todos = new GlideRecord('u_x_snc_marketing_ev_to_do_list_item');
todos.query();
while (todos.next()){
//since we are dealing with an object we need to get its String value to validate in our GLideRecord
for ( var x=0; x < recordObj.length; x++ ){
var osysID = JSON.stringify(recordObj[x].sysid);
if (todos.sys_id == JSON.parse(osysID)){
var cleanValue = JSON.stringify(recordObj[x].value);
todos.u_value = JSON.parse(cleanValue);
todos.update();
}
}
}
gs.addInfoMessage("Properties Updated");
},
add: function() {
var todos = new GlideRecord('u_x_snc_marketing_ev_to_do_list_item');
todos.newRecord();
todos.u_short_description = this.getParameter('u_short_description');
todos.u_value = this.getParameter('u_value');
todos.insert();
},
type: 'ToDoListItems'
});
Thank you,
Hope this is helpful,
- 3,649 Views
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-02-2017 06:22 AM
Great work, just a thought. If you going to do Angular and want a specific page. Use the Service Portal if possible. For example take a look how they did with the CAB Workbench... Then you can use the whole "widget" thingie and skip the GlideAjax etc. as well.
//Göran