When an Attachment is attached, How is the recently attached attachment displayed?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-07-2012 11:00 AM
Hey,
catalog_cart_attachment_list is the UI macro that is getting all the attached attachments into the Service Catalog form.
It is again broken down into attachment_list_body.xml and attachment_list UI macros respectively.
SNOW doesn't allow the access to these two UI macros, But if any one of you know how the Page is refreshing, i.e when I attach a new attachment, how is it getting displayed on the form( I mean the new attachment at the top of the form without a form re-load) is a mystery to me 😞
Please help me out on this!
Thanks!
- Labels:
-
Service Catalog

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-07-2012 12:53 PM
The page has an event listener that triggers upon attachment when using the paper-clip icon. It is also built-in, so we don't have access to that (unless you've done some snooping with your browser's developer tools...).

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-07-2014 12:57 PM
Has anybody found a way to refresh the attachment list programmatically? I have implemented a copy function in a Client Script using AJAX that copies attachments in the back-end and I would like to refresh the attachment list without having to re-load the page.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-07-2014 01:57 PM
I have not done this. But I can give you the code based on which you can start.
Logically, because everytime you attach an attachment, ServiceNow UI page will refresh the page, right? So the first place to start would be opening the UI page that uploads the attachment. The name of the UI page is "attachment". Once you open that, in the client script portion you will find a function called refreshAttachments() that will have code to create new nodes for creation of attachments nodes and their display, when ever an attachment is uploaded. Half work done right?
Now the last thing you will have to do is, find a way to call refreshAttachments () as there is no API exposed. So look at code that calls this function. You will find out that, attachment_uploaded UI page will call refreshAttachments, with parameters.
Use the same thing in your client script and your job is done. Drop me a message/comment if you are stuck at this.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-09-2014 12:25 PM
Hi Abhiram Diddigi,
I have been able to complete half of the process. Basically I looked into the UI Pages attachment and attachment_uploaded and extracted the functions needed.
So far, I'm am able to collect all the information required to refresh the attachment list, but it still trying to make the refresh function to work.
I created the following Script Include:
Name: CatalogItemAjax
Active: True
Client callable: True
Script:
var CatalogItemAjax = Class.create();
CatalogItemAjax.prototype = Object.extendsObject(AbstractAjaxProcessor, {
list: function() {
var tbl = this.getParameter('sysparm_table');
var id = this.getParameter('sysparm_table_sys_id');
var fileNameStr = "";
var ids = [];
var canDelete = [];
var createdBy = [];
var createdOn = [];
var contentType = [];
var encryption = [];
var sa = new GlideSysAttachment();
var gr = sa.getAttachments(tbl, id);
while (gr.next()) {
fileNameStr += gr.getValue("file_name") + "///";
ids.push(gr.getValue("sys_id"));
canDelete.push(gr.canDelete());
createdBy.push(gr.getValue("sys_created_by"));
createdOn.push(gr.Element("sys_created_on").getDisplayValue());
contentType.push(gr.getValue("content_type"));
if (gr.isValidField("encryption_context"))
encryption.push(gr.encryption_context.name);
else
encryption.push("");
}
var json = new JSON();
var results = {"fileNameStr": fileNameStr, "ids": ids, "canDelete": canDelete, "createdBy": createdBy, "createdOn": createdOn, "contentType": contentType, "encryption": encryption};
return json.encode(results);
},
type: 'CatalogItemAjax'
});
On a Record Producer, I created a Client Script that gets trigger when a user changes a reference field with the purpose of copying values to the record producer, including attachments:
Name: Copy Change Request
Applies to: A Catalog Item
Active: True
Type: onChange
Script:
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue == '')
{
return;
}
var cat_id = gel('sysparm_item_guid').value;
//copy values
var ga = new GlideAjax("AJAXChangeRequestUtils");
ga.addParam("sysparm_name", "getAttributes");
ga.addParam("sysparm_chg_id", newValue);
ga.getXML(handleResponse);
var answer = confirm("Would you like to copy the attachments?");
if (answer){
//copy attachments
var attga = new GlideAjax("AJAXChangeRequestUtils");
attga.addParam("sysparm_name", "copyAttachments");
attga.addParam("sysparm_source_id", newValue);
attga.addParam("sysparm_target_id", cat_id);
attga.getXMLWait();
getAttachmentList(cat_id);
}
}
function handleResponse(response)
{
//process return
var answer = response.responseXML.documentElement.getAttribute("answer");
if(answer)
{
var returneddata = answer.evalJSON(true);
for(field in returneddata)
{
g_form.setValue(field, returneddata[field]);
}
}
}
function getAttachmentList(sid) {
var ga = new GlideAjax('CatalogItemAjax');
ga.addParam('sysparm_name', 'list');
ga.addParam('sysparm_table', 'change_request');
ga.addParam('sysparm_table_sys_id', sid);
ga.getXML(handleCatalogItemAjaxResponse);
}
function handleCatalogItemAjaxResponse(response) {
// process return
var answer = response.responseXML.documentElement.getAttribute("answer");
if(answer)
{
var returneddata = answer.evalJSON(true);
var fileNameStr = "";
var ids = [];
var canDelete = [];
var createdBy = [];
var createdOn = [];
var contentType = [];
var encryption = [];
fileNameStr = returneddata["fileNameStr"];
ids = returneddata["ids"];
canDelete = returneddata["canDelete"];
createdBy = returneddata["createdBy"];
createdOn = returneddata["createdOn"];
contentType = returneddata["contentType"];
encryption = returneddata["encryption"];
var fileName = fileNameStr.split('///');
var msg1 = "The following document(s) will be added to your request:<br/><ul>";
var msg2 = "";
for(var i = 0; i < ids.length; ++i) {
if (fileName[i]) {
msg2 += "<li>" + fileName[i] + "</li>";
}
}
if (msg2 != "")
g_form.addInfoMessage(msg1 + msg2 + "</ul>");
}
}
Now I'm at the part where the list of attachments on the page needs to be refreshed, and I have tried with the refreshAttachments function found in UI Page attachment but is looking for page elements not found in the page, the script has jelly macros embedded as well. Here is the version of the function as I extracted it from the UI Page:
// this get called after an attachment is uploaded to update the display
function refreshAttachments(id, fileName, canDelete, createdBy, createdOn, contentType, encryption, iconPath) {
refreshLiveFeedAttachments(id, fileName, contentType, iconPath);
var encryptCheck = gel("encrypt_checkbox");
if (encryptCheck) {
encryptCheck.checked = false;
$('sysparm_encryption_context').value = "";
}
gel("please_wait").style.display = "none";
// if we didn't get an id, we could not read the attachment due to business rules so we're done
if (typeof id == "undefined")
return;
var noAttachments = gel("no_attachments");
if (noAttachments.style.display == "block")
noAttachments.style.display = "none";
// add the new upload to the display
var table = gel("attachment_table_body");
var tr = cel("tr");
var td = cel("td");
td.style.whiteSpace = "nowrap";
td.colspan = "2";
if (canDelete=="true") {
var input = cel("input");
var checkId = "sys_id_" + id;
input.name = checkId;
input.id = checkId;
input.type = "checkbox";
input.onclick = function() {setRemoveButton(gel(checkId));};
td.appendChild(input);
gel("delete_button_span").style.display = "inline";
var text = document.createTextNode(" ");
td.appendChild(text);
input = cel("input");
input.type = "hidden";
input.name = "Name";
input.value = "false";
td.appendChild(input);
}
var anchor = cel("a");
anchor.style.marginRight = "4px";
anchor.href = "sys_attachment.do?sys_id=" + id;
anchor.title = "${JS:gs.getMessage('Attached by')} " + createdBy + " ${JS:gs.getMessage('on')} " + createdOn;
var imgSrc = iconPath;
if (encryption != "") {
anchor.title += ", ${JS:gs.getMessage('Encrypted')}: " + encryption;
imgSrc = "images/icons/attachment_encrypted.gifx";
}
var img = cel("img");
img.src = imgSrc;
img.alt = anchor.title;
anchor.appendChild(img);
var text = $(cel('a'));
text.style.display = "inline";
text.href = "sys_attachment.do?sys_id=" + id;
text.onkeydown = function(event){return allowInPlaceEditModification(text, event);};
text.style.marginRight = "5px";
text.innerHTML = fileName;
text.setAttribute("data-id", id);
text.inPlaceEdit({
selectOnStart: true,
turnClickEditingOff: true,
onAfterEdit: function(newName) {
var oldName = this.oldValue;
var ga = new GlideAjax('AttachmentAjax');
ga.addParam('sysparm_type', 'rename');
ga.addParam('sysparm_value', id);
ga.addParam('sysparm_name', newName);
ga.getXML(function(response){
var answer = response.responseXML.documentElement.getAttribute("answer");
if (answer !== '0')
alert(new GwtMessage().getMessage("Renaming attachment {0} to new name {1} is not allowed", oldName, newName));
$$('a[data-id="' + id + '"]').each(function(elem){
elem.innerHTML = (answer === '0') ? newName : oldName;
});
$$('span[data-id="' + id + '"]').each(function(elem){
elem.innerHTML = (answer === '0') ? newName : oldName;
});
});
}
});
if (contentType == "text/html")
anchor.target = "_blank";
td.appendChild(anchor);
td.appendChild(text);
var allowRename = gel('ni.show_rename_link').value;
if (allowRename == "true") {
var renameAttachment = $(cel('a'));
renameAttachment.className = 'attachment';
renameAttachment.onclick = function() {
text.beginEdit();
};
renameAttachment.innerHTML = '${JS:gs.getMessage("[rename]")}';
td.appendChild(renameAttachment);
}
var showView = gel("ni.show_attachment_view").value;
if (showView == "true") {
var blank = document.createTextNode(" ");
tr.appendChild(blank);
var view = cel("a");
var newText = document.createTextNode('${JS:gs.getMessage("[view]")}');
view.appendChild(newText);
view.className = "attachment";
if (showPopup == "false")
view.href = "sys_attachment.do?sys_id=" + id + "&view=true";
else
view.onclick = function() {
tearOffAttachment(id)
};
td.appendChild(blank);
td.appendChild(view);
}
var showPopup = gel("ni.show_attachment_popup").value;
tr.appendChild(td);
table.appendChild(tr);
addAttachmentNameToForm(id, fileName, anchor.title, imgSrc, showView, showPopup);
var alert508 = "${gs.getProperty('glide.ui.section508')}";
if (alert508 == 'true')
alert(fileName + " " + anchor.title);
}