Build a HTML5 CSS3 and Javascript Code Editor with Live Preview in Browser Using Vanilla Javascript Full Project For Beginners

You are currently viewing Build a HTML5 CSS3 and Javascript Code Editor with Live Preview in Browser Using Vanilla Javascript Full Project For Beginners

 

Welcome folks today in this blog post we will be building a html5 css3 and javascript code eidtor with live preview in browser using vanilla javascript.All the full source code of the application is shown below.

 

 

 

Get Started

 

 

 

In order to get started you need to make an index.html file and copy paste the following code

 

 

index.html

 

 

 

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
<style>
  .box {
  position: relative;
  background: #ffffff;
  margin-bottom: 20px;
  width: 100%;
}
.box.collapsed-box .box-body,
.box.collapsed-box .box-footer {
  display: none;
}
.box .nav-stacked > li {
  margin: 0;
}
.box .nav-stacked > li:last-of-type {
  border-bottom: none;
}
.box.height-control .box-body {
  max-height: 300px;
  overflow: auto;
}
.box.box-solid {
  border-top: 0;
}
.box.box-solid > .box-header .btn.btn-default {
  background: transparent;
}
.box.box-solid > .box-header .btn:hover,
.box.box-solid > .box-header a:hover {
  background: rgba(0, 0, 0, 0.1);
}
.box.box-solid > .box-header > .box-tools .btn {
  border: 0;
  box-shadow: none;
}
.box.box-solid[class*='bg'] > .box-header {
  color: #fff;
}
.box .box-group > .box {
  margin-bottom: 5px;
}
.box .knob-label {
  text-align: center;
  color: #333;
  font-weight: 100;
  font-size: 12px;
  margin-bottom: 0.3em;
}
.box-pm {
  border: solid 1px #ccc;
  border-radius: 0;
}
.box-pm .box-header {
  color: #444;
  display: block;
  padding: 10px;
  position: relative;
  padding-bottom: 0;
}
.box-pm .box-header .btn {
  border-radius: 0;
  position: absolute;
  height: 28px;
  padding: 0 10px !important;
  line-height: 25px;
  margin: auto;
  top: -1px;
  bottom: 0;
  right: 10px;
}
.box-pm .box-header:after {
  content: "";
  display: block;
  padding-top: 9px;
  border-bottom: solid 1px #ccc;
}
.hideme {
  visibility: hidden;
  position: absolute;
  width: 0;
  height: 0;
}
#promo-css-editor,
#promo-html-editor,
#promo-js-editor {
  position: relative;
  height: 250px;
  width: 100%;
}
.box-body {
  padding: 10px;
  border-radius: 0 0 3px 3px;
}
.preview-options-wrapper {
  display: flex;
}
@media screen and (max-width: 768px) {
  .preview-options-wrapper {
    flex-direction: column;
  }
}
.preview-options-wrapper .preview-options {
  display: flex;
  align-items: center;
}
@media screen and (min-width: 768px) {
  .preview-options-wrapper .preview-options {
    flex-grow: 1;
    margin-right: 15px;
  }
  .preview-options-wrapper .preview-options:last-child {
    margin: 0;
    flex-grow: 0;
  }
}
@media screen and (max-width: 768px) {
  .preview-options-wrapper .preview-options {
    margin-bottom: 10px;
  }
  .preview-options-wrapper .preview-options:last-child {
    margin: 0;
  }
}
.preview-options-wrapper .preview-options label {
  margin-right: 10px;
  margin-bottom: 0;
}
.preview-options-wrapper .preview-options .preview-icon {
  width: 34px;
  height: 34px;
  line-height: 34px;
  text-align: center;
  border: solid 1px #ccc;
  margin: 0 5px;
  display: inline-block;
  cursor: pointer;
  transition: all .5s ease;
}
.preview-options-wrapper .preview-options .preview-icon.active {
  background-color: #00c0ef;
  color: #fff;
  border-color: #00c0ef;
}
.preview-options-wrapper .preview-options.device .preview-icon {
  font-size: 18px;
}
.preview-option-wrapper {
  width: 100%;
  position: relative;
}
.preview-option-wrapper:before,
.preview-option-wrapper:after {
  content: " ";
  display: table;
}
.preview-option-wrapper:after {
  clear: both;
}
.preview-option-wrapper .preview {
  display: block;
  border: solid 0px #313039;
  border-radius: 0;
}
.preview-option-wrapper .preview::after,
.preview-option-wrapper .preview::before {
  content: "";
  height: 0px;
  width: 0px;
  transform: all .5s;
}
.preview-option-wrapper .preview.center {
  margin: auto;
}
.preview-option-wrapper .preview.mobile {
  overflow: auto;
  border-width: 40px 15px 70px 15px;
  border-radius: 25px;
  transition: all .5s ease;
}
.preview-option-wrapper .preview.mobile::after,
.preview-option-wrapper .preview.mobile::before {
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
  background-color: #fff;
}
.preview-option-wrapper .preview.mobile::after {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  bottom: 15px;
}
.preview-option-wrapper .preview.mobile:before {
  width: 80px;
  height: 5px;
  top: 17.5px;
  border-radius: 10px;
}
.preview-option-wrapper .preview.tab {
  overflow: auto;
  border-width: 25px 15px 60px 15px;
  border-radius: 25px;
  transition: all .5s ease;
}
.preview-option-wrapper .preview.tab::before {
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
  background-color: #fff;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  bottom: 15px;
}
.preview-option-wrapper .preview.laptop {
  overflow: auto;
  width: auto !important;
  margin: 0 15px 40px 15px;
  border-width: 15px;
  border-radius: 10px;
  transition: all .5s ease;
}
.preview-option-wrapper .preview.laptop::after,
.preview-option-wrapper .preview.laptop::before {
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
  background-color: #fff;
}
.preview-option-wrapper .preview.laptop::after {
  width: 100%;
  height: 40px;
  border-bottom-left-radius: 30px;
  border-bottom-right-radius: 30px;
  bottom: -5px;
  background-color: #555;
}
.preview-option-wrapper .preview.laptop:before {
  width: 10px;
  height: 10px;
  top: 2.5px;
  border-radius: 5px;
}
.preview-option-wrapper .preview::-webkit-scrollbar {
  width: 3px;
  background-color: #666;
}
.preview-option-wrapper .preview::-webkit-scrollbar-thumb {
  width: 3px;
  background-color: #fff;
}
.form-control {
  border-radius: 0;
}
.modal-backdrop {
  background-color: rgba(0, 0, 0, 0.4);
}
.modal {
  visibility: hidden;
  background-color: transparent;
  display: block !important;
  transform: perspective(400px) scale(0.9) rotateX(-15deg) translateY(100%);
  opacity: 0;
  transition: all .5s ease;
}
.modal.in {
  transform: perspective(400px) scale(1) rotateX(0deg) translateY(0%);
  visibility: visible;
  opacity: 1;
}
.modal.style-1 .modal-header {
  background-color: #00c0ef;
  color: #fff;
}
.modal.style-1 .modal-header .close {
  opacity: .8;
  color: #Fff;
}
.modal.style-1 .footer {
  border-top: solid 1px #ccc;
  padding-top: 15px;
}
.modal-content {
  border-radius: 0;
}
.dnd-file-uploader .dnd-file-handler {
  width: 100%;
  border: solid 5px #ccc;
  height: 100px;
  font-size: 36px;
  text-align: center;
  line-height: 100px;
  color: #ccc;
  font-weight: bolder;
  cursor: pointer;
  margin-bottom: 15px;
}
.promo-images-wrapper {
  background-image: url(../img/photo1.png);
  background-size: cover;
  background-position: center center;
  height: 250px;
  padding: 10px;
  margin-bottom: 15px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.promo-images-wrapper .btn {
  border-radius: 0px;
  border: none;
}
.promo-images-wrapper .hover {
  text-align: center;
  padding: 10px 30px;
  background-color: #fff;
  transform: perspective(800px) rotateY(90deg);
  transition: all .5s ease;
}
.promo-images-wrapper .hover .promo-bg-options {
  min-height: 100px;
}
.promo-images-wrapper:hover .hover {
  transform: perspective(800px) rotateY(0deg);
  transition: all 0.8s cubic-bezier(0.43, 2.11, 0.59, 0.79);
}
.url .live-input {
  position: absolute;
  z-index: -1;
  opacity: 0;
}

</style>
<div class="container-fluid">

<div class="editor item active">
                                <div class="row">
                                    <div class="col-sm-4">
                                        <div class="box box-pm">
                                            <div class="box-header"><b>HTML</b> <div class="btn btn-info" data-toggle="modal" data-target="#choose-bg">Background</div></div>
                                            <div class="box-body">
                                                <div id="promo-html-editor" data-target="#promo-html"></div>
                                                <textarea class="hideme" id="promo-html" name="promo-html" data-type=".html"><div class="deal-content">
    <h1 class="title">Deals of the Day</h1>
    <h4 class="details">Toronto (YYZ) to Paris (CDG)</h4>
    <div class="price">C$ 15% OFF</div>
</div></textarea>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="col-sm-4">
                                        <div class="box box-pm">
                                            <div class="box-header"><b>CSS</b></div>
                                            <div class="box-body">
                                                <div id="promo-css-editor" data-target="#promo-css"></div>
                                                <textarea class="hideme" id="promo-css" name="promo-css" data-type="style">.preview {
    display:flex !important;
    flex-direction:column;
    justify-content:center;
}

.deal-content {
    text-align:center;
    background-color:rgba(12, 166, 220, 0.9);
    color:#fff;
    padding:15px 0px;
}

.deal-content .title{
    font-weight:bold;
    text-transform:uppercase;
    margin:0;
    line-height:1;
}
.deal-content .details {
    margin:30px 0px;
    font-weight:bold;
    line-height:1;
}

.deal-content .price {
    height:44px;
    line-height:44px;
    display:inline-block;
    padding:0 20px;
    background-color:#fff;
    color:rgb(12, 166, 220);
    font-size:18px;
    font-weight:bold;
    border-radius:30px;
}</textarea>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="col-sm-4">
                                        <div class="box box-pm">
                                            <div class="box-header"><b>JavaScript</b></div>
                                            <div class="box-body">
                                                <div id="promo-js-editor" data-target="#promo-js"></div>
                                                <textarea class="hideme" id="promo-js" name="promo-js" data-type="script"></textarea>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
<div class="preview-wrapper">
                                <div class="box box-pm">
                                    <div class="box-header">
                                        <div class="preview-options-wrapper">
                                            <div class="preview-options" data-css="width">
                                                <label>Width</label>
                                                <input type="number" class="form-control" id="preview-width">
                                            </div>
                                            <div class="preview-options" data-css="height">
                                                <label>Height</label>
                                                <input type="number" class="form-control" id="preview-height">
                                            </div>
                                            <div class="preview-options align">
                                                <label>Align</label>
                                                <span class="preview-icon" data-preview-align="pull-left">
                                                    <i class="fa fa-align-left"></i>
                                                </span>
                                                <span class="preview-icon" data-preview-align="center">
                                                    <i class="fa fa-align-center"></i>
                                                </span>
                                                <span class="preview-icon" data-preview-align="pull-right">
                                                    <i class="fa fa-align-right"></i>
                                                </span>
                                            </div>
                                          <div class="preview-options device">
                                                    <label>Devices</label>
                                                    <span class="preview-icon" data-preview-device="mobile">
                                                        <i class="fa fa-mobile-phone"></i>
                                                    </span>
                                                    <span class="preview-icon"  data-preview-device="tab">
                                                        <i class="fa fa-tablet"></i>
                                                    </span>
                                                    <span class="preview-icon" data-preview-device="laptop">
                                                        <i class="fa fa-laptop"></i>
                                                    </span>
                                                    <span class="preview-icon active" data-preview-device="">
                                                        <i class="fa fa-desktop"></i>
                                                    </span>
                                                </div>
                                        </div>
                                    </div>
                                    <div class="box-body">
                                        <div class="preview-option-wrapper">
                                            <div class="preview">
                                                <style></style>
                                                <div class="html"></div>
                                                <script></script>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
  
  
  <input type="text" class="hideme" name="promo-bg" id="promo-bg">
                            <!-- Modal -->
                            <div class="modal style-1" id="choose-bg" role="dialog">
                                <div class="modal-dialog modal-lg">
                            
                                    <!-- Modal content-->
                                    <div class="modal-content">
                                        <div class="modal-header">
                                            <button type="button" class="close" data-dismiss="modal">×</button>
                                            <h4 class="modal-title">Choose Background Image</h4>
                                        </div>
                                        <div class="modal-body">
                                            <div class="dnd-file-uploader">
                                                <input class="hideme" type="file" accept=".jpg,.png" name="promo-bg" id="promo-bg">
                                                <div class="dnd-file-handler">
                                                    DROP IMAGE OR CLICK ME
                                                </div>
                                            </div>
                                            <div class="row image-images-container">
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>

</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.6/ace.js"></script>
<script>
  function editor()
    {
        if($('#promo-css-editor').length)
            {
                var targetCss = $('#promo-css-editor').data('target');
                var editorCss = ace.edit("promo-css-editor");
                editorCss.setValue($(targetCss).val());
                editorCss.setTheme("ace/theme/chrome");
                editorCss.getSession().setMode("ace/mode/css");
                editorCss.getSession().setUseWrapMode(true);
                editorCss.on('change', function(){
                    $(targetCss).val(editorCss.getValue());
                    $(targetCss).trigger('change');
                });
            }
        if($('#promo-html-editor').length)
            {
                var targetHtml = $('#promo-html-editor').data('target');
                var editorHtml = ace.edit("promo-html-editor");
                editorHtml.setValue($(targetHtml).val());
                editorHtml.setTheme("ace/theme/chrome");
                editorHtml.getSession().setMode("ace/mode/html");
                editorHtml.getSession().setUseWrapMode(true);
                editorHtml.on('change', function(){
                    $(targetHtml).val(editorHtml.getValue());
                    $(targetHtml).trigger('change');
                    
                });
            }
        if($('#promo-js-editor').length)
            {
                var targetJs = $('#promo-js-editor').data('target');
                var editorJs = ace.edit("promo-js-editor");
                editorJs.setValue($(targetJs).val());
                editorJs.setTheme("ace/theme/chrome");
                editorJs.getSession().setMode("ace/mode/javascript");
                editorJs.getSession().setUseWrapMode(true);
                editorJs.on('change', function(){
                    $(targetJs).val(editorJs.getValue());
                    $(targetJs).trigger('change');
                });
            }
        function changehtmleditor(val)
        {
            editorHtml.setValue(val);
        }
    }

function livePreview()
    {
        if($('.preview').length)
            {
                
                $('#promo-css,#promo-js,#promo-html').on('change', function() {
                    var el = $(this);
                    var target = el.data('type');
                    var val = el.val();
                    $('.preview').find(target).html(val);
                });
                
                $('.preview-options input').keyup(function() {
                    var el = $(this);
                    var root = el.parent();
                    var css = root.data('css');
                    var val = el.val();
                    if(val == 0)
                        {
                            val = '100%';
                        }
                    if(css == 'width')
                        {
                            $('.preview').animate({
                                width: val
                            });
                        }
                    if(css == 'height')
                        {
                            $('.preview').animate({
                                height: val
                            });
                        }
                    
                });
                $('.align .preview-icon').click(function() {
                    var align = $(this).data('preview-align');
                    var root = $(this).parent();
                    root.find('.preview-icon').removeClass('active');
                    $(this).addClass('active');
                    $('.preview-icon').each(function(k,el) {
                        $('.preview').removeClass($(el).data('preview-align'));
                    });
                    $('.preview').addClass(align);
                });
                $('.device .preview-icon').click(function() {
                    var device = $(this).data('preview-device');
                    var root = $(this).parent();
                    root.find('.preview-icon').removeClass('active');
                    $(this).addClass('active');
                    $('.preview-icon').each(function(k,el) {
                        $('.preview').removeClass($(el).data('preview-device'));
                    });
                    $('.preview').addClass(device);
                    switch (device)
                    {
                        case 'mobile':
                            $('[data-preview-align="center"]').click();
                            $('#preview-width').val(375);
                            $('#preview-height').val(667);
                            $('#preview-width,#preview-height').trigger('keyup');
                            break;
                        case 'tab':
                            $('[data-preview-align="center"]').click();
                            $('#preview-width').val(480);
                            $('#preview-height').val(687);
                            $('#preview-width,#preview-height').trigger('keyup');
                            break;
                        case 'laptop':
                            $('[data-preview-align="center"]').click();
                            $('#preview-height').val($('.preview').width()*0.5625);
                            $('#preview-width,#preview-height').trigger('keyup');
                            break;
                        default :
                            $('#preview-width').val(0);
                            $('#preview-height').val(0);
                            $('#preview-width,#preview-height').trigger('keyup');
                            break;
                    }
                    
                });
            }
    }

function createImgNode(src)
    {
        var node = $('<div class="col-sm-6"> <div class="promo-images-wrapper" style="background-image: url('+src+');"> <div class="hover"> <div class="form-group"> <div class="btn btn-info set-bg">Set Background</div></div><div class="promo-bg-options"> </div><div class="url"> <div class="live-input"> <input type="text" class="img-url text-center form-control" value="'+src+'"> </div><div class="btn btn-info"  data-toggle="tooltip" data-original-title="Copy">Copy URL</div></div></div></div></div>');
        
        $('.image-images-container').append(node);
        copyUrl();
        setBgOptions();
    }
    
    function copyUrl()
    {
        $('.url .btn').click(function(e) {
            e.preventDefault();
            var root = $(this).parent();
            var target = root.find('.img-url');
            $('input').blur();
            target.select();
            try {
                // copy text
                document.execCommand('copy');
                target.blur();
                $(this).attr('data-original-title','Copied').tooltip('fixTitle') .tooltip('show');
              
            }
            catch (err) {
              alert('please press Ctrl/Cmd+C to copy');
            }
        });
    }
    
    function setBgOptions()
    {
        $('.set-bg').click(function(e) {
            e.preventDefault();
            var root = $(this).parentsUntil('body','.promo-images-wrapper').last();
            var node = $('<div> <div class="row"> <div class="col-xs-6"> <div class="live-input form-group active"> <select class="form-control repeat"> <option value="">repeat Type</option> <option value="repeat">Repeat</option> <option value="repeat-x">Repeat-x</option> <option value="repeat-y">Repeat-y</option> <option value="no-repeat">No-repeat</option> </select> </div></div><div class="col-xs-6"> <div class="live-input form-group active"> <select class="form-control size"> <option value="">Backgeound Size</option> <option value="cover">Cover</option> <option value="contain">Contain</option> </select> </div></div></div></div><div class="form-group"> <div class="row"> <div class="col-xs-3"> <label>X -</label> </div><div class="col-xs-9"> <div class="live-input active"> <select class="form-control x-pos"> <option value="">Position</option> <option value="left">Left</option> <option value="center">Center</option> <option value="right">Right</option> </select> </div></div></div></div><div class="form-group"> <div class="row"> <div class="col-xs-3"> <label>Y -</label> </div><div class="col-xs-9"> <div class="live-input active"> <select class="form-control y-pos"> <option value="">Position</option> <option value="top">Top</option> <option value="center">Center</option> <option value="bottom">Bottom</option> </select> </div></div></div></div>');
            $('.promo-bg-options').html('');
            root.find('.promo-bg-options').html(node);
            $('.img-url').removeClass('bg-img-url');
            root.find('.img-url').addClass('bg-img-url');
            bgval();
        });
        
        function bgval()
        {
            $('.promo-bg-options .form-control').on('change', function() {
                $('#promo-bg').trigger('change');
            });
            
            
            $('#promo-bg').on('change', function() {
                var size = $('.promo-bg-options .size').val();
                var repeat = $('.promo-bg-options .repeat').val();
                var xPos = $('.promo-bg-options .x-pos').val();
                var yPos = $('.promo-bg-options .y-pos').val();
                var src = $('.bg-img-url').val();
                var bgVal = 'url('+src+') '+xPos+' '+yPos+' '+size;
                //$('#promo-bg').val(bgVal);
                console.log(bgVal);
                $('.preview').css({
                    backgroundImage: 'url('+src+')',
                    backgroundPosition: xPos+' '+yPos,
                    backgroundSize: size,
                    backgroundRepeat: repeat
                });
            });
        }
    }
    
    function DNDfileUploader()
    {
        if($('.dnd-file-handler').length)
            {
                var dnd = $(".dnd-file-handler");
                var fileinput = $('.dnd-file-uploader [type="file"]');
                dnd.click(function() {
                    fileinput.click();
                });
                dnd.on('dragenter', function (e) {
                    e.stopPropagation();
                    e.preventDefault();
                    $(this).css({
                        borderStyle:'dashed',
                        borderColor:'#00c0ef',
                        color: '#00c0ef'
                    });
                });
                dnd.on('dragover', function (e) {
                    e.stopPropagation();
                    e.preventDefault();
                });
                dnd.on('drop', function (e) {
                    e.preventDefault();
                    $(this).css({
                        borderStyle:'solid',
                        borderColor:'#ccc',
                        color: '#ccc'
                    });
                    var img = e.originalEvent.dataTransfer.files;
                    fileHandler(img[0]);
                });
                fileinput.on('change', function() {
                    fileHandler(this.files[0]);
                });
                function fileHandler(file)
                {
                    var fr = new FileReader();
                    fr.onload = function(e) {
                        var fileload = e.target.result;
                        createImgNode(fileload);
                    }
                    fr.readAsDataURL(file);
                }
            }
    }





editor();
livePreview();
copyUrl();
setBgOptions();
DNDfileUploader();


$(window).on('load',function() {
        if($('.preview').length)
            {
                $('#promo-css,#promo-js,#promo-html').trigger('change');
            }
    });
</script>

 

 

 

And now if you open index.html file inside the browser you will see the below result

 

 

 

 

 

 

 

 

 

 

 

Leave a Reply