- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-29-2015 01:52 AM
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?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-29-2015 06:21 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-31-2015 03:15 PM
Niklas, I just surfed the web to get the methods to get clipboard data and to convert it to base64 format. Once we have base64 it's easy to create an attachment by just inserting it in sys_attachment against a record.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-13-2016 10:47 AM
Hi Niklas,
This sounds exactly like what I'm trying to do but I seem to have run into a snag.
It seems everything works up until the dialog opens and tries to run the Ajax with the script include.
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.
Below is what I have done (as outlined by yourself and @Guhan Narayanan) in my personal instance, can you let me know if you can see where I am going wrong?
Any help would be really appreciated!!
Thanks
Incident Form
- Annotation field added to top of form
UI Script - addPasteEvent
- Global - Ticked
function addPasteEvent() {
// Get browser type and IE version
var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
var isChrome = !!window.chrome && !isOpera;
var isFirefox = typeof InstallTrigger !== 'undefined'; // Firefox 1.0+
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
var isIE = /*@cc_on!@*/false || !!document.documentMode;
var ieVersion = "";
if(isIE) {
ieVersion = getInternetExplorerVersion();
if(ieVersion != "11"){
alert("Cannot paste using Ineternet Explorer 10 or earlier. Please upgrade to Internet Explorer 11 for to be able to paste images directly into the task");
return false;
}
}
// Add paste event for all supported browser types
if(isChrome){
document.getElementById("pasteArea").addEventListener('paste', pasteAttachmentChrome, false);
}else if(isIE){
document.getElementById("pasteArea").addEventListener('paste', pasteAttachmentIE, false);
}else if (isFirefox){
document.getElementById("pasteArea").addEventListener('paste', pasteAttachmentFF, false);
}
//add event handler for removing and adding informative text in annotaction field
document.getElementById("pasteArea").addEventListener('blur', addInformativeText, false);
document.getElementById("pasteArea").addEventListener('focus', removeInformativeText, false);
}
function addInformativeText(){
document.getElementById("pasteArea").innerHTML = "Click here then paste screenshot (ctrl + v)";
}
function removeInformativeText(){
document.getElementById("pasteArea").innerHTML = "";
}
function pasteAttachmentChrome(){
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) {
var base64Image = event.target.result;
attachClipboardData(base64Image);
};
reader.readAsDataURL(blob);
}else{
pastedNotImage();
}
}
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]);
}
}
}
}
function pasteAttachmentFF(event){
//setTimeout(getImage, 1)
var base64img = setTimeout(getImage, 1);
}
function getImage(){
var pasteCatcher = document.getElementById("pasteArea");
var image = pasteCatcher.getElementsByTagName("img");
if(image.length == 0) pastedNotImage();
attachClipboardData(image[0].src);
}
function pastedNotImage(){
alert("No image pasted");
}
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('attachScreen');
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) {
window.location.reload();
}
}
function getInternetExplorerVersion() {
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
var rv = -1;
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) // If Internet Explorer, return version number
{
if (isNaN(parseInt(ua.substring(msie + 5, ua.indexOf(".", msie))))){
//For IE 11 >
if (navigator.appName == 'Netscape') {
ua = navigator.userAgent;
var re = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null) {
rv = parseFloat(RegExp.$1);
return rv;
}
}
else {
return fale;
}
}
else {
//For < IE11
return parseInt(ua.substring(msie + 5, ua.indexOf(".", msie)));
}
return false;
}}
Script Includes - attachScreen
- Client Callable - Ticked
var attachScreen = Class.create();
attachScreen.prototype = {
initialize : function() {
},
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);
},
type : 'attachScreen'
};
Client Script - addScreen
- Table - Incident
- Type - On Load
function onLoad() {
addPasteEvent();
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-13-2016 11:00 AM
Hello Graham,
What browser and version are you using? If you are using IE11 or Microsoft Edge the code have to be updated to support those versions I think. Haven't done it yet myself but I have verified that it doesn't work in those browsers. I haven't done any debugging at all so I don't know which part has to be updated (identification of the browser version or the actual capture of the screenshot).
Regards,
/Niklas
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-14-2016 01:18 AM
Hi Niklas,
I'm currently trying to do this in Google Chrome - version 49.0.2623.112 m - but I will also need to make this work for IE11 (our business uses IE11 as their standard browser). I just can't seem to get this to work at all at the moment.
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-16-2016 01:07 AM
It was a while since I completed this project. I don't remember but there may have been some issues with the code above for Chrome. If you just copied the code above you may need to do some debugging to find out where it fails.
As mentioned, this doesn't work with IE11 and I haven't started to look for a fix yet.