The CreatorCon Call for Content is officially open! Get started here.

Create attachment from javascript after ctrl + v a screenshot

smicloud
Tera Guru

We are trying to create a function so the user can paste a screenshot to a task by pressing ctrl+v. The most important browser to get this working in is IE11. We have created functionality so we can paste the actual image and base64 encode it in the javascript. Now, the problem is that we cannot sort out how to actually create the attachment and save it with the task. Here is how we want it to work:

1. If possible, add the attachment to the task as if we added it using the normal component but by using javascript to access the components function for adding the attachment. This means no saving or reloading of the task. Cannot find any such kind of functionality. Is there any javascript function we can access to fix this? The normal component must use something, is this available to use? Or the function used when dragging a file to the task may also be used if available?

2. In case we cannot solve it as above, the other option we have been looking into is using the SOAP method AttachmentCreator. I see two suggestions we would like to explore: i) Use the normal way of accessing the SOAP API as if it was an external application. However, I am not sure if this is possible, is it? (http://wiki.servicenow.com/index.php?title=AttachmentCreator_SOAP_Web_Service#gsc.tab=0) ii) The other way is if we can access the some include script using GlideAjax to post the attachment (http://wiki.servicenow.com/index.php?title=GlideAjax#gsc.tab=0). Then I guess one has to refresh to get the attachments visible in the attachment list.

3. Any suggestions you may have in addition to this is of course appreciated.

Is it possible to solve and how?

1 ACCEPTED SOLUTION

guhann
Mega Guru

Hi Niklas,



Try this small utility. This may be helpful.



1) Create an UI Script with below code.


function addPasteEvent() {


  document.onpaste = function (event) {


  // use event.originalEvent.clipboard for newer chrome versions


  var items = (event.clipboardData   || event.originalEvent.clipboardData).items;


  // find pasted image among pasted items


  var blob = null;


  for (var i = 0; i < items.length; i++) {


  if (items[i].type.indexOf("image") === 0) {


  blob = items[i].getAsFile();


  }


  }


  // load image if there is a pasted image


  if (blob !== null) {


  var reader = new FileReader();


  reader.onload = function(event) {


  console.log(event.target.result); // data url!


  attachClipboardData(event.target.result);


  };


  reader.readAsDataURL(blob);


  }


  };


}



function attachClipboardData(data){


  var recordSysID = g_form.getUniqueValue();


  var recordTable = g_form.getTableName();


  var temp = data.toString().replace(/data:/g,'').split(';');


  var contentType = temp[0];


  var fileName = 'Screen shot.'+contentType.split('/')[1];


  var content = temp[1].toString().replace(/base64,/g,'');




  showLoadingDialog();


  var attach = new GlideAjax('<script>'); // Specify the script include name after completing step 2


  attach.addParam('sysparm_name','attachScreenshot');


  attach.addParam('sysparm_tableName',recordTable);


  attach.addParam('sysparm_sys_id',recordSysID);


  attach.addParam('sysparm_content_type',contentType);


  attach.addParam('sysparm_value',content);


  attach.addParam('sysparm_filename',fileName);


  attach.getXML(getResponse);



  function getResponse(response) {


  alert('Screen shot attached to ticket!');


  window.location.reload();


  }


}



2) Create a script include with below function in it.


attachScreenshot : function() {


  var StringUtil = GlideStringUtil;


  var value = StringUtil.base64DecodeAsBytes(this.getParameter('sysparm_value'));


  var tableName = this.getParameter('sysparm_tableName');


  var sys_id = this.getParameter('sysparm_sys_id');


  var filename = this.getParameter('sysparm_filename');


  var content_type = this.getParameter('sysparm_content_type');



  var attachment = new Attachment();


  attachment.write(tableName, sys_id, filename, content_type, value);


  },



3) Call the UI Script function in an onload script of incident/problem/change/global table as required.


function onLoad() {


  addPasteEvent();


}



After doing these just take a screen shot using print screen and paste it over an incident form. You can see the attachment added after a form reload.


NOTE: Its working fine in Chrome and FF. I don't have IE 11 to test. You can give it a try.



Try this and let me know if any questions.


View solution in original post

49 REPLIES 49

And now I can see that I wrote that it works in IE11 in my old comments. I think you need to debug the code to find out what the issue is for IE11. Also, make sure that you have the security settings in the browser configured properly, there are settings that can prevent the browser to capture paste of images if incorrectly configured.


Hi Niklas,



Thanks for your response. I have managed to make this work in Chrome (yay!!) and now I'm trying to make it work in IE11 (version 11.212.10586.0).



I've debugged your script and it adds the event listener to the element, but it doesn't seem to call the pasteAttachmentIE function.



I'll keep doing some digging and will let you know if I make any headway with a solution.



Thanks again for your help.



if(isIE){  


  document.getElementById("pasteArea").addEventListener('paste', pasteAttachmentIE, false);  


}




function pasteAttachmentIE(){  


if(typeof window.clipboardData != 'undefined') {  


var clip = window.clipboardData;  


  if (clip) {  


  if(clip.files.length == 0){  


  pastedNotImage();  


 


  }else if ( clip.files[0].type.indexOf('image/') !== -1) {  


  var url = URL.createObjectURL(clip.files[0]);  


  var blob = url.substring(4);  


  var reader = new window.FileReader();  


 


  reader.onloadend = function() {  


  var base64Image = reader.result;  


  attachClipboardData(base64Image);  


 


  };  


 


  reader.readAsDataURL(clip.files[0]);  


 


  }  


  }  


  }  


 


}


Hi Graham,



I've tried you code but I've got several problems :



1) in Chrome, it display an endless Loading message


find_real_file.png



2) In IE and FF, the fucntions pasteAttachmentIE and pasteAttachmentFF are not called.



I would be nice if you could advice me



Jean-Luc


Hi Graham,



I've done a step further but now no attachment in done. It looks like you had the same problem "I can see that the UI Script passes into the Ajax the data from the screenshot correctly and the page reloads as outlined within the dialog, but no attachment is created.". How did   you solve it ?



Your help will be greatly appreciated.



Regards


Jean-Luc


Hi Jean-Luc,



Apologies for the delay getting back to you, I've been away on paternity leave as I very recently became a dad



I did manage to get it working before I went for Google Chrome and only for the Incident form (so not Record Producers) but however my instance has since been removed and the work wasn't backed up (lesson learnt!).



However, I have seen from further comments down that you have managed to not only get it working but also made it work for Record Producers, as well as other browsers!



Seriously well done, this had my head in a blender for a while so I'm glad you managed to find a solution and that you have also been very kind enough to share it.



Thanks