JSFiddle - React, Tailwind, and code Playground

by Imri Paloja

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">


<div class="container">

  <dialog id="output"></dialog>

  <p onclick="HtmlEditor.selectTag(this)">Click me</p>
  <a onclick="HtmlEditor.selectTag(this)">Link</a>

</div>

CSS

html, body {
  color: #454545;
}

input,button,textarea {
  color: inherit;
}

.container {
  margin-top: 5% !important;
}

JavaScript

const HtmlEditor = {

  data: null,            // loaded JSON
  selectedTag: null,    // current tag name
  outputEl: "#output",  // dialog or container selector

  init(jsonData) {
    this.data = jsonData;
    console.log("Editor initialized");
  },

  selectTag(tagEl) {
    if (!tagEl || !tagEl.tagName) return;

    this.selectedTag = tagEl.tagName.toLowerCase();

    if (!this.data[this.selectedTag]) {
      console.warn("No data for tag:", this.selectedTag);
      return;
    }

    this.renderAttributes();
  },

  renderAttributes() {
    const attributes = this.data[this.selectedTag].attributes;
    const $output = $(this.outputEl);

    $output.empty().prop("open", true);

    $.each(attributes, (attributeName, tagData) => {

      const $row = $("<div>").addClass("editor-row");
      const $label = $("<label>").text(attributeName + ": ");

      // Case 1: value is a plain object → dropdown
      if (tagData.value && typeof tagData.value === "object") {

        const $select = $("<select>").attr("id", attributeName);

        $.each(tagData.value, (key, description) => {
          $("<option>")
            .val(key)
            .text(description)
            .appendTo($select);
        });

        $row.append($label, $select);
      }

      // Case 2: value is a string → text input
      else {

        const $input = $("<input>")
          .attr("type", "text")
          .attr("id", attributeName)
          .attr("placeholder", attributeName);

        $row.append($label, $input);
      }

      $output.append($row);
    });
  },

  collectValues() {
    const attributes = this.data[this.selectedTag].attributes;
    const result = {};

    $.each(attributes, (attributeName) => {
      const $field = $("#output #" + attributeName);

      if ($field.length) {
        result[attributeName] = $field.val();
      }
    });

    console.log("Collected values:", result);
   ...