<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<style>
[v-cloak] {
display: none;
}
[disabled] {
background-color: lightgray;
}
.ctrl {
border: solid black 3px;
}
.black-text {
color: black;
}
.blue-text {
color: blue;
}
input,
textarea,
select {
width: 1000px;
background-color: rgb(202, 237, 206);
border: solid black 3px;
font-size: 20px;
font-family: 'consolas';
}
textarea {
height: 200px;
}
.pre-wrap {
white-space: pre-wrap;
}
.hover-lightblue:hover {
background-color: lightblue;
}
.light-blue {
background-color: lightblue;
}
</style>
<div id='items-container' v-cloak>
<template v-for='item in items'>
<div :style='getItemStyle(item)' :id='item.id'>
<div style='width:100%'>
<a @click.prevent='expand(item)' href='javascript:void(0);'>expand</a>
<a @click.prevent='collapse(item)' href='javascript:void(0);'>collapse</a>
<a @click.prevent='item.checked=!item.checked' href='javascript:void(0);'>check/uncheck</a>
<span v-bind:style='{visibility:(item.checked?"visible":"hidden"),color:"blue"}'>✔</span>
<span class='pre-wrap'>{{item.text}}</span>
</div>
<div class='sub-items-container' v-show='item.isExpanded'></div>
</div>
</template>
</div>
<script src='./xxx.js'></script>
</body>
</html>
var newid = (function () {
var id = 1;
function _newid() {
return 'vue-id-' + id++;
}
return _newid;
})();
const domParser = new DOMParser();
function parseHtml(html) {
return domParser.parseFromString(html, 'text/html').body.childNodes[0]
}
const items_container_template_html = document.getElementById('items-container').outerHTML;
buildItemsUi([
{ text: 'xxx', depth: 1, items: undefined, isExpanded: false, id: newid(),checked:false },
{ text: 'yyy', depth: 1, items: undefined, isExpanded: false, id: newid(),checked:false },
{ text: 'zzz', depth: 1, items: undefined, isExpanded: false, id: newid(),checked:false },
], '#items-container');
function buildItemsUi(items, el) {
// if (el instanceof HTMLElement) {
// if (!el.id) {
// el.id = newid();
// }
// }
var vo = new Vue({
el: el,
data: {
items: items,
},
methods: {
expand: function (item) {
if (item.isExpanded) return;
if (item.items === undefined) {
item.items = [];
for (let i = 0; i < 5; i++) {
var newitem = { text: '' + i, depth: item.depth + 1, isExpanded: false, id: newid(),checked:false };
item.items.push(newitem);
}
var el = parseHtml(items_container_template_html);
el.id = newid();
//this.$el.getElementsByClassName('sub-items-container')[0].appendChild(el);
document.getElementById(item.id).getElementsByClassName('sub-items-container')[0].appendChild(el);
buildItemsUi(item.items, el);
// console.log(el);
}
item.isExpanded = true;
},
collapse: function (item) {
if (!item.items) return;
if (!item.isExpanded) return;
item.isExpanded = false;
},
getItemStyle: function (item) {
return { paddingLeft: item.depth * 5 + 'px' }
},
},
computed: {
}
});
vo.$el.vo = vo;
return vo;
}