- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
I'm trying to build a UI macro in the global scope that creates a db_image record from an image file input, and adds the db_image reference to a list field on the record. I've not managed to get the image content written correctly.
Extract of the client-side code:
function addPicture() {
var fileInput = document.getElementById('picture_upload'); // picture_upload is a file input element
if (fileInput.value=='') return;
var file = fileInput.files[0];
if (file.type.indexOf('image')!=0) return;
var reader = new FileReader();
reader.onload = function() {
var content = this.result.replace(/data:[^;]+;base64,/i, '');
var ga = new GlideAjax('UoBImageUtilsAjax');
ga.addParam('sysparm_name', 'add');
ga.addParam('sysparm_file_name', file.name);
ga.addParam('sysparm_file_type', file.type);
ga.addParam('sysparm_file_content', content );
ga.addParam('sysparm_target_table', 'u_learning_spaces_locations');
ga.addParam('sysparm_target_id', document.getElementById('record_id').value);
ga.getXMLAnswer(function(answer) {
try {
var result = JSON.parse(answer);
if (result.success==true) {
g_form.addInfoMessage(file.name + ' attached successfully');
setTimeout(function() { location.reload(true); }, 1000);
} else {
g_form.addErrorMessage(result.error);
}
} catch (ex) {
g_form.addErrorMessage('something has gone wrong');
}
})
};
reader.onerror = function() {
g_form.addErrorMessage('Error reading ' + file.name);
};
reader.readAsDataURL(file);
}
Extract of the server-side code
var result = {success: false, error: '', db_image_id: '', attachment_id: ''};
var file_name = (this.getParameter('sysparm_file_name')+''),
file_type = (this.getParameter('sysparm_file_type')+''),
file_content = (this.getParameter('syparm_file_content')+'');
var target_table = (this.getParameter('sysparm_target_table')+''),
target_id = (this.getParameter('sysparm_target_id')+''),
target_fld = (this.getParameter('sysparm_target_fld') || 'u_pictures')+'';
try {
var db_image = new GlideRecord('db_image');
db_image.setValue('name', file_name);
db_image.setValue('category', 'general');
db_image.setValue('active', true);
result.db_image_id = db_image.insert();
// GlideSysAttachment.writeBase64 does not work in global scope
var raw = GlideStringUtil.base64DecodeAsBytes(file_content)+'';
result.attachment_id = (new GlideSysAttachment()).write(db_image, file_name, file_type, raw);
if (!result.attachment_id) {
throw new Error('Error creating attachment record');
}
db_image.setValue('image', result.attachment_id);
db_image.setValue('format', file_type.split('/').pop());
db_image.update();
var target = new GlideRecord(target_table);
if (target.get(target_id)) {
var pictures = (target.getValue(target_fld)||'').split(',');
pictures.push(result.db_image_id);
target.setValue(target_fld, pictures.join(','));
target.update();
} else {
throw new Error('Invalid target record');
}
result.success = true;
} catch (ex) {}
How do I process the file input so that the image content is saved correctly?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
update as this
Client side
-> spelling mistake in this.getParameter() is corrected
function addPicture() {
var fileInput = document.getElementById('picture_upload');
if (!fileInput || !fileInput.files || fileInput.files.length === 0) {
g_form.addErrorMessage('Please select an image.');
return;
}
var file = fileInput.files[0];
if (!file.type || file.type.indexOf('image/') !== 0) {
g_form.addErrorMessage('Only image files are allowed.');
return;
}
var reader = new FileReader();
reader.onload = function(event) {
var dataUrl = event.target.result || '';
var commaIndex = dataUrl.indexOf(',');
if (commaIndex === -1) {
g_form.addErrorMessage('The selected file could not be encoded.');
return;
}
// Remove: data:image/png;base64,
var base64Content = dataUrl.substring(commaIndex + 1);
var ga = new GlideAjax('UoBImageUtilsAjax');
ga.addParam('sysparm_name', 'add');
ga.addParam('sysparm_file_name', file.name);
ga.addParam('sysparm_file_type', file.type);
ga.addParam('sysparm_file_content', base64Content);
ga.addParam('sysparm_target_table', 'u_learning_spaces_locations');
ga.addParam(
'sysparm_target_id',
document.getElementById('record_id').value
);
ga.addParam('sysparm_target_field', 'u_pictures');
ga.getXMLAnswer(function(answer) {
try {
var result = JSON.parse(answer);
if (result.success === true) {
g_form.addInfoMessage(
file.name + ' attached successfully'
);
setTimeout(function() {
window.location.reload(true);
}, 1000);
} else {
g_form.addErrorMessage(
result.error || 'The image could not be saved.'
);
}
} catch (ex) {
g_form.addErrorMessage(
'Invalid response received from the server.'
);
}
});
};
reader.onerror = function() {
g_form.addErrorMessage(
'Error reading ' + file.name
);
};
reader.readAsDataURL(file);
}
Server script -> use GlideStringUtil.base64DecodeAsBytes() followed by the global GlideSysAttachment.write()
var UoBImageUtilsAjax = Class.create();
UoBImageUtilsAjax.prototype = Object.extendsObject(AbstractAjaxProcessor, {
add: function() {
var result = {
success: false,
error: '',
db_image_id: '',
attachment_id: ''
};
try {
var fileName = this.getParameter('sysparm_file_name') || '';
var fileType = this.getParameter('sysparm_file_type') || '';
var fileContent =
this.getParameter('sysparm_file_content') || '';
var targetTable =
this.getParameter('sysparm_target_table') || '';
var targetId =
this.getParameter('sysparm_target_id') || '';
var targetField =
this.getParameter('sysparm_target_field') ||
'u_pictures';
if (!fileName || !fileType || !fileContent) {
throw new Error('File name, type, or content is missing.');
}
if (fileType.indexOf('image/') !== 0) {
throw new Error('Only image files are allowed.');
}
if (!targetTable || !targetId || !targetField) {
throw new Error('Target record information is incomplete.');
}
var target = new GlideRecord(targetTable);
if (!target.isValid()) {
throw new Error('Invalid target table.');
}
if (!target.get(targetId)) {
throw new Error('Target record was not found.');
}
if (!target.isValidField(targetField)) {
throw new Error(
'Invalid target field: ' + targetField
);
}
// Validate the payload before decoding.
fileContent = fileContent
.replace(/\s/g, '')
.replace(/-/g, '+')
.replace(/_/g, '/');
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(fileContent)) {
throw new Error('Invalid Base64 image content.');
}
// Decode Base64 into binary bytes.
var bytes =
GlideStringUtil.base64DecodeAsBytes(fileContent);
if (!bytes || bytes.length === 0) {
throw new Error('The decoded image content is empty.');
}
/*
* Create the db_image record first.
*/
var dbImage = new GlideRecord('db_image');
dbImage.initialize();
dbImage.setValue('name', fileName);
dbImage.setValue('category', 'general');
dbImage.setValue('active', true);
var dbImageId = dbImage.insert();
if (!dbImageId) {
throw new Error('Could not create db_image record.');
}
result.db_image_id = dbImageId;
/*
* Attach the decoded bytes to the db_image record.
*/
var attachment = new GlideSysAttachment();
var attachmentId = attachment.write(
dbImage,
fileName,
fileType,
bytes
);
if (!attachmentId) {
throw new Error(
'Could not create attachment for db_image.'
);
}
result.attachment_id = attachmentId;
/*
* The db_image.image field stores the attachment sys_id.
*/
dbImage.setValue('image', attachmentId);
dbImage.setValue(
'format',
fileType.substring(fileType.indexOf('/') + 1)
);
dbImage.update();
/*
* Add the db_image sys_id to the list field.
*/
var existingValue =
target.getValue(targetField) || '';
var imageIds = existingValue
.split(',')
.filter(function(id) {
return id;
});
if (imageIds.indexOf(dbImageId) === -1) {
imageIds.push(dbImageId);
}
target.setValue(targetField, imageIds.join(','));
target.update();
result.success = true;
} catch (ex) {
result.error = ex.message || String(ex);
gs.error(
'UoBImageUtilsAjax.add failed: ' + result.error
);
}
return JSON.stringify(result);
},
type: 'UoBImageUtilsAjax'
});
💡 If my response helped, please mark it as correct ✅ and close the thread 🔒— this helps future readers find the solution faster! 🙏
Ankur
✨ Certified Technical Architect || ✨ 10x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
Hi Ankur
I understand what you were trying to tell me. There was a typo in the server script.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
yes that's what I mentioned the spelling mistake
Glad that my script worked.
💡 If my response helped, please mark it as correct ✅ and close the thread 🔒— this helps future readers find the solution faster! 🙏
Ankur
✨ Certified Technical Architect || ✨ 10x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
21 hours ago
It was actually your script that confused me, since it was essentially the same as what I had written. It would have been a lot clearer if you had simply pointed out the typo.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
21 hours ago
Thanks for the feedback.
I did mention the correction but may be it got missed due to the script section
Ankur
✨ Certified Technical Architect || ✨ 10x ServiceNow MVP || ✨ ServiceNow Community Leader