jQuery: drag and drop HTML editor

adsasdad

by jelcsys

HTML

<div id="thumbs">
  <img src="https://lh4.googleusercontent.com/-MP6drmKHpmc/T1Mrj1mAsDI/AAAAAAAAA3o/nqv3fXcyOCw/w387-h310/mac.jpg" class="thumb" />
  <img src="https://lh4.googleusercontent.com/-MP6drmKHpmc/T1Mrj1mAsDI/AAAAAAAAA3o/nqv3fXcyOCw/w387-h310/mac.jpg" class="thumb" />
  <img src="https://lh4.googleusercontent.com/-MP6drmKHpmc/T1Mrj1mAsDI/AAAAAAAAA3o/nqv3fXcyOCw/w387-h310/mac.jpg" class="thumb" />
</div>
<div id="layout-area">
  <div id="choose-layout">
    <h3>Choose a layout</h3>
    <div id="layout-1">
      <div class="layout">1</div>
      <p>
        <input type="radio" value="target2" id="l1" />
      </p>
    </div>
    <div id="layout-2">
      <div class="layout">2</div>
      <p>
        <input type="radio" value="target" id="l2" />
      </p>
    </div>
  </div>
  <table id="target2">
    <tr>
      <td class="logo">
        <div class="img-container"></div>
      </td>
      <td class="text">
        <input type="text" id="title" value="Title" />
        <input type="text" id="sub-title" value="Subtitle" />
        <input type="text" id="evident" value="Title" />
      </td>
    </tr>
    <tr>
      <td class="half">
        <div class="img-container"></div>
        <textarea class="caption"></textarea>
      </td>
      <td class="half">
        <div class="img-container"></div>
        <textarea class="caption"></textarea>
      </td>
    </tr>
    <tr>
      <td colspan="2" class="data">
        <input type="text" id="dati" value="Data" />
      </td>
    </tr>
  </table>
  <table id="target">
    <tr>
      <td class="header" colspan="3">
        <input type="text" id="name" value="Details" />
        <input type="text" id="data" value="Details" />
        <input type="text" id="speciality" value="Details" />
      </td>
    </tr>
    <tr>
      <td>
        <div class="img-container"></div>
        <textarea class="caption"></textarea>
      </td>
      <td>
        <div class="img-container"></div>
        <textarea...

CSS

body {
  margin: 2em auto;
  max-width: 600px;
}

#thumbs {
  text-align: center;
  margin-bottom: 2em;
  background: #ccc;
  padding: 0.5em;
}

#thumbs img {
  width: 150px;
  height: 140px;
  margin: 0 1em;
  cursor: move;
}

#layout-area table {
  width: 100%;
  border-spacing: 2%;
  table-layout: fixed;
}

#target,
#target2 {
  display: none;
}

#target td {
  width: 30%;
  height: 140px;
  vertical-align: top;
}

textarea.caption {
  display: block;
  width: 95%;
  margin: 10px auto;
  height: 50px;
  border: none;
  background: #eee;
}

#layout-area .sized {
  display: block;
  max-width: 100%;
  max-height: 100%;
}

#layout-area .img-container {
  width: 100%;
  height: 150px;
  background: #eee;
  overflow: hidden;
  position: relative;
}

#layout-area .img-inserted {
  background: #fff;
}

img.ui-draggable {
  z-index: 100000;
}

#layout-area .remove {
  width: 26px;
  height: 26px;
  cursor: pointer;
  background: #000;
  color: #fff;
  text-align: center;
  line-height: 26px;
  font-size: 20px;
  position: absolute;
  top: 0;
  right: 0;
  display: none;
}

#target td.header {
  width: 100%;
}

#target td.header input,
#target2 td.text input {
  width: 100%;
  margin-bottom: 0.5em;
  display: block;
  padding: 0.3em;
  border: none;
  text-align: center;
  background: #eee;
}

#choose-layout {
  width: 480px;
  margin: 2em auto;
  overflow: hidden;
}

#choose-layout div {
  width: 230px;
  text-align: center;
}

#choose-layout .layout {
  height: 180px;
  line-height: 180px;
  background: #eee;
}

#layout-1 {
  float: left;
}

#layout-2 {
  float: right;
}

#choose-layout img {
  display: block;
  max-width: 100%;
}

#target2 td {
  vertical-align: top;
}

#target2 td.logo {
  width: 50%;
}

#target2 td.text {
  width: 50%;
}

#target2 td[colspan] {
  width: 100%;
}

#target2 td[colspan] input {
  width: 100%;
  margin-bottom: 0.5em;
  display: block;
  padding: 0.3em;
  border: none;
  background: #eee;
  text-align: center;
}

JavaScript

var LayoutHandler = {
  fn: {
    start: function() {
      $('div.img-container').each(function() {
        var div = $(this);
        $('<span class="remove"/>').text('X').appendTo(div);
      });


      $('img.thumb').draggable({
        containment: '#layout-area',
        revert: 'invalid',
        helper: 'clone'
      });

      $('div.img-container').droppable({
        accept: 'img.thumb',
        drop: function(event, ui) {
          var div = $(this);
          var img = ui.draggable;
          var copy = img.clone();
          $(copy).addClass('sized').appendTo(div);
          div.addClass('img-inserted');
          $('span.remove', div).show();
        }

      });


    },

    remove: function() {
      $('span.remove').on('click', function() {
        var span = $(this);
        span.parent().find('img').remove();
        span.parent().removeClass('img-inserted');
        span.hide();
      });

    },

    oninput: function() {
      $('input[type="text"]', '#layout-area').focus(function() {
        $(this).val('');
      });
    },

    chooseLayout: function() {
      $('input[type="radio"]', '#choose-layout').change(function() {
        var $input = $(this);
        if ($input.prop('checked')) {
          var target = $('#' + $input.val());
          target.show().siblings('table').hide();
          $input.parents('#choose-layout').find('input').not($input).removeAttr('checked');
          $('#choose-layout').hide();
        }
      });

    },

    toHTML: function() {
      $('#html').click(function() {
        var html = '<table style="table-layout: fixed; width: 100%; border-spacing: 3%; border-collapse: separate;">';
        if ($('#target').is(':visible')) {
          $('tr', '#target').each(function() {
            var tr = $(this);
            html += '<tr>';
            $('td', tr).each(function() {
              var td = $(this);
              if (!td.is('td.header')) {
                var img = $('img', td);
                var...