

- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on ‎03-14-2022 11:49 AM
Hi all,
I've seen this question asked a lot on the forums in various ways and majority of the responses point to either an old Guru (3rd party website) article that's a bit outdated or the response involves some sort of complex solution that majority of the time...is not needed.
I do want to preface this article with this callout....the solution I'm about to define is already available on your instance. This means you don't have to install anything.
So where is this "Download All" feature already available within your instance? Out of box, the "Download All" button, is located within the attachments menu (accessible by the paperclip icon for example) and is used to download all of the attachments associated to that current record as a Zip file:
So...that's it? Article over?
If the above satisfies your need and you don't need anything else, then yes, thanks for reading and enjoy the platform! If however...you were wanting to do something else...like make this feature more accessible or call it out a bit more or perhaps you have attachments on ANOTHER record that isn't the current record (perhaps a child record) and you want to download them by calling that action here (on the current record)…instead?
There's a few use cases as mentioned above that I'll go through and explain.
Use case #1: You want to create a more accessible experience that allows you to download all attachments for the current record
In this scenario, let's assume your audience doesn't necessarily like clicking the attachment icon to then click "Download All" and you want to make their life easier by creating a form button or form link, etc. where they can just click it and voila...all the attachments download that are associated to the current record into a nice Zip file.
This can be accomplished by creating a UI Action!
- Using the Incident form as an example, let's access the contextual menu and go to Configure > UI Action
- From here, we'll name our UI Action and ensure it's set Active = true
- You can decide if you want this to show up on insert (when creating new record) or update (after the record has been created) -- normally I'd say just check "Show update"
- Make sure "Client" = true
- Make your selection if you want this as a Form button, Form context menu, Form link, etc.
- The OnClick field should be set to a function name such as: openURL()
- If you want this UI Action to be conditional, utilize the Condition field as needed
- Within the script section, you can use something as simple as this:
function openURL() { g_navigation.openPopup("/download_all_attachments.do?sysparm_sys_id=" + g_form.getUniqueValue()); }​
- If you want this to appear within Agent Workspace, then scroll down and check the box for "Workspace Form Button" and then use script such as:
function onClick(g_form) { top.window.open("/download_all_attachments.do?sysparm_sys_id=" + g_form.getUniqueValue()); }​
Use case #2: You want to utilize the "download all attachments" feature on the current record, but the attachments are on another record
The setup for this use case is essentially the same as Use case #1 (same steps 1-7), except the script (steps 8 and 9) would refer to a specific record other than the current record. The easiest method would be if your current record had a field on it that references the target record that holds all the attachments, if so, your script would simply be:
function openURL() {
g_navigation.openPopup("/download_all_attachments.do?sysparm_sys_id=" + g_form.getValue('reference_field_name');
}​
And for Agent Workspace, you'd use:
function onClick(g_form) {
top.window.open("/download_all_attachments.do?sysparm_sys_id=" + g_form.getValue('reference_field_name');
}​
If perhaps the record that contains all the attachments is not on the current record as a reference field, for example...you may need to conduct a GlideRecord query based on some values on the current record to find the target record, etc. then you'd want to utilize GlideAjax in your UI Action. Example script could be:
UI Action:
function openURL() {
var ga = new GlideAjax('urlRecordQuery');
ga.addParam('sysparm_name', 'conductQuery');
ga.addParam('sysparm_field_value', g_form.getValue('field_name'));
ga.getXMLWait();
var sysID = ga.getAnswer();
if (sysID) {
g_navigation.openPopup("/download_all_attachments.do?sysparm_sys_id=" + sysID);
} else {
g_form.addErrorMessage("No valid record was retrieved");
}
}
UI Action for Agent Workspace:
function onClick(g_form) {
var ga = new GlideAjax('urlRecordQuery');
ga.addParam('sysparm_name', 'conductQuery');
ga.addParam('sysparm_field_value', g_form.getValue('field_name'));
ga.getXMLWait();
var sysID = ga.getAnswer();
if (sysID) {
top.window.open("/download_all_attachments.do?sysparm_sys_id=" + sysID);
} else {
g_form.addErrorMessage("No valid record was retrieved");
}
}
Script Include with Client Callable checkbox = true
var urlRecordQuery = Class.create();
urlRecordQuery.prototype = Object.extendsObject(AbstractAjaxProcessor, {
conductQuery: function(){
var fieldValue = this.getParameter('sysparm_field_value');
var sysID;
var gr = new GlideRecord('table_name');
gr.addQuery('field_name', fieldValue);
gr.query();
if (gr.next()) {
sysID = gr.sys_id;
} else {
sysID = '';
}
return sysID;
},
type: 'urlRecordQuery'
});
The above are just examples, but hopefully you get the idea. You can add more parameters to your GlideAjax and Script Include as needed to help supply your GlideRecord query with more query parms.
Note: You can also accomplish the above with using both Client and Server side code in your UI Action, but for the sake of this article, we are using client side scripting and GlideAjax for any server calls we need to make.
Use case #3: You want to utilize the "download all attachments" feature on the current record, but the attachments are on multiple different records
This solution is the most complex out of the three and requires you to do a combination of Use case #1 (steps 1-7) and Use case #2 (use GlideAjax to communicate with the server to do 'x').
The overall idea here is that within your script include you'd leverage the GlideSysAttachment API to temporarily make copies of the attachments from those target records and house them on the current record (or a blank new record or somewhere else), once complete, you'd fire an event that would trigger a script action all while you'd return the appropriate record sys_id that houses your attachments to your UI Action to then commence the download. The download process executed by your UI Action runs very quick, while the script action takes a few seconds before it actually starts to circle back through and delete the attachments from the housing record. Again, this is all an example to get your mind thinking how you'd like to accomplish this.
If you want to see an example for this use case, leave a comment below and I'll put something together.
Use case #4: You want to utilize the "download all attachments" feature on the Service Portal as a button
You'd want to create a widget and then use relevant HTML, Client, and Server Side scripting, as necessary to essentially do the same thing we're doing in these other use cases. At the end of the day, as long as you're pushing towards the URL that is supplied in these script examples, that is how you'd engage the out of box feature to download all attachments. If you're interested in seeing an example for this use case, feel free to leave a comment below, letting me know, and I'll put together something.
Please be sure to bookmark this article as well as mark it as Helpful if you thought it was helpful.
Interested in other articles I've written? Check this out: Embed image attachments from a record within your notification email body!
Thanks and take care! 🙂
- 13,402 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Thanks, @Allen Andreas for this informative article,

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content


- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi,
Please give some details towards your need for use case 3 and I can give instructions.
Thanks!
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @Allen Andreas , The Problem statement to leverage use case 3 is:
On parent incident there should be a ui action and on click of it, attachment from all the child incidents should be download at once in a zip file.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi Allen,
Thanks for this interesting explanation. It seems you covered almost all the use cases.
Considering to explore use case 3, can we download entire attachments from a specific table? Also to download the attachments with some primary key of corresponding record (attachment file name with extended name). The idea is to restore the attachments when required. In HR or other/legal/govt requirement, we need to remove and restore the attachment to comply with legal requirements. Appreciate any input on this. Thanks.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @Allen Andreas ,
We have a requirement to download the selected records of a custom table into zip file(with individual records as pdf files inside).
How to achieve this. Could you please suggest a solution.
Thank you,
Manasa
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
This feature is provided as a built-in functionality, and you don't need to install any additional plugins or software to access it forza horizon 5 free download
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
How can we change the zip file name according to our need?

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
I have requirement when we click on Zip button zip file will get download which contains csv /excel in which all record details are present for that current table.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
@SaurabhGidwani
Did you manage to achieve use case 3?
I am trying to do something similar.
From a pm_project, i need to download all attachments from the project + all related prj_tasks
@Allen Andreas Did you ever come around to give and example of use case 3?
thanks
Andreas
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
can you give case 3 example
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi all,
You can implement case 3 with a UI Action that has
Client = true
List Choice = true
Condition = true
OnClick = openURL()
Script
function openURL() {
var string_list = g_list.getChecked();
var list = string_list.split(",");
for (var i =0; i<list.length; i++){
g_navigation.openPopup("/download_all_attachments.do?sysparm_sys_id=" + list[i]);
}
}
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
how can I change the file name?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
hi,
my scenario is the following: i have a list in agent workspace, for each record in the list i have to download via REST API the related file (the REST is working and for each record selected there is the proper file)...then i want to create the zip of all these file, automatically download it and then delete that attachments...any advice?