JSFiddle - React, Tailwind, and code Playground
by texinwien
HTML
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Tree Editor</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body id="body">
<form method="post" id="theForm">
<ul class="main-container expanded">
<li id="uiid0x24667e20" class="element resource">
<fieldset>
<span class="shrinker">
<span class="resource nodename">resource</span>
<span class="attribute-container">
<label for="id0x24667e20-0000000000">rid: </label>
<input type="text" id="id0x24667e20-0000000000" name="rid" value="Test Container" size="20" class="rid">
</span>
<span class="attribute-container">
<label for="id0x24667e20-0000000001">Autocomplete: </label>
<input type="text" id="id0x24667e20-0000000001" name="country" value="USA" size="20" class="country autocomplete">
</span>
<span class="attribute-container">
<label for="id0x24667e20-0000000002">label: </label>
<input type="text" id="id0x24667e20-0000000002" name="label" value="Test" size="20" class="label">
</span>
<span class="nodename"></span>
</span>
<ul class="expanded">
<li id="uiid0x24676560" class="element resource">
<fieldset>
<span class="shrinker">
<span class="resource nodename">Click Here</span>
<span...
CSS
body {
font-size:10px;
font-family: Consolas, Courier;
overflow-x: hidden;
}
body, form ul, form li{
border:0; margin:0; padding:0; list-style:none;
}
form {
width:100%;
font-size: 1.4em;
font-family: Consolas;
/*border: 1px solid #A6A6A6;*/
margin:0;
padding:0;
}
fieldset {
clear:both;
display: block;
padding:0;
margin:0;
width:99%;
border-style:none;
}
fieldset fieldset {
margin-left:1em;
}
fieldset legend {
display:none;
font-weight: bold;
background-color: #FFF;
margin-top:1.2em;
color:blue;
cursor:pointer;
}
input[type=text], textarea, select {
font-size:1em;
font-family: Consolas;
float:left;
background:transparent;
border-style:none;
margin:0;
padding:0;
}
input:hover, textarea:hover, select:hover {
background:#F5F5F5;
}
input:focus, textarea:focus, select:focus {
background:white;
}
input[type=text], select {
font-size:1em;
color:#8000FF;
font-weight:bold;
}
textarea {
width:94%;
height:1em;
}
.comment textarea {
font-style: italic;
color:#008000;
}
.text textarea {
color:#000000;
}
span.expandcollapse {
display:none;
position:relative;
margin-top:.2em;
z-index:10;
width:11px;
height:11px;
background-image:url(../images/sprite.png);
background-position:-11px 0px;
left:-11px;
margin-right:-11px;
}
li.resource > fieldset > span.expandcollapse, li.if > fieldset > span.expandcollapse {
display:inline;
}
span.expandcollapse.collapsed {
background-position:0px 0px;
}
label, li span, .nodename, .assignment-operator, .double-quotes,
.comment-start, .comment-end, .processing-instruction-start,
.processing-instruction-end {
float: left;
white-space: nowrap;
display:block;
cursor:default;
}
fieldset > span.shrinker {width:90%;
white-space: normal;
}
.compact {height: 1.2em; overflow-y: hidden;}
.hidden{display:none;}
label {
...
JavaScript
$().ready(function() {
var myAutoIncrementingID = 1,
theForm = $('#theForm'); /* BEGIN: Element Menu */
var elementMenu = document.getElementById('element-menu'),
allChildLIs = $('#theForm li.element.resource li.element'),
htmlClipboard = document.createDocumentFragment();
// Attach function to click on all Node Name Spans to open the menu
$(allChildLIs).delegate('span.nodename', 'click', function(event) {
event.stopPropagation();
var position = $(this).position(),
height = $(this).height(),
contextHtmlNodeID = $(this).parents('li:first').attr('id');
$(elementMenu).css({
'top': parseInt(position.top + height),
'left': position.left
}).toggle();
$(elementMenu).attr('contextHtmlNodeID', contextHtmlNodeID);
});
$('#body').click(function() {
$(elementMenu).hide();
});
function generateNewID() {
return ++myAutoIncrementingID;
}
$('#duplicate-element').click(function() {
$(elementMenu).toggle();
var newIDPostfix = generateNewID(),
//Set HTML Node variables
contextHtmlNodeID = $(elementMenu).attr('contextHtmlNodeID'),
contextHtmlNode = document.getElementById(contextHtmlNodeID),
newHtmlId = contextHtmlNodeID.split('-')[0] + '-' + newIDPostfix,
duplicateHtmlNode = $(contextHtmlNode).clone();
$(duplicateHtmlNode).attr('id', newHtmlId);
//generate Ids for the new nodes
$(duplicateHtmlNode).find('input:text').each(function() {
var origHtmlId = $(this).attr('id').split('-');
origHtmlId[2] = origHtmlId[2] === undefined ? '' : origHtmlId[2];
var newHtmlId = origHtmlId[0] + '-' + origHtmlId[1] + '-' + origHtmlId[2] + newIDPostfix;
$(this).attr('id', newHtmlId);
$(this).siblings('label').attr('for', newHtmlId);
});
...