Grammarly — Spell Checker using Vanilla JavaScript
By: Hitesh Kumar
Tags: Spell Check, JavaScript, Javascript Development

Now, lets start with a simple html page, where user will be asked to input the file.

index.html

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Grammarly</title>

<link rel="stylesheet" type="text/css" href="style.css">

</head> <body>

<center><h1 id="title">Spell Checker</h1></center>

<div class="container">

<div class="row">

<input type="file" name="inputfile" id="inputfile">

<button onclick="readData()">Upload</button>

<br><br>

<pre id="filecontent"></pre>

<menu id="contextMenu" class="context-menu"></menu>

</div>

</div>

</body>

<script src="script.js"></script>

</html>

Here we have linked our style.css file we will be making that later. Lets see what we have done here. We have made a form , asking user to input a file and we have a button to upload it. When the user will click the upload button, we are gonna display the whole content of the text file inside our pre tag. And there is a menu tag as well, if there is any typo we will inject the suggestions in it. And finally we are calling our script file for all the functionality. Lets jump over the fun part. The javaScript.

script.js

Lets do it in a step by step way. First thing first we need to read the whole data of the file. To do this we will use something called FileReader.

function readData(files){

let file = inputfile.files[0];

let reader = new FileReader();

reader.readAsText(file);

reader.onload = async function(){

filecontent.innerHTML = await reader.result;

getCheck(reader.result); //Calling our func for typo

}

}

So we are getting the files array and reading the first file and then when we are done with reading, we will use this data to check any typo. Now lets write getCheck() Method to check for all the typo in the file.



async function getCheck(data){

let url = "

let response = await fetch(url);

if(response.ok){

spell = await response.json();

for(let item of spell.response.errors){

highlight(item.bad);

}

}

} let spell;async function getCheck(data){let url = " https://api.textgears.com/grammar?key=wF4nKAm0SzmgBeEd&text= "+data;let response = await fetch(url);if(response.ok){spell = await response.json();for(let item of spell.response.errors){highlight(item.bad);

So what we did here is we are using a third party API for checking any typo. We are calling the API and getting the response. Our response have have a field called errors. This will include all the errors. We will loop through each errors and highlight them by calling our highlight().

function highlight(text) { var inputText = document.getElementById("filecontent").innerHTML

var index = inputText.indexOf(text); //If we found an index i.e != -1, then we will apend span for that typo

if (index >= 0) {

inputText = inputText.substring(0,index) + "<span class='highlight'>" + inputText.substring(index,index+text.length) + "</span>" + inputText.substring(index + text.length);

document.getElementById("filecontent").innerHTML = inputText;

}

}

Here we are searching the typo word in the whole file and if we found such word we are just injecting a span tag with class highlight in it.

Now we are almost done we have to add last functionality suggestions. Whenever user right click on any typo word, he/she should get suggestions. We don’t have right click eventListener as such so will use contextMenu.

document.oncontextmenu = rightClick;

document.onclick = hideMenu; //For Hiding the contextMenu

function hideMenu() {

document.getElementById("contextMenu").style.display = "none";

}

So here we have add listener on rightClick event. And if user single click then we have to hide our suggestions. Now lets write our last rightClick() method.

//Whenever user right click

function rightClick(e) {

e.preventDefault(); if(e.path.length == 7) return; // If user click on correct word we will simply return var wrongWord = e.path[0].innerHTML // This is our current wrong word, where user right clicked var errorWords = spell.response.errors; // This is the complete array of wrong words in the paragraph var list = document.createElement("div"); // Created an

list.style.backgroundColor = '#c0cccf';

list.style.width = '100px'; for(let i = 0; i<errorWords.length; i++){

if(errorWords[i].bad == wrongWord) {

// Remove any previous child if it exist, from the context MEnu

const parent = document.getElementById('contextMenu')

while (parent.firstChild) {

parent.firstChild.remove()

} // Generate a list of all the suggestions

for(let j = 0; j < errorWords[i].better.length; j++ ){ // Create a li and append suggestion

var li = document.createElement("li");

li.innerText = errorWords[i].better[j]; //If user click on suggestion , remove highlight class

li.addEventListener('click', (ev) => {

e.path[0].innerHTML = ev.path[0].innerHTML;

e.path[0].classList.remove('highlight')

}) // Append it to our list

list.appendChild(li);

list.style.listStyleType = "none";

}

document.getElementById('contextMenu').appendChild(list);

console.log(document.getElementById('contextMenu'))

}

} if (document.getElementById("contextMenu").style.display == "block") hideMenu(); else {

var menu = document.getElementById("contextMenu")



menu.style.display = 'block';

menu.position = "absolute";

menu.style.left = e.clientX + "px";

menu.style.top = e.clientY + "px";

}

}

Let me break this big code for you. Here what we are doing is if user right click on any correct word we will simply return. But if he rightclick on any typo then we will proceed further. We will check all the typo word and see which one on the user clicked . Once we will get that word, then we will simply create a menu and append all the suggestions corresponding to that typo.

That’s it we are done. We have successfully made this awesome spell checker.

Github : https://github.com/HiteshBucky/spellchecker