This is the last in a series of articles where I explore the possibility of adding any record to a Visual Task Board from a form, from a list context menu, and a list choice.
This last one will also involve a list choice, but in this case, we will add a single card for multiple records.
The idea
We can use Personal tasks [vtb_task] as an interface between the VTB Card [vtb_card] and the actual record
Instead of:
VTB Card [vtb_card] → Target record [task]
We can have:
VTB Card [vtb_card] → Personal Task [vtb_task] → Multiple target records [any record in the system]
The code
How do we do that?
With a single UI Action and relying on the out of the box functionality.
Create a new Global UI action (easier if you just copy the OOTB one “Add to Visual Task Board”).
Name: Add to VTB (non-task) (single card)
Type: List choice
Action name: add_to_vtb_list_choice_non_task_single
Onclick:
openAddToBoardDialogListSingleCard()
Code language: JavaScript (javascript)
Condition:
gs.hasRole('admin')
Code language: JavaScript (javascript)
Script:
function openAddToBoardDialogListSingleCard() {
var tableName = g_list.getTableName();
var listId = g_list.listID;
var list = GlideList2.get(listId);
var checked = list.getChecked();
if (!checked)
return;
//Add a single card for the first selected item
//Include the rest in the description
var selectedIds = checked.split(',');
var vtbIds = [];
var firstSelected = selectedIds[0];
var grVTB = new GlideRecord('vtb_task');
var shortDescription = g_list.getCell(firstSelected, 'short_description') || g_list.getCell(firstSelected, 'name') || g_list.getCell(firstSelected, 'number');
shortDescription = shortDescription ? shortDescription.innerText : 'No short description defined';
grVTB.short_description = shortDescription;
var description = [];
var comment = [];
for (var i = 0; i < selectedIds.length; i++) {
var shortDescription = g_list.getCell(selectedIds[i], 'short_description') || g_list.getCell(selectedIds[i], 'name') || g_list.getCell(selectedIds[i], 'number');
shortDescription = shortDescription ? shortDescription.innerText : 'No short description defined';
description.push(shortDescription);
comment.push('<a href="' + tableName + '.do?sys_id=' + selectedIds[i] + '" target="_blank">' + shortDescription + '</a>');
}
grVTB.description = description.join('\\n');
var taskSysID = grVTB.insert();
vtbIds.push(taskSysID);
var grVTBComment = new GlideRecord('sys_journal_field');
grVTBComment.name = 'vtb_task';
grVTBComment.element = 'comments';
grVTBComment.element_id = taskSysID;
grVTBComment.value = '[code]' + comment.join('<br/>') + '[/code]';
grVTBComment.insert();
var url = new GlideURL("$vtb_add_to_board.do");
url.addParam("sysparm_nostack", "yes");
url.addParam("sysparm_record_list", vtbIds);
url.addParam("sysparm_table_name", "vtb_task");
//The code below is exactly the same that you can find in the OOTB "Add to Visual Task Board" UI Action
var o = new GlideOverlay({
title: getMessage("Select a Visual Task board"),
iframe: url.getURL(),
allowOverflowX: true,
height: 1000,
width: 2000,
messages: "",
onAfterLoad: function() {
document.getElementsByClassName('gb_close')[0].focus();
},
onBeforeLoad: function() {
this.glideBoxCallerElement = event.target;
},
onAfterClose: function() {
this.glideBoxCallerElement.focus();
}
});
o.setPreference("sysparm_table_name", tableName);
o.setOnBeforeClose(displayMessageStashListChoice);
o.render();
uncheckSelected(listId, checked);
}
function displayMessageStashListChoice() {
if (!this.getData("messages"))
return;
GlideUI.get().clearOutputMessages();
var m = this.getData("messages");
if (m.messages.info) {
for (var i = 0; i < m.messages.info.length; i++) {
var msg = m.messages.info[i];
if (msg)
addFormMessage(msg, "info", 0);
}
}
if (m.messages.error) {
for (var i = 0; i < m.messages.error.length; i++) {
var msg = m.messages.error[i];
if (msg)
addFormMessage(msg, "error", 0);
}
}
}
function addFormMessage(msg, type, id) {
GlideUI.get().addOutputMessage({
msg: msg,
type: type,
id: id
});
var scrollDiv = getFormContentParent();
scrollDiv.scrollTop = 0;
}
function uncheckSelected(listId, checked) {
var checkedIds = checked.split(',');
for (var i = 0; i < checkedIds.length; i++)
$('check_' + listId + '_' + checkedIds[i]).checked = false;
$("allcheck_" + listId).checked = false;
}
Code language: JavaScript (javascript)
Result
Now, we can add multiple records to a board simultaneously in a single card.
Why don’t we use all our new “Add to VTB (non-task)” UI Actions to test this feature?