DEV Community

Cover image for Let’s Develop an Online Code Editor/Compiler Like HackerRank
Nil Madhab
Nil Madhab

Posted on • Edited on

49 4

Let’s Develop an Online Code Editor/Compiler Like HackerRank

In this article, I will explain how I made my own online compiler using open-source code.

Here I will make one editor that supports 3 languages; C++, Java, and Python.

Adding more languages is also very simple.
Alt Text

Overview

Building an online code editor and compiler can seem too complicated, but we can break it down into two pieces.

  1. API running on the backend server, which will take a piece of code and language as input and output the answer after running the code on the server
  2. Frontend code editor, we can choose the language and edit and modify the code here. Then we make a post request to the backend API and show output on the website

Tutorials in this Series

  1. Deploy our Online Code Executor in Google Cloud
  2. Understanding the API of Judge0
  3. Creating an online code editor front-end (this tutorial)

Demo

This is the webpage we are going to build.

you can find the live demo here

Online code editor demo

FrontEnd

Our frontend is pretty simple. We have one drop-down menu where we can select the language and depend upon the language we will get our respective code editors. Our main code lies in the home-page.html and the code-editor resides in the texteditor.js.

Here we have made one onClickListener for dropdown menu items. So when one item is clicked, the corresponding listener gets triggered and we can call our desired editors. All the languages have different id associated with it . The list can be found using this.

The home-page looks like this.
Alt Text
The home-page html code is given below.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Home Page</title>
<link rel="stylesheet" type="text/css" href="assets/css/style.css" />
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
crossorigin="anonymous"
/>
<style type="text/css" media="screen">
body {
overflow: hidden;
}
#editor {
min-width: 500px;
min-height: 500px;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
src="src-noconflict/ace.js"
type="text/javascript"
charset="utf-8"
></script>
</head>
<body>
<div>
<h1>Code Editor</h1>
<select id="myselect" onchange="onSelectChange(this.value.trim())">
<option value="53" >C++</option>
<option value="62" >Java</option>
<option value="70">Python</option>
</select>
<div id="editorContainer">
<div class="container" style="margin-top: 30px">
<div class="row">
<div class="col">
<pre id="editor">
</pre
>
</div>
<div class="col">
<button class="btn btn-success">Execute</button>
<br />
<pre id="ans"></pre>
</div>
</div>
</div>
</div>
</div>
<script src="texteditor.js"></script>
<script>
function onSelectChange(selectedVal){
console.log(selectedVal)
if(selectedVal != undefined && selectedVal!=null && selectedVal!=""){
$("button").off('click');
codeEditor(selectedVal)
}
}
window.onload = function () {
codeEditor("53");
};
</script>
</body>
</html>
view raw home_page.html hosted with ❤ by GitHub

Here we call the codeEditor function of the javascript file , we pass the respective id associated with the language.

We add the style from assets/css/style.css .

body {
display: flex;
flex-direction: column;
align-items: center;
font-family: sans-serif;
color: black;
margin-top: 50px;
}
#myselect {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: 100%;
max-width: 400px;
padding: 6px 12px;
border-radius: 4px;
border: 1px solid #cbd1d8;
font-size: 1rem;
line-height: 1.5;
background: #fff url(../img/down.svg) no-repeat center right 12px / 18px 18px;
transition: all .2s ease-in-out;
}
.myselect::-ms-expand {
display: none;
}
.myselect:focus {
outline: 0;
border-color: #7bbaff;
box-shadow: 0 0 0 3px rgba(0, 121, 250, .3);
}
h1 {
font-size: 1.5rem;
}
view raw style.css hosted with ❤ by GitHub

Also we need to link the javascript file so that the code can be executed. We get the lang_id from the html and do the network call accordingly. For java code is 62, cpp 53 and python 70. This is passed in language_id . We also set default values to the editor depending on the lang_id.
const JAVA_KEY = "62";
const CPP_KEY = "53";
const PYTHON_KEY = "70";
const BASE_URL = "http://34.72.83.62/submissions"
function codeEditor(lang_id) {
var editor = ace.edit("editor");
editor.setTheme("ace/theme/twilight");
console.log("id" + lang_id )
$(document).ready(function () {
$("button").click(function () {
let code = editor.getValue();
$("#ans").html("Loading...");
console.log(code);
let data = {
source_code: code,
language_id: lang_id,
number_of_runs: "1",
stdin: "Judge0",
expected_output: null,
cpu_time_limit: "2",
cpu_extra_time: "0.5",
wall_time_limit: "5",
memory_limit: "128000",
stack_limit: "64000",
max_processes_and_or_threads: "60",
enable_per_process_and_thread_time_limit: false,
enable_per_process_and_thread_memory_limit: false,
max_file_size: "1024",
};
console.log(data)
let request = $.ajax({
url: BASE_URL,
type: "post",
data: data,
});
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
// Callback handler that will be called on success
request.done(async function (response, textStatus, jqXHR) {
// Log a message to the console
console.log("Hooray, it worked!");
let token = response.token;
await new Promise((resolve) => setTimeout(resolve, 5000)); // 5 sec
let second_request = $.ajax({
url: BASE_URL + "/"+ token,
type: "get",
});
second_request.done(function (response) {
console.log(response.stdout);
$("#ans").html(response.stdout);
});
});
});
});
if(lang_id==PYTHON_KEY)
editor.setValue("def execute(): \n\t for i in range(10):\n\t\t print i \nexecute()")
//java
if(lang_id==JAVA_KEY){
let javacode = `public class Main{
public static void main(String args[]){
System.out.println("hello");
}
}
`;
editor.setValue(javacode)
}if(lang_id==CPP_KEY){
let cppcode = `#include <iostream>
using namespace std;
int main() {
cout<<"Hello World"; \n
}`
editor.setValue(cppcode)
}
}
view raw texteditor.js hosted with ❤ by GitHub

On execution of code it should show like this.
Alt Text

The entire code can be found in the following repository.

Ace (Ajax.org Cloud9 Editor)

CDNJS npm

Ace is a code editor written in JavaScript.

This repository has only generated files. If you want to work on ace please go to https://github.com/ajaxorg/ace instead.

here you can find pre-built files for convenience of embedding. it contains 4 versions

  • src concatenated but not minified
  • src-min concatenated and minified with uglify.js
  • src-noconflict uses ace.require instead of require
  • src-min-noconflict concatenated, minified with uglify.js, and uses ace.require instead of require

For a simple way of embedding ace into webpage see editor.html or list of other simple examples To see ace in action go to kitchen-sink-demo, scrollable-page-demo or minimal demo,




Top comments (3)

Collapse
 
limitcracker profile image
Ioannis Gyftakis

Hi, how we could also make Run Test feature in order to check for the solution?

Collapse
 
tel profile image
Taha Elkarroumy

How to accept input from the user

Collapse
 
shubhanshu2000 profile image
shubhanshu2000 • Edited

Use post method

nextjs tutorial video

📺 Youtube Tutorial Series

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay