Build a Vanilla JavaScript + NodeJS GUI Content Tool

In this lesson we will use HTML, CSS, Vanilla JavaScript, and NodeJS to create a GUI content tool that creates HTML files.

Video Tutorial: Build a Vanilla JavaScript + NodeJS GUI Content Tool

YouTube Tutorial: Build a Vanilla JavaScript + NodeJS GUI Content Tool

GUI Content Tool File Structure

The file structure is how you organize the files in your website. Here is our project's file structure:

Mouse Hover over the blue text in the description to highlight.

content_gui
  files
  static
    index.html
    style.css
    maker.js
  main.js

➼ Main Project Folder

➼ files - This is the folder where the HTML files that our application creates are stored.

➼ static - This is the folder containing our front end files: index.html, style.css, maker.js

➼ index.html - This is the main page users will be directed to when entering your web address. HTML is the markup language that displays your content in the web browser. This file contains the user forms for entering content.

➼ style.css - CSS formats HTML: color, size, shape, font ect.

➼ maker.js - This file contains our front end JavaScript code.

➼ main.js - This file contains our back end JavaScript code (NodeJS + ExpressJS).

CSS

Our GUI Content Tool uses a little bit of CSS. Click here for CSS tutorials.

Click here to learn about the responsive CSS used in this tutorial..

Project Code

index.html

<html>
  <head>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta charset="UTF-8">
  <link rel='stylesheet' type='text/css' href='style.css'>
  <meta charset="UTF-8">
  <title>My GUI Content Tool</title>
  </head>
  <body>
  <h1>My Content Tool</h1>
    <div class="myForm">
          <textarea class="consoleText" id="content" name='content' rows='4' cols='50' spellcheck='true' placeholder="type..."></textarea>
          <br>
          <label for="content_type">Content Type:</label><br>
         <select class="greenBut" id="content_type" name="content_type">
         <!-- User's makes selection-->
           <option value="paragraph">Paragraph<br>
           <option value="console">Console Text<br>
           <option value="bordered">Bordered<br>
         </select><br><br>
         <button class="greenBut" onclick="addThis()" id="addThat">Add To Code</button>
    </div>
    <br><br>
         <form class="myForm" action="/page" method="post">
           File Name:<br>
           <input name="file" type="text" spellcheck="true" required><br><br>
           Code Preview:<br>
           <textarea rows="10" columns="40" class="consoleText" name="myPage" id="myPage" type="text"></textarea><br><br>
           <input class="greenBut" type='submit' id="type" value='Create Page'>
         </form>
         <script src="maker.js"></script>
  </body>
</html>

style.css

/* Element sizing includes padding and border*/
* {
    box-sizing: border-box;
}
/* "row class" */
.row::after {
    content: "";
    clear: both;
    display: table;
}
/* Columns containing "col-"*/
[class*="col-"] {
    float: left;
    padding: 15px;
}
/* Column size for small devices (phones)*/
[class*="col-"] {
    width: 100%;
}
/* Column size for large devices (computers)*/
@media only screen and (min-width: 768px) {
    /* For Large Devices*/
    .col-1 {width: 8.33%;}
    .col-2 {width: 16.66%;}
    .col-3 {width: 25%;}
    .col-4 {width: 33.33%;}
    .col-5 {width: 41.66%;}
    .col-6 {width: 50%;}
    .col-7 {width: 58.33%;}
    .col-8 {width: 66.66%;}
    .col-9 {width: 75%;}
    .col-10 {width: 83.33%;}
    .col-11 {width: 91.66%;}
    .col-12 {width: 100%;}
}

input {
  background: black;
  color: #35E309;
  border-radius: 6px;
  border: none;
}


.greenBut {
  background-color: #39DB18;
  color: black;
  font-size: 14px;
  border-radius: 9px;
  border-color: black;
  font-weight: bold;
  padding: 5px;
}

input.greenBut{
  border-style: solid;
  border-width: 1px;
  border-color: black;

}

.greenBut:hover{
  background-color: black;
  color: #39DB18;
  border-color: #39DB18;
}
/* Page Body*/
body {
  color: #ededed;
  background-color: black;
  color: black;
  font-family: helvetica, arial, sans-serif;
  font-size: 16px;
}

/* Header Image*/
img.topImage {
  max-width: 150px;
  float: left;
}

body a{
  color:red;
  font-weight: bold;
  text-decoration: none;
}

body a:hover{
  color:white;
  background:black;
}

/* Question labels*/
.redLabel {
  color: darkred;
  font-size: 16px;
  font-weight:800;
}

h1{
  color: #35E309;
  text-align: center;
  border-radius: 9px;
  background-color: black;
}
/*Form class*/
.myForm {
  color: #DBFA9E;
  padding-left: 15px;
  border: none;
  padding-bottom: 15px;
  background-color: #2F3638;
  padding:25px;
  border-radius: 9px;
}



form {
  border-style: double;
  border-color: red;
  border-width: 1px;
  color:black;
  padding-left: 15px;
  padding-bottom: 15px;
  background-color: #ededed;
  padding:25px;
  border-radius: 9px;
}


.section{
  padding: 5px;
  border-color: grey;
  border-style: groove;
  border-width: 1px;
  border-radius: 9px;
}

.textType
{
  background: transparent;
  width: auto;
  align: center;
  border: none;
}

.label1{
  font-size: 10px;
}

.consoleText{
  background-color: black;
  color: #35E309;
  line-height: 1.5;
  font-family: "Ubuntu Mono","Lucida Console",monospace;
  border-radius: 9px;
  width: 90%;
  font-size: 16px;
}

maker.js

function addThis () {
  let content = document.getElementById("content").value;
  let contentType = document.getElementById("content_type").value;
  let returnValue =  makeHTML(content, contentType);
  document.getElementById("myPage").value += returnValue;
  document.getElementById("content").value = "";
}

function makeHTML(content,type){
   let toReturn = "";
   switch (type) {
     case "paragraph":
       toReturn = "<p>" + content + "</p>";
       break;
     case "console":
       toReturn = "<div class='consoleText'>" + content + "</div>";
       break;
     case "bordered":
       toReturn = "<div class='bordered'>" + content + "</div>";
       break;
     default:
       toReturn = content;
   }
   return toReturn;
 };

main.js

// variables
var express = require('express');
//var redirect = require("express-redirect");
var fs = require("fs");
var bodyParser = require('body-parser');


var app = express(); // express application
app.use(bodyParser.urlencoded({ extended: false }));

// HTML
var preData = '<!DOCTYPE html><html><!-- Page Head:Contains information for the web browser to read --><head><meta name="google-site-verification" content="bMAKd8Xm3F7Ouc_P8g-pfDvu4JAAMyU6eoPP7WfwUVo"/><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta charset="UTF-8"><!-- Title:Max 50-60 character including spaces --><title>Coding Commanders Computer Science Tutorials</title><meta name="keywords" content="coding, commanders, coding commanders, computer science tutorials, computer science, tutorials, commander candy"><meta name="description" content="Commander Commanders provides free beginner friendly computer science tutorials.  Your journey starts here! Descrete Mathematics, Linux, PHP, SQL, NodeJS and so much more!"><!-- CSS Links --><!-- Our CSS File --><link rel="stylesheet" type="text/css" href="style.css"><!-- Fontawesome Librbary --><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous"><!-- Google Font Link--><link href="https://fonts.googleapis.com/css?family=Share+Tech&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css?family=Ubuntu+Mono&display=swap" rel="stylesheet"><style>.contentBox a:hover{opacity:.5}</style></head><!-- Page Body:Contains information to display to site users and JavaScript --><body><div="row"><div id="menu" class="col-3"><div class="sidenav" id="sidenav"><a href="https://www.codingcommanders.com">Home</a><h3>Language Tutorials</h3><a href="https://www.codingcommanders.com/godot">GDScript(Godot)</a><a href="https://www.codingcommanders.com/nodejs">NodeJS+Postgres</a><a href="https://www.codingcommanders.com/html">HTML</a><a href="https://www.codingcommanders.com/css">CSS</a><a href="https://www.codingcommanders.com/php">PHP</a><a href="https://www.codingcommanders.com/javascript">JavaScript</a><a href="https://www.codingcommanders.com/reactVRMain.php">ReactJS VR</a><h3>Linux</h3><a href="https://www.codingcommanders.com/linux">Linux Tutorials</a><a href="https://www.codingcommanders.com/LAMP">LAMP Stack Tutorials</a><a href="https://www.codingcommanders.com/twitch">Linux Open Source Streamer</a><a href="https://www.codingcommanders.com/linux-gaming/">Linux Gaming Blog</a><h3>Mathematics</h3><a href="https://www.codingcommanders.com/logic.php">Logic</a><h3>Projects</h3><a href="https://www.codingcommanders.com/randomjs">JavaScript Random Number Generator</a><a href="https://www.codingcommanders.com/dice">JavaScript Dice game</a><a href="https://www.codingcommanders.com/website-builder">Static Website</a><a href="http://www.codingcommanders.com/nodejs/fsfile_project.php">NodeJS CLI File Program</a><a href="https://www.codingcommanders.com/random/">Express NodeJS Random Number Generator</a><a href="https://www.codingcommanders.com/htmlMatFiles/responsive2M.php">Responsive Form Template</a><h3>More!</h3><a href="https://www.codingcommanders.com/battlecards">Battle Card RPG</a><a href="https://www.codingcommanders.com/blog">Tech Blog</a><a href="http://www.palmbeachtechie.com/" target="blank">Palm Beach Techie</a><a href="https://www.twitch.tv/daisychaincosplay" target="blank">Twitch Channel</a><a href="https://www.youtube.com/codingcommanders" target="blank">YouTube Channel</a><h3>Support</h3><a href="https://streamlabs.com/daisychaincosplay/tip" target="blank">Twitch Donations</a><a href="http://codingcommanders.storenvy.com/" target="blank">T-Shirt Shop</a><a href="https://donorbox.org/18be1a20-283d-414d-bae0-fbf1d7c101db" target="blank">DonorBox</a></div><div align="center"><a href="https://www.twitch.tv/daisychaincosplay" target="blank"><img class="content-image" src="/battlecards/pics/twitch-follow.gif" alt="daisychaincosplay LIVE on Twitch"/></a><br><br><a href="http://codingcommanders.storenvy.com/" target="blank"><img src="linux-gaming/media/linux-side/linux-tshirt.jpg" target="blank" alt="Coding Commanders T-shirt Shop"/></a></div><br><br></div><div class="col-9"><div class="row"><div class="header"><div class="col-5"><button onclick="mobileMenu" id="menu-link" class="mobile-menu"><i class="fas fa-bars"></i></button><button onclick="hideMenu" id="hide" class="hide"><i class="fas fa-window-close"></i></button><div id="menu-display"></div><img class="logo" src="http://www.codingcommanders.com/coding_commanders_logo.png" alt="Daisy Chain Cosplay Twitch Channel"/></div><div class="col-5"><h1>Computer Science Tutorials+Tech Blog</h1></div></div></div><div class="row social" align="center"><a target="blank" href="https://www.twitch.tv/daisychaincosplay"><i class="fab fa-twitch"></i></a><a target="blank" href="https://www.youtube.com/channel/UC-gCUMK_EGUqJ7P9VA7BJmQ"><i class="fab fa-youtube"></i></a><a target="blank" href="https://twitter.com/codingCommander"><i class="fab fa-twitter"></i></a><a target="blank" href="https://www.facebook.com/codingcommanders/"><i class="fab fa-facebook"></i></a><a target="blank" href="https://www.instagram.com/codingcommanders"><i class="fab fa-instagram"></i></a><a target="blank" href="https://social.tchncs.de/@codingcommanders"><i class="fab fa-mastodon"></i></a><a href="https://discordapp.com/invite/AeUvu7v" target="blank"><i class="fab fa-discord"/></i></a></div>';

var postData = '</div><!-- Page Footer--><footer><div class="copyright">©copyright 2020 Coding Commanders </div></footer></div><script language="JavaScript" src="twitch/main.js"></script><script>(function(i,s,o,g,r,a,m){i["GoogleAnalyticsObject"]=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,"script","https://www.google-analytics.com/analytics.js","ga");ga("create","UA-99741636-1","auto");ga("send","pageview");</script></body></html>';
function htmlFile(file,data,response)  {
  var name = "files/" + file + ".html";
  var content = preData + data + postData;
  fs.writeFile(name, content, function (err) {
    if (err) {
      throw err;
      response.send(err);
    }
    else {
      response.send(' File Saved! Location: ' + name +') Notes: ');
    }
  });
};

// static directory
app.use(express.static('static'))

// Home Page: index.html
app.get('/', (req, res) => {
  res.sendFile('./static/index.html');
});

// create page
app.get('/page', (req, res) => {
  res.sendFile(__dirname + '/static/index.html');
});

app.post('/page', function(req, response){
  var file = req.body.file;
  var content = req.body.myPage;
  htmlFile(file,content,response);
});

port = 3000;

app.listen(port, (err) => {
  console.log(`The magic happens on port: ${port}`);
});

Complete Another Project