flexbox based editable table with divs - vanillajs

by Ercan Cicek

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
<div class="grid-container">
          <!-- angular: head from coll.head -->
          <div class="grid-header flex-display flex-row">
            <div>Name</div>
            <div>Arrival Time</div>
          </div>
          <!-- angular: repeat from coll.content -->
          <div class="grid-content">
              <div class="grid-row flex-display flex-row">
                  <div>Targaryen</div>
                  <div>20:15</div>
                  <a href="#" onclick="removeRow(this);" class="grid-toggle-bubble grid-toggle-bubble-minus flex-display flex-center fas fa-minus"></a>
                  <a href="#" onclick="moveRow(true, this);" class="grid-toggle-bubble grid-toggle-bubble-arrow-up flex-display flex-center fas fa-chevron-up"></a>
                  <a href="#" onclick="moveRow(false, this);" class="grid-toggle-bubble grid-toggle-bubble-arrow-down flex-display flex-center fas fa-chevron-down"></a>
                </div>
                <div class="grid-row flex-display flex-row">
                  <div>Lannister</div>
                  <div>23:00</div>
                  <a href="#" onclick="removeRow(this);" class="grid-toggle-bubble grid-toggle-bubble-minus flex-display flex-center fas fa-minus"></a>
                  <a href="#" onclick="moveRow(true, this);" class="grid-toggle-bubble grid-toggle-bubble-arrow-up flex-display flex-center fas fa-chevron-up"></a>
                  <a href="#" onclick="moveRow(false, this);" class="grid-toggle-bubble grid-toggle-bubble-arrow-down flex-display flex-center fas fa-chevron-down"></a>
                </div>
                <div class="grid-row flex-display flex-row">
                  <div>Stark</div>
                  <div>00:05</div>
                  <a href="#" onclick="removeRow(this);"...

CSS

html,
body {
  position: relative;
  width: 100%;
  height: 100%;
  font-family: Helvetica;
}

.panel {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  word-wrap: break-word;
  background-color: #fff;
  background-clip: border-box;
  border: 1px solid rgba(0, 0, 0, 0.125);
  border-radius: 0.25rem;
}

.panel-head {
  padding: 0.75rem 1.25rem;
  margin-bottom: 0;
  background-color: rgba(0, 0, 0, 0.03);
  border-bottom: 1px solid rgba(0, 0, 0, 0.125);
  font-size: 1.25em;
}

.panel-content {
  flex: 1 1 auto;
  padding: 1.25rem;
  font-size: 0.9em;
}

.panel-content > .group > .title {
  font-weight: bold;
  margin-bottom: 10px;
}

.panel-content > .group > .group {
  padding-left: 30px;
}

/* --- table --- */
.grid-container {
  position: relative;
  width: calc(100% - 1.25rem - 90px);
  margin: 1em auto 0 auto;
  font-size: 1.05em;
}

.grid-container > .grid-header,
.grid-container > .grid-content > .grid-row {
  padding: 0.67em;
}

.grid-container > .grid-header {
  position: relative;
  width: 100%;
  height: auto;
  background-color: #fff;
  font-weight: bold;
  border-bottom: 2px solid #bdbdbd;
}

.grid-container > .grid-header > div {
  position: relative;
  width: 50%;
  height: auto;
}

.grid-container > .grid-content {
  position: relative;
  width: 100%;
  height: 100%;
}

.grid-container > .grid-content > .grid-row {
  position: relative;
  width: 100%;
  height: auto;
  background-color: #f9f9f9;
  overflow: hidden;
  transition: background .15s ease;
}

.grid-container > .grid-content > .grid-row {
  border-bottom: 1px solid #bdbdbd;
}

.grid-container > .grid-content > .grid-row > div:not(.grid-toggle-bubble) {
  position: relative;
  width: 50%;
  height: auto;
}

.grid-container > .grid-content > .grid-row:nth-of-type(odd) {
  background-color: #fff;
}

/* --- bubbles --- */
.grid-container .grid-toggle-bubble {
  position: absolute;
  width: 1.4em;
  height: 1.4em;
  background-color: #e0e0e0;
  border-radius:...

JavaScript

function addRow() {
  var parent = document.getElementsByClassName("grid-content")[0],
    newRow = document.createElement("div"), // --- row itself
    minus = document.createElement("a"), // --- minus bubble
    arrUp = document.createElement("a"), // --- arrow up bubble
    arrDown = document.createElement("a"); // --- arrow down bubble
  newRow.classList = "grid-row flex-display flex-row";
  minus.classList = "grid-toggle-bubble grid-toggle-bubble-minus flex-display flex-center fas fa-minus";
  minus.onclick = function() { removeRow(this); };
  newRow.appendChild(minus);
  arrUp.classList = "grid-toggle-bubble grid-toggle-bubble-arrow-up flex-display flex-center fas fa-chevron-up";
  arrUp.onclick = function() { moveRow(true, this); };
  newRow.appendChild(arrUp);
  arrDown.classList = "grid-toggle-bubble grid-toggle-bubble-arrow-down flex-display flex-center fas fa-chevron-down";
  arrDown.onclick = function() { moveRow(false, this); };
  newRow.appendChild(arrDown);
  // --- add dummy values into row
  var colCount = document.getElementsByClassName("grid-header")[0];
  for (var i = 0; i < colCount.childElementCount; i++) {
    var dummyValDiv = document.createElement("div");
    dummyValDiv.innerText = "dummy";
    newRow.appendChild(dummyValDiv);
  }
  parent.appendChild(newRow);
}

function removeRow(ele) { ele.parentElement.outerHTML = ""; }

function moveRow(direction, ele) {
  // --- direction => true up; false down
  var parent = document.getElementsByClassName("grid-content")[0],
    eleToMove = ele.parentNode,
    rowsArr = Array.prototype.slice.call(parent.children),
    curIdx = rowsArr.indexOf(ele.parentNode),
    newIdx = curIdx + (direction ? -1 : 2);
  if ((direction && newIdx >= 0) || (!direction && newIdx <= rowsArr.length)) {
    var eleToMoveBefore = parent.children[newIdx];
    parent.insertBefore(eleToMove, eleToMoveBefore);
    parent.children[curIdx].classList.add("bg-anim");
    parent.children[direction ? newIdx : newIdx -...