JSFiddle - React, Tailwind, and code Playground
by dafastestfingers
HTML
<button>Create JSON</button>
<br/>
<ul class="root">
<li class="toggle">--</li>
<li><input type="text" placeholder="name"/></li>
<li><input type="text" placeholder="description"/></li>
<li class="children">
<ul class="item">
<li class="toggle">--</li>
<li><input type="text" placeholder="title"/></li>
<li><input type="text" placeholder="href"/></li>
<li><input type="text" placeholder="image"/></li>
</ul>
<ul class="item">
<li class="toggle">--</li>
<li><input type="text" placeholder="title"/></li>
<li><input type="text" placeholder="href"/></li>
<li><input type="text" placeholder="image"/></li>
<li class="children">
<ul class="item">
<li class="toggle">--</li>
<li><input type="text" placeholder="title"/></li>
<li><input type="text" placeholder="href"/></li>
<li><input type="text" placeholder="image"/></li>
</ul>
</li>
</ul>
<ul class="item">
<li class="toggle">--</li>
<li><input type="text" placeholder="title"/></li>
<li><input type="text" placeholder="href"/></li>
<li><input type="text" placeholder="image"/></li>
</ul>
</li>
</ul>
<textarea id="output"></textarea>
CSS
ul {
list-style: none;
margin: 2px;
margin-left: 20px;
padding: 0;
position: relative;
}
li {
display: table;
padding: 1px;
}
.root > li:first-child + li {
background: yellow;
border: solid 1px black;
border-bottom: none;
margin-bottom: -3px;
}
.root li:first-child + li + li {
background: yellow;
border: solid 1px black;
border-top: none;
}
.toggle {
left: -20px;
position: absolute;
}
.item li:first-child +li ,
.item li:first-child + li + li,
.item li:first-child + li + li + li {
background: yellow;
}
.item li:first-child + li {
border: solid 1px black;
border-bottom: none;
margin-bottom: -3px;
}
.item li:first-child + li + li {
border: solid 1px black;
border-bottom: none;
border-top: none;
margin-bottom: -3px;
}
.item li:first-child + li + li + li {
border: solid 1px black;
border-top: none;
}
JavaScript
$('.toggle').click(function() {
var $t = $(this);
var $nxt = $t.next();
var $siblings = $t.siblings().not($nxt);
if ($t.text() === '+') {
$t.text('--');
$nxt.css('border-bottom', 'none');
$siblings.show();
} else {
$t.text('+');
$nxt.css('border-bottom', 'solid 1px black');
$siblings.hide();
}
});
$('button').click(function() {
parseList($('.root'));
})
function parseList(root) {
var json = '';
function parse(elm) {
var arr = [];
elm.children().not('.toggle').each(function(index) {
var $t = $(this);
var $c = $t.children();
var key = $c.attr('placeholder');
var val = $c.val();
var str = '"' + key + '":"' + val + '"';
if ($t.hasClass('children')) {
arr[arr.length] = '"children": [' + parse($c) + ']}';
} else {
if (key === 'title') {
str = '{' + str;
} else if(key === 'image' && !$t.next().hasClass('children')) {
str = str + '}';
}
arr[arr.length] = str;
}
});
return arr;
}
json = '{' + parse(root).join();
$('#output').val(json);
return json;
}