The Jodit WYSIWYG editor is licensed MIT and authored in Typescript.
I discovered it quite by accident while search for a WYSIWYG editor for my new project. I had previously used several other products, notably CKEditor and TinyMCE. I switched recently to Quill because the license models for CKEditor and TinyMCE changed and are more restrictive. Quill is close, but very very basic. One Quill feature that appealed to me is that uploaded images are base64 encoded directly in the editor. That should be a basic option of all WYSIWYG editors to provide a measure of security (it prevents hot linking of images and minimizes image hacking). It's also one of the reasons I started looking again, I wanted the option of providing images that were stored on the server for alternate uses.
Jodit appeared during a Google search, but not shown as a main competitor to TinyMCE, CKEditor or even Quill. It appeared to be an "alternative" product. It didn't take long to identify Jodit as a much stronger alternative to TinyMCE and CKEditor ... and far surpassing Quill.
I'm not 100% certain, but I think the documentation for Jodit is auto-generated. It sucks. It's horrible – and most users and reviewers agree. After fiddling with Jodit awhile, I have finally figured out how to handle image uploads with out resorting to the "connector" code that is an optional part of the package. The main reason for that is the optional code is 17Mb all by itself. Gheez, I just want a basic uploader that verifies file type, file size, and handles the upload. The use is by known administrators and moderators of my package, not the general public.
By the way, if you continue reading, know that this article is for the image upload feature only, not for the file browser. The code that follows is for the page that displays the editor. It will contain two main sections, one is for the textarea that is the container of the editor and looks like:
<div class="result">
<textarea id="area_editor"></textarea>
</div>
The next section is the script to generate the WYSIWYG editor. Note this is only part of it, the missing parts are for the layout of the buttons and not necessary for this article.
There are two possible "configurations", the first is if you want the image uploader to display the image as a base64 blob.
<script>
var editor = Jodit.make('#area_editor', {
imageDefaultWidth: 400, // Sets default width in px
uploader: {
insertImageAsBase64URI: true
}
});
</script>
The second is if you want the image to display as an <img tag with the server-side location. Note that my uploader PHP script is stored in /assets/lib/. The code:
<script>
var editor = Jodit.make('#area_editor', {
imageDefaultWidth: 400, // Sets default width in px
uploader: {
insertImageAsBase64URI: false,
format: 'json',
url: 'https://example.com/assets/lib/jodit_uploader.php',
defaultHandlerSuccess: function (data, resp) {
// Check if the backend returned the correct format
if (data && data.files && data.files.length > 0) {
// Correct: Inserts <img src="...">
this.selection.insertImage(data.baseurl + data.files[0]);
}
}
}
});
</script>
This next section is from MY actual jodit_uploader.php script ... but only the applicable portion. Security and validation is your responsibility (not the subject of this article). And note that jodit_uploader.php script is only required is you are not using base64 for the image source.
The relevant portion is the return code for AJAX. The rest you should have from basic Google searches (add a reply to this article if you can't find from Google searches and I'll figure a way to create a download). Here's the response after verifying an image was uploaded:
if (isset($_FILES['files']) && $_FILES['files']['error'][0] === UPLOAD_ERR_OK) {
if (move_uploaded_file($_FILES['files']['tmp_name'][0], $targetPath)) {
$response = [
"success" => true,
'time' => date('d/m/Y'),
"data" => [
'files' => [$fileName],
'path' => $jsonPath,
'baseurl' => 'https://example.com/assets/lib/uploads/',
"error" => 0,
'messages' => ['File uploaded successfully']
]
];
} else {
$response['messages'] = ['Failed to move uploaded file.'];
}
} else {
$response['messages'] = ['No file uploaded or an upload error occurred.'];
}
This article should save you countless hours of searching and frustrating coding attempts.
Enjoy!