Create Web Text Editor using JavaScript with Editor.js

by Vincy. Last modified on March 25th, 2024.

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.

View Demo

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.

create web text editor javascript

How to install and initiate Editor.js

The Editor.js and its libraries can be integrated using one of the several ways listed below.

  1. Node package modules.
  2. By using the available CDN URLs of this JavaScript library.
  3. By including the local minified library files downloaded to the application folder.

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.

Fill the editor with the initial data

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"
}

Example: Integrate Editor.js with Raw HTML block, Image, Link embeds, and more

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.

Image tool configuration keys and endpoint script

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.

  1. byFile – This endpoint is used while pasting the file.
  2. byUrl – This endpoint is used while choosing the file, and dragging and dropping files.
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'
                    }
		}
	}
}

PHP endpoint to upload file

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);
?>

Extract content from link embeds

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,
        }
    }
}

PHP endpoint to extract content from the remote file

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);
?>

Save Editor content to the database

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)
	});
}

PHP code to save Editor.js data

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();
    }
}
?>

View DemoDownload

Vincy
Written by Vincy, a web developer with 15+ years of experience and a Masters degree in Computer Science. She specializes in building modern, lightweight websites using PHP, JavaScript, React, and related technologies. Phppot helps you in mastering web development through over a decade of publishing quality tutorials.

Leave a Reply

Your email address will not be published. Required fields are marked *

↑ Back to Top

Share this page