Editor.js is a JavaScript solution for creating a web text editor. It is a WYSIWYG editor that allows inline editing of web text content.
Online-hosted editors provide more features to create and format content in an enriched manner. The Editor.js JavaScript library helps to create our editor in an application.
There are numerous online editors with advanced tools. But, having a custom editor can be sleeker to use and maintain.
The Editor.js has many features to embed rich text content by creating placeholders in the editor with the help of its tools. Tools are enabled by using the external libraries developed for Editor.js.
Those library tools enrich the capability of this web text editor plugin. The following table shows the tools enabled with this Editor.js JavaScript initiation. These tools create different types of rich text content in different formats.
This demo allows you to experience the features of an online editor by integrating this library.
Tool | Description |
---|---|
Header | Creates the H1, H2, H3, H4, H5, and H6 heading blocks for the web editor. |
Link embeds | It lets pasting URL and extracts content from the link pasted into this input. |
Raw HTML blocks | It allows embedding raw HTML codes to the web text editor. |
Simple image | It accepts the image’s full path or allows to paste of copied image content to render images without server-side processing. |
Image | It supports choosing files, pasting URLs, pasting images or dragging and dropping images to the rich text content area. |
Checklist | It is used to create checklist items. |
List | It adds ordered and unordered list items. |
Embeds | It embeds content by loading iFrame to the content. |
Quote | It creates quote blocks with a toolbar to format rich text content and add links. |
The official getting started tutorial has detailed usage documentation about this JavaScript editor. The above tools list is described with appropriate linking to their 3-party library manual.
The Editor.js and its libraries can be integrated using one of the several ways listed below.
After including the required library files, the Editor.js has to be instantiated.
const editor = new EditorJS('editorjs');
[OR]
const editor = new EditorJS({
holder: 'editorjs'
});
Here, the “editorjs” is used as the holder referring to the HTML target to render the web text editor.
If the editor has to display some default template, it requires creating a landing template to render into this. This web editor plugin class accepts rich text content templates via a data property. The format will be as shown below.
{
time: 1452714582955,
blocks: [
{
"type": "header",
"data": {
"text": "Title of the Editor",
"level": 2
}
}
],
version: "2.10.10"
}
This example has the code that teaches how to configure the most used tools of the Editor.js library. It renders HTML code blocks and embeds images and link extracts.
The image upload and link extract tools are configured with the server-side endpoint. It handles backend action on the upload or the extract events.
On saving the composing rich text content, the Editor.js data will be saved to the database. The data shown in the web editor is dynamic from the database.
<?php
require_once __DIR__ . '/dbConfig.php';
$content = "''";
$sql = "SELECT * FROM editor";
$stmt = $conn->prepare($sql);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
if(!empty($row["content"])) {
$content = $row["content"];
}
?>
<html>
<head>
<title>Create Web Text Editor using JavaScript with Editor.js</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<link href="form.css" rel="stylesheet" type="text/css" />
<style>
#loader-icon {
display: none;
vertical-align: middle;
width: 100px;
}
</style>
</head>
<body>
<div class="phppot-container">
<h1>Create Web Text Editor using JavaScript with Editor.js</h1>
<div id="editorjs" name="editor"></div>
<input type="submit" onClick=save() value="save">
<div id="loader-icon">
<img src="loader.gif" id="image-size" />
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/header@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/list@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/image@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/raw"></script>
<script
src="https://cdn.jsdelivr.net/npm/@editorjs/checklist@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/link@latest"></script>
<script src="editor-tool.js"></script>
<script>
const editor = new EditorJS({
/**
* Id of Element that should contain Editor instance
*/
holder: 'editorjs',
tools: {
header: Header,
list: List,
raw: RawTool,
image: {
class: ImageTool,
config: {
endpoints: {
byFile: 'http://localhost/phppot/javascript/create-web-text-editor-javascript/ajax-endpoint/upload.php', // Your backend file uploader endpoint
byUrl: 'http://localhost/phppot/javascript/create-web-text-editor-javascript/ajax-endpoint/upload.php', // Your endpoint that provides uploading by Url
}
}
},
checklist: {
class: Checklist
},
linkTool: {
class: LinkTool,
config: {
endpoint: 'http://localhost/phppot/jquery/editorjs/extract-link-data.php', // Your backend endpoint for url data fetching,
}
}
},
data: <?php echo $row["content"]; ?>,
});
</script>
</body>
</html>
It has the ladder of six tools of Editor.js with JavaScript code. In this example, it creates images, link embeds, and more types of rich text content. Some are basic, like header, list, the default text tool, and more.
The Image and Link embed tools depend on the PHP endpoint URL to take action on the back end.
The image tool requires the PHP endpoint URL to save the uploaded files to the target folder. The JavaScript editor keys to configure the endpoint are listed below.
tools: {
image: {
class: ImageTool,
config: {
endpoints: {
byFile: 'http://localhost/phppot/javascript/create-web-text-editor-javascript/ajax-endpoint/upload.php',
byUrl: 'http://localhost/phppot/javascript/create-web-text-editor-javascript/ajax-endpoint/upload.php'
}
}
}
}
This is simple and performs the image upload operation in PHP. The image file is posted via JavaScript links to this server-side script.
<?php
$targetDir = "../uploads/";
$output = array();
if (is_array($_FILES)) {
$fileName = $_FILES['image']['name'];
if (is_uploaded_file($_FILES['image']['tmp_name'])) {
if (move_uploaded_file($_FILES['image']['tmp_name'], $targetDir . $fileName)) {
$output["success"] = 1;
$output["file"]["url"] = "http://localhost/phppot/javascript/create-web-text-editor-javascript/ajax-endpoint/" . $targetDir . $fileName;
}
}
}
print json_encode($output);
?>
This tool is configured like the one below to set the PHP endpoint to extract the content.
This example extracts contents like title, image, and text description from the embedded link.
tools: {
linkTool: {
class: LinkTool,
config: {
endpoint: 'http://localhost/phppot/jquery/editorjs/extract-link-data.php', // Your backend endpoint for url data fetching,
}
}
}
It creates a cURL post request in the endpoint PHP file to extract the data from the link. After getting the cURL response, the below code parses the response and creates a DOM component to render the rich text content into the WYSIWYG web editor.
It uses the GET method during the cURL request to extract rich text content and image from the link. In a previous tutorial, we used the GET and POST methods on PHP cURL requests.
<?php
$output = array();
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $_GET["url"]);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$data = curl_exec($ch);
curl_close($ch);
$dom = new DOMDocument();
@$dom->loadHTML($data);
$nodes = $dom->getElementsByTagName('title');
$title = $nodes->item(0)->nodeValue;
$metas = $dom->getElementsByTagName('meta');
$body = "";
for ($i = 0; $i < $metas->length; $i ++) {
$meta = $metas->item($i);
if ($meta->getAttribute('name') == 'description') {
$body = $meta->getAttribute('content');
}
}
$image_urls = array();
$images = $dom->getElementsByTagName('img');
for ($i = 0; $i < $images->length; $i ++) {
$image = $images->item($i);
$src = $image->getAttribute('src');
if (filter_var($src, FILTER_VALIDATE_URL)) {
$image_src[] = $src;
}
}
$output["success"] = 1;
$output["meta"]["title"] = $title;
$output["meta"]["description"] = $body;
$output["meta"]["image"]["url"] = $image_src[0];
echo json_encode($output);
?>
On clicking the “Save” button below the web text editor, it gets the editor output data and saves it to the database.
It calls the editor.save() callback to get the WYSIWYG web editor output. An AJAX call sends this data to the PHP to store it in the database.
function save() {
editor.save().then((outputData) => {
document.getElementById("loader-icon").style.display = 'inline-block';
var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.onreadystatechange = function() {
if (xmlHttpRequest.readyState == XMLHttpRequest.DONE) {
document.getElementById("loader-icon").style.display = 'none';
if (xmlHttpRequest.status == 200) {
// on success get the response text and
// insert it into the ajax-example DIV id.
document.getElementById("ajax-example").innerHTML = xmlHttpRequest.responseText;
}
else if (xmlHttpRequest.status == 400) {
// unable to load the document
alert('Status 400 error - unable to load the document.');
}
else {
alert('Unexpected error!');
}
}
};
xmlHttpRequest.open("POST", "ajax-endpoint/save-editor.php", true);
xmlHttpRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlHttpRequest.send("btnValue=" + JSON.stringify(outputData));
}).catch((error) => {
console.log('Saving failed: ', error)
});
}
This is the endpoint PHP file to process the editor’s rich text output in the backend. It creates the query to prepare and execute the insert operation to save the rich text content to the database.
<?php
require_once __DIR__ . '/../dbConfig.php';
$sql = "SELECT * FROM editor";
$stmt = $conn->prepare($sql);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
if (isset($_POST['btnValue'])) {
$editorContent = $_POST['btnValue'];
if (empty($row["content"])) {
$query = "INSERT INTO editor(content,created)VALUES(?, NOW())";
$statement = $conn->prepare($query);
$statement->bind_param("s", $editorContent);
$statement->execute();
} else {
$query = "UPDATE editor SET content = ? WHERE id = ?";
$statement = $conn->prepare($query);
$statement->bind_param("si", $editorContent, $row["id"]);
$statement->execute();
}
}
?>