📝 Rich Text Editor in a Form
Have you ever wanted to allow persons/end users to input HTML? You might do this to allow a person lacking a Slate user account to insert content, or for other reasons.
Thanks to Lloyd Lentz for the improved script!
Summary
Basically, we pick a Paragraph Text (textarea) form element, supply some background scripts, then transform the textarea into a CKEditor.
Your text field will store raw HTML. If you output it in a portal, use Liquid like {{ field_name | rawhtml }}
to avoid the HTML being escaped.
Instructions
- Create a Paragraph Text form element. We recommend width 80 and height 10.
- Create an Instructions form element below the Paragraph Text and supply the below code in the source.
- The first three scripts are needed resources. You may need to find updated URL's as Technolutions continues to update Slate.
- Update
var exportKey = "some_notes";
with the actual export key of your textarea.
<script>
// Define the export key
var exportKey = "purpose";
// Load CKEditor and CKFinder scripts dynamically
$.when(
$.getScript("/fw/framework/ckfinder/ckfinder.js?v=25af&cdn=0"),
$.getScript("//slate-technolutions-net.cdn.technolutions.net/manage/deliver/ckeditor.js?v=TS-25af-635119916154460870"),
$.getScript("//fw.cdn.technolutions.net/framework/ckeditor.js?v=25af")
).done(function () {
// All scripts loaded successfully, now find the textarea and attach CKEditor
var textareaId = $('div[data-export="' + exportKey + '"] textarea').attr('id');
if (textareaId) {
if (CKEDITOR.instances[textareaId]) {
CKEDITOR.remove(CKEDITOR.instances[textareaId]);
}
editor = CKEDITOR.replace(textareaId, {
startupFocus: true,
fullPage: false,
height: 320,
forceEnterMode: true,
toolbar: CKEDITOR.getToolbar('full'),
removePlugins: 'image,templates'
});
}
}).fail(function () {
console.error("One or more scripts failed to load.");
});
</script>
removePlugins
removes images and template options under the assumption that people submitting the form do not have /manage access. Alternate version that allows image and template browsing:
<script>
// Define the export key
var exportKey = "purpose";
// Load CKEditor and CKFinder scripts dynamically
$.when(
$.getScript("/fw/framework/ckfinder/ckfinder.js?v=25af&cdn=0"),
$.getScript("//slate-technolutions-net.cdn.technolutions.net/manage/deliver/ckeditor.js?v=TS-25af-635119916154460870"),
$.getScript("//fw.cdn.technolutions.net/framework/ckeditor.js?v=25af")
).done(function () {
// All scripts loaded successfully, now find the textarea and attach CKEditor
var textareaId = $('div[data-export="' + exportKey + '"] textarea').attr('id');
if (textareaId) {
if (CKEDITOR.instances[textareaId]) {
CKEDITOR.remove(CKEDITOR.instances[textareaId]);
}
editor = CKEDITOR.replace(textareaId, {
filebrowserImageBrowseUrl: '/manage/database/asset?cmd=browse&type=images',
filebrowserBrowseUrl: '/manage/database/asset?cmd=browse&type=documents',
templates_files: ['/manage/deliver/?cmd=templates'],
startupFocus: true,
fullPage: false,
height: 320,
forceEnterMode: true,
toolbar: CKEDITOR.getToolbar('full'),
});
}
}).fail(function () {
console.error("One or more scripts failed to load.");
});
</script>
7 Comments
I propose the following, which allows us to use the ExportKey, which is user defined in the form.
// Define the export key
var exportKey = "purpose";
// Find the textarea based on the export key and get its ID
var textareaId = $('div[data-export="' + exportKey + '"] textarea').attr('id');
// Attach the CKEditor using the dynamically obtained ID
if (textareaId) {
if (CKEDITOR.instances[textareaId]) {
CKEDITOR.remove(CKEDITOR.instances[textareaId]);
}
editor = CKEDITOR.replace(textareaId, {
filebrowserImageBrowseUrl: '/manage/database/asset?cmd=browse&type=images',
filebrowserBrowseUrl: '/manage/database/asset?cmd=browse&type=documents',
templates_files: ['/manage/deliver/?cmd=templates'],
startupFocus: true,
fullPage: false,
height: 320,
forceEnterMode: true,
toolbar: CKEDITOR.getToolbar('full'),
});
}
... and even better
// Define the export key
var exportKey = "purpose";
// Load CKEditor and CKFinder scripts dynamically
$.when(
$.getScript("/fw/framework/ckfinder/ckfinder.js?v=25af&cdn=0"),
$.getScript("//slate-technolutions-net.cdn.technolutions.net/manage/deliver/ckeditor.js?v=TS-25af-635119916154460870"),
$.getScript("//fw.cdn.technolutions.net/framework/ckeditor.js?v=25af")
).done(function() {
// All scripts loaded successfully, now find the textarea and attach CKEditor
var textareaId = $('div[data-export="' + exportKey + '"] textarea').attr('id');
if (textareaId) {
if (CKEDITOR.instances[textareaId]) {
CKEDITOR.remove(CKEDITOR.instances[textareaId]);
}
editor = CKEDITOR.replace(textareaId, {
filebrowserImageBrowseUrl: '/manage/database/asset?cmd=browse&type=images',
filebrowserBrowseUrl: '/manage/database/asset?cmd=browse&type=documents',
templates_files: ['/manage/deliver/?cmd=templates'],
startupFocus: true,
fullPage: false,
height: 320,
forceEnterMode: true,
toolbar: CKEDITOR.getToolbar('full'),
});
}
}).fail(function() {
console.error("One or more scripts failed to load.");
});
-Lloyd
In reply to #2
Thanks, Lloyd!
Hi there! Thank you for this - so helpful!! I'm wondering if it's possible to apply this code to more than one field on a single form... I keep trying, but it's not working. Does anyone know if it's possible and if so, how? :)
In reply to #4
You have to change the name of the variable associated with the exportKey, not just the export key itself. The scripts are technically all running at effectively the same time, so if you leave the variable names the same, the last one to set it is the only one all scripts will search for to add the rich text editor to. 🫡
In reply to #5
At least that's the cause of and solution to the issue in my experience
In reply to #5
I think you identified the problem correctly! You could also do something like this that use a loop to attach the editor to multiple fields:
<script>
// Array of textarea fields keys to be processed
var exportKeys = ["purpose", "description", "requirements", "notes"];
// Load CKEditor and CKFinder scripts dynamically
$.when(
$.getScript("/fw/framework/ckfinder/ckfinder.js?v=25af&cdn=0"),
$.getScript("//slate-technolutions-net.cdn.technolutions.net/manage/deliver/ckeditor.js?v=TS-25af-635119916154460870"),
$.getScript("//fw.cdn.technolutions.net/framework/ckeditor.js?v=25af")
).done(function () {
// All scripts loaded successfully, now find the textareas and attach CKEditor
$.each(exportKeys, function(index, exportKey) {
var textareaId = $('div[data-export="' + exportKey + '"] textarea').attr('id');
if (textareaId) {
if (CKEDITOR.instances[textareaId]) {
CKEDITOR.remove(CKEDITOR.instances[textareaId]);
}
CKEDITOR.replace(textareaId, {
fullPage: false,
height: 320,
forceEnterMode: true,
toolbar: CKEDITOR.getToolbar('full'),
removePlugins: 'image,templates'
});
}
});
}).fail(function () {
console.error("One or more scripts failed to load.");
});
</script>