Hiding specific attachments?

othews
Giga Contributor

Hi,

Is there any way to hide specific attachments or only show specific attachments to end users? 


We enable end users to look at their incidents and Requested Items throught the ess view in Servicenow. We do not use the portal solution yet due to various reasons and  we will not be doing so for at least a year. 
We need to be able to hide specific attachments or only show specific attachments for our end users. Currently they see all of the attachments in their ticket and the attachments that we receive from partners or from assignment groups might contain sensitive information. We do not utilize incident tasks or Catalog tasks in our system. If we did we could of course keep sensitive attachments in the tasks and not on the main incident/RITM. But we dont.


However, we still need to show some attachments to the end users. For example guides or just showing them the documents that they've uploaded themselves.

Is there for example a way to create a new field where you place only certain attachments? Is there any way for Servicenow to recognize different upload sources for attachments? 
Is there any way at all for us to solve this?

Best regards
Ola Thews

1 ACCEPTED SOLUTION

Hello Othews,

 

1) Create an custom table "u_internal_attachments" and add two fields "Attachment" & DP Reference(reference to parent table.

2) Create a related list - select a view and give a related list

3) Create an UI action "Create new internal attachment"

check the List banner input and list action

Condition : current.canCreate() && !RP.getListControl().isOmitNewButton() && RP.isRelatedList()

Script:

function CreateNewInternalAttachment() {
try{

var uri = action.getGlideURI();
var path = uri.getFileFromPath() + '';
path = path.substring(0, path.length- 5) + '.do';
uri.set('sys_id', '-1');
var mainCaseSysID = uri.get('sysparm_collectionID');

var mainCaseDPIR = new GlideRecord('parent table');
mainCaseDPIR.get('sys_id', mainCaseSysID);

var params = 'sysparm_DPIRmaincaseSysID=' + mainCaseDPIR.sys_id + '&';
params += 'sysparm_fromMainCase=true';

var url = 'u_internal_attachments.do?sys_id=-1';
action.setRedirectURL(url + '&' + params);
action.setReturnURL(mainCaseDPIR);

}

catch (e){
gs.addErrorMessage('>>>UI Action ERROR: ' + e);
}

}

CreateNewInternalAttachment();

--------------------------------------------------------------------------

4)Hide the save button for this table since only "Submit" button should be visible - create a save action

5) Give the specific access by using ACLs

6) Write the BR to check whether attachment is made

 

(function executeRule(current, previous /*null when async*/) {

try{
var currentsysid = current.sys_id;

var attach = new GlideRecord('sys_attachment');
attach.addQuery('table_sys_id', currentsysid);
attach.query();

//Gliding current Table to create NEW records for Each Attachments.
var gr = new GlideRecord("u_internal_attachments");
var count = 1;

while(attach.next()){
//If only one Attachment attached.
if(count == 1){
current.u_attachment_reference = attach.sys_id;
}

//If more than one Attachment attached
else{
gr.initialize();
gr.u_dp_reference = current.u_dp_reference; //Check out the fields here
gr.u_attachment_reference = attach.sys_id;
gr.insert();

attach.table_sys_id = gr.sys_id;
attach.update();

}
count++;
}
gs.setRedirect('u_aero.do?sys_id='+current.u_dp_reference.sys_id); // after attachment is made basically it returns to the parent id

}

catch (e){
gs.log(">>>'Business Rule - DPInternalAttach - Populate Attachment : " + e + ' - ' + e.message, ">>>Business Rule<<<");
}

})(current, previous);

 

7) Write Client script - onLoad

 

function getParmVal(name) {
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.href);
if(results == null) {
return "";
}
else {
return unescape(results[1]);
}
}

function onLoad() {
try {

var fromMainCase = getParmVal('sysparm_fromMainCase') == 'true';

if (fromMainCase) {
var DPIRmaincaseSysID = getParmVal('sysparm_DPIRmaincaseSysID');

g_form.addInfoMessage('Please upload at least one attachment to proceed.');

g_form.setValue('u_dp_reference', DPIRmaincaseSysID);

}
else{
g_form.disableAttachments();
}
}

catch(e) {
//alert('Client Script --DPInternalAttachment-OnLoad-- ERROR: ' + e);
}
}

---------------------------------------------------------------------------

😎 write one onSubmit client script and call script include.

function onSubmit() {
try {

var glideAjax = new GlideAjax("DynamicAjaxQuery");
glideAjax.addParam('sysparm_name', 'queryMultipleResults_EncodedQuery');
glideAjax.addParam('sysparm_table', 'sys_attachment');
glideAjax.addParam('sysparm_encodedQuery', 'table_name=u_dp_internal_attachments^table_sys_id=' + g_form.getUniqueValue());
glideAjax.addParam('sysparm_returnField', 'file_name');
glideAjax.getXMLWait();
var response = glideAjax.getAnswer();
var attachmentCount = response == '' ? 0 : response.toString().split('|').length;
if (attachmentCount === 0) {
alert('No attachment(s) found. Please upload at least one attachment to proceed.');
return false;
}
}
catch (e) {
alert('>>>Unhandled client exception -- DPInterAttach-OnSubmit- CheckAttachment --: ' + e);
}
}

 

--------------------------------

 

queryMultipleResults_EncodedQuery : function () {
try {
var response = '';
var table = this.getParameter('sysparm_table');
var encodedQuery = this.getParameter('sysparm_encodedQuery');
var returnField = this.getParameter('sysparm_returnField');
var displayValue = this.getParameter('sysparm_displayValue') == 'true' ? true : false;

var gr = new GlideRecord(table);
gr.addEncodedQuery(encodedQuery);
gr.query();

while (gr.next()) {
response += (displayValue ? gr[returnField].getDisplayValue().toString() : gr[returnField].toString());
response += (gr.hasNext() ? '|' : '');
}

gs.log("Invocation DynamicAjaxQuery.queryMultipleResults_EncodedQuery() param {table:" + table + ", encodedQuery:" + encodedQuery + ", returnField:" + returnField + "} response: " + response, ">>>Script Include<<<");
return response;
}
catch (e) {
gs.log("'DynamicAjaxQuery' ERROR: " + e + ' - ' + e.message, ">>>Script Include<<<");
}
},

------------------------------------------------------------------

 

1) Refer the 1st screenshot in my 1st reply ..thats how it looks in related list

2) in form view and if you try to submit then it throws an alert as in client script

find_real_file.png

View solution in original post

20 REPLIES 20

Linda21
Kilo Contributor

Hi I'm encountering same issue. I'm wondering if you know how to solve it now. Please let me know. THANKS~

Hi,

I wasn't able to solve the issue. I had to abandon the effort to focus on other demands. Please let me know if you figure it out.

Many thanks!

Cyndi

 

I have this as a project and it's exactly what we're looking for. I took a look at the scripting and made some minor adjustments for the button, but couldn't get it to work, however, the "New" button that automatically gets associated with the table works just fine so I copied that scripting to the "New Internal Attachments" button and that fixed the problem.

I'm now having an issue with the onSubmit client script throwing an exception error so I'm working on that at the moment to try and figure out the problem. One thing I noticed is  that in the client script you're looking for your new table name on the sys_attachments table with "YY_ZZ" prefixed to the table name.

I'll respond to this later when I figure it out. The instructions were given a few releases ago so some of the scripting is probably getting thwarted by the updates.

Spencer, 

I was never able to figure it out myself so I am really looking forward to your next response.

Thanks so much!

Cyndi

Ok so I have it working now. Keep in mind, the idea behind my setup is so that agents can attach documents to a case that don't get exposed to their customers; nothing more and nothing less. I have no business rules setup and I only have this as a related list to cases - not tasks (yet). Also, I'm on Orlando, but here are the new instructions:

1. Create a new custom table and name it "u_internal_attachments" (or really whatever you'd like to name it) with two fields:

a. u_attachment (type: File Attachment)

b. u_parent (type: Reference; table: sn_customerservice_case)

2. Create a new relationship System Definition -> Relationships

a. Applies to table: Case [sn_customerservice_case] (or whatever table you want this to show up for in the Related Lists section)

b. Queries from table: Internal Attachments [u_internal_attachments]

c. Query with: find_real_file.png

3. Create a new UI action named "New Internal Attachment"

a. Check: Active, Show insert, Show Update, List banner button, List context menu, List choice

b. Condition:

current.canCreate() && !RP.getListControl().isOmitNewButton() && RP.isRelatedList()

c. Script:

var uri = action.getGlideURI();
var path = uri.getFileFromPath() + '';
path = path.substring(0, path.length - 5) + '.do';

uri.set('sys_id', '-1');

path = checkWizard(uri, path);

if (path)
   action.setRedirectURL(uri.toString(path));

action.setNoPop(true);

function checkWizard(uri, path) {
   var already = uri.get('WIZARD:action');
   if (already == 'follow')
   return null;
   
   var wizID = new GlideappWizardIntercept(path).get();
   if (!wizID)
      return path;
   
   uri.set('sysparm_parent', wizID);
   uri.deleteParmameter('sysparm_referring_url');
   uri.deleteMatchingParameter('sysparm_list_');
   uri.deleteMatchingParameter('sysparm_record_');
   uri.deleteParmameter('sys_is_list');
   uri.deleteParmameter('sys_is_related_list');
   uri.deleteParmameter('sys_submitted');
   uri.deleteParmameter('sysparm_checked_items');
   uri.deleteParmameter('sysparm_ref_list_query');
   uri.deleteParmameter('sysparm_current_row');
 
   uri.set('sysparm_referring_url', uri.toString());
   uri.deleteMatchingParameter('fancy.');
   uri.deleteMatchingParameter('sys_rownum');
   uri.deleteMatchingParameter('sysparm_encoded');
   uri.deleteMatchingParameter('sysparm_query_encoded');
   uri.deleteParmameter('sysparm_refer');

   return 'wizard_view.do';
}

3. Look for the "Save" UI action on the global table that shows up for this table, open up the record and change the table to the new attachments table and click "Insert and stay" from the context menu. Once done change the "Condition" to say false to override and hide that button.

4. Modify the ACLs for this table as needed

5. Create an async business rule for the new attachments table:

(function executeRule(current, previous /*null when async*/) {

try{
var currentsysid = current.sys_id;

var attach = new GlideRecord('sys_attachment');
attach.addQuery('table_sys_id', current.sys_id);
attach.query();

//Gliding current Table to create NEW records for Each Attachments.
var gr = new GlideRecord("u_internal_attachments");
var count = 1;

while(attach.next()){
//If only one Attachment attached.
if(count == 1){
current.u_attachment_reference = attach.sys_id;
}

//If more than one Attachment attached
else{
gr.initialize();
gr.u_parent = current.u_parent; //Check out the fields here
gr.u_attachment_reference = attach.sys_id;
gr.insert();

attach.table_sys_id = gr.sys_id;
attach.update();

}
count++;
}
gs.setRedirect('u_aero.do?sys_id='+current.u_dp_reference.sys_id); // after attachment is made basically it returns to the parent id

}

catch (e){
gs.log(">>>'Business Rule - DPInternalAttach - Populate Attachment : " + e + ' - ' + e.message, ">>>Business Rule<<<");
}

})(current, previous);

6. Write an onLoad client script for the regular expression to accept the file type in the name:

function onLoad() {
   //Type appropriate comment here, and begin script below
   function getParmVal(name) {
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.href);
if(results == null) {
return "";
}
else {
return unescape(results[1]);
}
}

function onLoad() {
try {

var fromMainCase = getParmVal('sysparm_fromMainCase') == 'true';

if (fromMainCase) {
var DPIRmaincaseSysID = getParmVal('sysparm_DPIRmaincaseSysID');

g_form.addInfoMessage('Please upload at least one attachment to proceed.');

g_form.setValue('u_parent', DPIRmaincaseSysID);

}
else{
g_form.disableAttachments();
}
}

catch(e) {
alert('Client Script --DPInternalAttachment-OnLoad-- ERROR: ' + e);
}
}
}

7. Go to your table you want this to appear on (and the one you setup the relationship definition for), open up a record on that table, right-click the grey area to get the context menu, go to Configure -> Related Lists and search for "Internal Attachments -> Parent" in the slush bucket and drag that over to the "Selected" side

Go into the form and test this to make sure it works. I did some testing and it works just fine for what we need.

I didn't implement the onSubmit client script (or rather, I did but then deleted it) or the script include because that checks to make sure there's a document to attach on submission. Instead I just hid the "Save" button as the "Submit" button will show up once the attachment field has a document in it. This way they either attach something or hit the back button.

Be advised, however, that this is 100% customized and not OOB so there will be wonky things with it. When I didn't have the "Save" button hidden from the form and hit "Save" it would create a record on the table, but no attachment would be there. This is something that I couldn't prevent, but hiding that "Save" button helps eliminate that.

Hope this solution works for you!