“Everyone thinks of changing the world, but no one thinks of changing himself.”
— Leo Tolstoy
After all of that work on customizing the Data Table widget(s), I realized that my Data Table Content Selector widget didn’t support all of the new features. If I wanted to have buttons or icons or customized reference links, I needed to tweak the code a little bit to provide that capability. Primarily, I needed to expand the schema for my configuration object to include options for buttons and reference pages for every table configuration. That would make the typical state value for a given table look something like this:
open: {
filter: 'caller_idDYNAMIC90d1921e5f510100a9ad2572f2b477fe%5Eactive%3Dtrue',
fields: 'number,opened_by,opened_at,short_description',
btnarray: [],
refmap: {sys_user: 'user_profile'}
},
To maintain backwards compatibility, both of the new options, btnarray and refmap, would need to be optional. Since the content selector widget relies on the URL-based version of the Data Table widget, implementing the new features was simply a matter of including them, if present, in the new URL at every page refresh:
function refreshPage(table, perspective, state) {
var tableInfo = getTableInfo(table, perspective);
var s = {};
s.id = $location.search().id;
s.table = tableInfo.name;
s.filter = tableInfo[state].filter;
s.fields = tableInfo[state].fields;
s.buttons = '';
if (tableInfo[state].btnarray && Array.isArray(tableInfo[state].btnarray) && tableInfo[state].btnarray.length > 0) {
s.buttons = JSON.stringify(tableInfo[state].btnarray);
}
s.refpage = '';
if (tableInfo[state].refmap) {
s.refpage = JSON.stringify(tableInfo[state].refmap);
}
s.px = perspective;
s.sx = state;
var newURL = $location.search(s);
spAriaFocusManager.navigateToLink(newURL.url());
}
That was basically all there was to it. Now I just need to create a new configuration object that takes advantage of these new features. My original example configuration contained two perspectives, Requester and Fulfiller. To show off the new buttons feature, I decided to add a third perspective, Approver, and then include three separate icons, one to Approve, one to Approve with comments, and another to Reject. The button configuration that I created to support this turned out like this:
btnarray: [
{
name: 'approve',
label: 'Approve',
heading: '-',
icon: 'workflow-approved',
color: 'success',
hint: 'Click here to approve'
},{
name: 'approvecmt',
label: 'Approve w/Comments',
heading: '-',
icon: 'comment-hollow',
color: 'success',
hint: 'Click here to approve with comments'
},{
name: 'reject',
label: 'Reject',
heading: '-',
icon: 'workflow-rejected',
color: 'danger',
hint: 'Click here to reject'
}
]
After entering some additional modifications to the configuration to add the new perspective, the resulting page ended up looking like this:
That took care of the look and feel, but to make the buttons actually work, I needed to create another button handling widget to process the button clicks on the three icons that I had configured. For that, I just grabbed the example that I had created earlier and cloned it to create a new Approval Click Handler widget. Here is the client script:
function(spModal, $rootScope) {
var c = this;
$rootScope.$on('button.click', function(e, parms) {
if (!c.data.inProgress) {
c.data.inProgress = true;
c.data.sys_id = parms.record.sys_id;
c.data.action = parms.button.name;
c.data.comments = '';
if (c.data.action == 'reject' || c.data.action == 'approvecmt') {
getComments(c.data.action);
} else if (c.data.action == 'approve') {
processDecision();
}
c.data.inProgress = false;
}
});
function getComments(state) {
var msg = 'Approval comments:';
if (state == 'reject') {
msg = 'Please enter the reason for rejection:';
}
spModal.prompt(msg, '').then(function(comments) {
c.data.comments = comments;
processDecision();
});
}
function processDecision() {
c.server.update().then(function(response) {
window.location.reload(true);
});
}
}
… and here is the server side script:
(function() {
if (input) {
var current = new GlideRecord('sysapproval_approver');
current.get(input.sys_id);
if (current.state == 'requested') {
current.state = 'approved';
if (input.action == 'reject') {
current.state = 'rejected';
}
var comments = 'Approval response from ' + gs.getUserDisplayName() + ':';
comments += '\n\nDecision: ' + current.getDisplayValue('state');
if (input.comments) {
comments += '\nReason: ' + input.comments;
}
current.comments = comments;
current.update();
}
}
})();
When I first pulled this up and tested the various buttons, a single click appeared to launch multiple iterations of the code. After entering comments in the modal pup-up box, another comment entry box would pop-up as if I had clicked on the icon a second time. Looking at the resulting records, the entered comments would often appear multiple times. On one example, it was entered 10 times! I never did figure out why that was happening, but I added conditionals to both the client side and server side scripts in an effort to put a stop to that behavior. That seems to have stopped it, but that still doesn’t explain to me why that is happening.
Looks like I have a little more testing to do before I put together a final Update Set …