DEV Community

Cover image for How to Build Interactive CodePlay App with Real-time Output
Dauda Lawal
Dauda Lawal

Posted on

How to Build Interactive CodePlay App with Real-time Output

In this tutorial, we will create an interactive web application called CodePlay App using HTML, CSS, JavaScript, Bootstrap, and jQuery. This application allows users to write code in HTML, CSS, and JavaScript and see the output in real-time within an embedded iframe.

We'll focus on implementing smooth animations, responsive design, and seamless code editing capabilities.

Prerequisites

To follow along with this tutorial, you should have basic knowledge of HTML, CSS, JavaScript, Bootstrap, and jQuery. Make sure you have a text editor and a modern web browser installed.

Project Setup

  1. Create Project Structure:

    • Create a new directory for your project (codeplay-app).
    • Inside this directory, create subdirectories for css and javascript.
    • Create an index.html file in the root directory.
  2. Include Required Libraries:

    • Download Bootstrap CSS and include it in the css directory.
    • Include jQuery library from a CDN in your index.html.
    • Create a main.js file in the javascript directory for your application logic.

HTML Structure

<!doctype html>
<html lang="en">
<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>CodePlay App</title>
  <link href="css/bootstrap.css" rel="stylesheet">
  <link href="css/style.css" rel="stylesheet">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js" defer></script>
  <script src="javascript/main.js" type="text/javascript" defer></script>
</head>
<body>
  <header>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
      <a class="navbar-brand" href="#">CodePlayer</a>
      <div class="ml-lg-5 btn-group btn-group-sm" role="group">
        <button type="button" id="html" class="btn btn-secondary active">HTML</button>
        <button type="button" id="css" class="btn btn-secondary">CSS</button>
        <button type="button" id="javascript" class="btn btn-secondary">JavaScript</button>
        <button type="button" id="output" class="btn btn-secondary active">Output</button>
      </div>
      <button class="navbar-toggler mt-sm-0 mt-2" type="button" data-toggle="collapse"
        data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false"
        aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav ml-auto">
          <li class="nav-item mr-2">
            <a class="nav-link" href="https://www.linkedin.com/in/daslaw26/">About Me</a>
          </li>
          <li class="nav-item mr-2">
            <a class="nav-link" href="https://github.com/Daslaw/codePlayer.git">DaslawCodePlayer</a>
          </li>
        </ul>
      </div>
    </nav>
  </header>
  <main class="container-fluid">
    <div class="row" id="bodyContainer">
      <textarea id="htmlPanel" class="col panel"><p>Hello world!</p></textarea>
      <textarea id="cssPanel" class="col panel hidden">/* Enter your css code here! */</textarea>
      <textarea id="javascriptPanel" class="col panel hidden">/* Enter your JS code here! */</textarea>
      <iframe id="outputPanel" class="col panel">Hello world!</iframe>
    </div>
  </main>
  <!-- Optional JavaScript; choose one of the two! -->
  <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
    integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
    crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx"
    crossorigin="anonymous"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

CSS Styling

The CSS file (style.css) defines styles for the application, including layout and panel visibility.

*,
*::before,
*::after {
  margin: 0;
  padding: 0;
}

.inlineMenu {
  display: inline;
}

.active {
  background-color: green !important;
}

.hidden {
  display: none;
}

.panel {
  resize: none;
  border: none;
  outline: none;
  border-top: 1.3px solid grey;
  transition: opacity 0.5s ease-in-out;
}

.panel:not(:last-child) {
  border-right: 1.3px solid grey;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.fadeIn {
  animation: fadeIn 0.5s;
}
Enter fullscreen mode Exit fullscreen mode

JavaScript Functionality

The JavaScript file (main.js) handles dynamic behavior, including updating the output panel and managing panel visibility based on screen size.

$(document).ready(function () {

    $(".panel").height($(window).height() - $("header").height() - 10);

    function updateOutput() {
        $("iframe").contents().find("html").html("<html><head><style type='text/css'>" +
            $("#cssPanel").val() + "</style></head></body>" + $("#htmlPanel").val() + "</body></html>");

        document.getElementById("outputPanel").contentWindow.eval($("#javascriptPanel").val());
    }

    updateOutput();
    $("textarea").on('change keyup paste', function () {
        updateOutput();
    });

    function hideAllPanel() {
        $(".btn-group").children().removeClass("active");
        $("#bodyContainer").children().addClass("hidden");
    }

    function mediaChange() {
        if (mobileScreen.matches) {
            //for small screen devices (max-width: 500px)
            hideAllPanel();
            $(".btn-group").children(":first-child").addClass("active");
            $("#bodyContainer").children(":first-child").removeClass("hidden");

            $(".btn-group").children().off("click");
            $(".btn-group").children().click(function () {
                hideAllPanel();
                $(this).toggleClass("active");
                let panelId = $(this).attr("id") + "Panel";
                $("#" + panelId).toggleClass("hidden");
            });
        }
        else if (tabScreen.matches) {
            //for medium screen devices (max-width: 800px)
            hideAllPanel();
            $(".btn-group").children(":first-child").addClass("active");
            $("#bodyContainer").children(":first-child").removeClass("hidden");
            $(".btn-group").children(":last-child").addClass("active");
            $("#bodyContainer").children(":last-child").removeClass("hidden");

            let activePanel = ["html", "output"];

            $(".btn-group").children().off("click");
            $(".btn-group").children().click(function () {
                let thisID = $(this).attr("id");

                if (this.matches(".active")) {
                    //when user clicks on active panel button...
                    $(this).toggleClass("active");
                    let panelId = $(this).attr("id") + "Panel";
                    $("#" + panelId).toggleClass("hidden");

                    if (thisID != activePanel[0])
                        activePanel[1] = activePanel[0];

                    activePanel[0] = null;
                }
                else {
                    //when user clicks on inactive(hidden) panel button...
                    let selectPanel = activePanel.shift();
                    $("#" + selectPanel + "Panel").toggleClass("hidden");
                    $("#" + selectPanel).toggleClass("active");

                    $(this).toggleClass("active");
                    let panelId = $(this).attr("id") + "Panel";
                    $("#" + panelId).toggleClass("hidden");

                    activePanel.push(thisID);
                }
            });
        }
        else {
            //for other screens...
            $(".btn-group").children().off("click");
            $(".btn-group").children().click(function () {
                $(this).toggleClass("active");
                let panelId = $(this).attr("id") + "Panel";
                $("#" + panelId).toggleClass("hidden");
            });
        }
    }

    //media queries; on Screen change.
    var mobileScreen = window.matchMedia("(max-width: 500px)");
    var tabScreen = window.matchMedia("(max-width: 800px)");

    mediaChange();
    tabScreen.addEventListener("change", mediaChange);
    mobileScreen.addEventListener("change", mediaChange);

});
Enter fullscreen mode Exit fullscreen mode

Live Demo and Repository

Conclusion

Congratulations! You have successfully built a CodePlay App that allows users to write and preview HTML, CSS, and JavaScript code in real-time with smooth animations and responsive design for optimal usability across different devices.

Happy coding!

Top comments (0)