Add to Visual Task Board – Any record (List choice) (multi-card)

In previous articles, I explored the possibility of adding any record to a Visual Task Board from a form and from a list.

Where do we go from here?

What about selecting multiple records from a list and adding a card for each one of them?

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] → Target record [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) (multi-card)

Type: List choice

Action name: add_to_vtb_list_choice_non_task_multi

Onclick:

openAddToBoardDialogListMultiCard()
Code language: JavaScript (javascript)

Condition:

gs.hasRole('admin')
Code language: JavaScript (javascript)

Script:

function openAddToBoardDialogListMultiCard() { var tableName = g_list.getTableName(); var listId = g_list.listID; var list = GlideList2.get(listId); var checked = list.getChecked(); if (!checked) return; var selectedIds = checked.split(','); var vtbIds = []; for (var i = 0; i < selectedIds.length; i++) { var currentID = selectedIds[i]; var grVTB = new GlideRecord('vtb_task'); var shortDescription = g_list.getCell(currentID, 'short_description') || g_list.getCell(currentID, 'name') || g_list.getCell(currentID, 'number'); shortDescription = shortDescription ? shortDescription.innerText : 'No short description defined'; grVTB.short_description = shortDescription; grVTB.description = shortDescription; 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]<a href="' + tableName + '.do?sys_id=' + currentID + '" target="_blank">' + shortDescription + '</a>[/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.

Why don’t we use all our new “Add to VTB (non-task)” UI Actions to test this feature?