JSFiddle - React, Tailwind, and code Playground

by Ryan Brackett

CSS

/**************** DASHBOARD *****************/
#ltp-gdpr-accost {
  display: none;
}

body,
html {
  width: 100%;
  scroll-behavior: smooth;
}

h1.page-header {
  margin-top: 50px;
  font-size: 50px;
}

.sticky {
  position: -webkit-sticky;
  /* Safari */
  position: sticky;
  top: 80px;
}

/* PANELS */

.panel-column {}

.panel-column h2 {
  font-size: 35px;
  margin-bottom: 40px;
  margin-top: 50px;
}

/* PANEL STYLES */

.panel {
  margin: 0px 0px 40px 0px;
  border-radius: 1em;
  overflow: hidden;
  -webkit-box-shadow: -1px 7px 6px 0px #70788114;
  box-shadow: -1px 7px 6px 0px #70788114;
}

.panel .panel-heading {
  height: auto;
  padding: 20px 40px;
  letter-spacing: normal;
  line-height: normal;
  font-weight: 500;
  border-bottom: 1px solid #dedede;
}


.panel .panel-heading h2 {
  font-size: 170%;
  letter-spacing: -.5px;
  margin: 0px;
  line-height: 1.4em;
}

.panel .panel-container {
  padding: 0px;
}

.panel .panel-body {
  padding: 0px 40px 20px 40px;
}

.panel .panel-body h3 {
  font-size: 1.75em;
  font-weight: 300;
}

.panel .panel-body h4 {
  font-weight: 500;
  font-size: 1.4em;
  line-height: 1.4em;
  margin-bottom: 30px;
}

/* BREADCRUMB */

.breadcrumb {
  background: #363636;
  font-size: 12px;
}

.breadcrumb a {
  color: white;
}

.breadcrumb li.active {
  color: white;
}

/* OVERRIDES */
.btn {
  -webkit-transition: all .2s ease-in-out;
  -moz-transition: all .2s ease-in-out;
  -ms-transition: all .2s ease-in-out;
  -o-transition: all .2s ease-in-out;
  transition: all .2s ease-in-out;
}

.btn-success {
  color: #fff;
  background-color: #5cb85c;
  border-color: #4cae4c;
}

.btn-success:hover {
  color: #fff;
  background-color: #449d44;
  border-color: #398439;
}


/**
 * ----------------------------------------
 * animation blink
 * ----------------------------------------
 */

.blink {
  -webkit-animation: blink 5s infinite both;
  animation: blink 5s infinite both;
}

@-webkit-keyframes blink {

  0%,
  50%,
  100% {
    opacity: 1;
...

JavaScript

$(document).ready(function() {

  // REMOVE BUTTON
  $(document).on("click", ".row-action .remove", function() {
    $(this).closest(".data-item").remove();
  });

  // ADD BUTTON
  $(".form-table-wrapper .add").click(function() {
    let dataSet = $(this).attr("data-set");
    let dataRowClone = $('table[data-set="' + dataSet + '"] tbody tr:last').clone();
    $(dataRowClone).find('input.form-input').val('');
    $('table[data-set="' + dataSet + '"] tbody').append(dataRowClone);
  });

  //SAVE BUTTON
  $(".form-table-wrapper .save").click(function() {
    // SELECT THE RELATED DATA SET
    let dataSet = $(this).attr("data-set");
    let dataSetRows = $('table[data-set="' + dataSet + '"] .data-item');
    let dataSetArray = [];

    // FOR EACH ROW IN THE DATA TABLE
    $(dataSetRows).each(function(i) {
      let dataRow = $(this);
      let dataRowInputs = $(this).find(".form-input");
      let dataRowArray = [];

      // FOR EACH INPUT IN THE ROW
      $(dataRowInputs).each(function() {
        let inputValue = $(this)[0]["value"];
        let className = $(this)[0]["className"].replace("form-input ", "");
        let dataItem = {
          key: className,
          value: inputValue
        };
        dataRowArray.push(dataItem);
      });
      dataSetArray.push(dataRowArray);
    });
    // NEED TO SEND THIS DATA TO THE PS API
    console.log(dataSetArray);
  });
});