Vue - PE block ideas
common template for frame
by Ben Clayton
HTML
<script src="https://unpkg.com/vue"></script>
<div style="border:1px solid red;font-size:12px;">
Header
</div>
<div id="page-editor">
<div>
<holo-htmltext v-bind:properties='blocks[0]'></holo-htmltext>
<holo-htmltext v-bind:properties='blocks[0]'></holo-htmltext>
<holo-newpicture v-bind:properties='blocks[1]'></holo-newpicture>
<holo-group-wrapper v-bind:properties='blocks[2]'>
<holo-newpicture v-bind:properties='blocks[1]'></holo-newpicture>
<holo-newpicture v-bind:properties='blocks[1]'></holo-newpicture>
<holo-newpicture v-bind:properties='blocks[1]'></holo-newpicture>
</holo-group-wrapper>
</div>
</div>
<hr>
<script id="vue-tmpl-block-frame" type="text/x-template">
<div ref="blockref" :data-block="block" v-bind:class="outerclasses()" >
<div v-bind:class="innerclasses()"
@click.stop="toggleselected">
<div class="btncollapse" @click.stop="togglecollapse">V</div>
<div class="title">{{block.type}} (class:{{block.class }})</div>
</div>
<div class="inner" v-if="!collapsed">
<slot></slot>
</div>
</div>
</script>
<script id="vue-tmpl-newpicture" type="text/x-template">
<holo-block-frame v-bind:block="properties">
<img :src="properties.picture" />
</holo-block-frame>
</script>
<script id="vue-tmpl-group-wrapper" type="text/x-template">
<holo-block-frame v-bind:block="properties">
<slot></slot>
</holo-block-frame>
</script>
<script id="vue-tmpl-htmltext" type="text/x-template">
<holo-block-frame v-bind:block="properties">
<h1 v-bindhtml="properties.text" contenteditable=true></h1>
</holo-block-frame>
</script>
CSS
body {
font-size: 12px;
}
.text {
font-size: 24px;
}
.block {
background-color: #FEEEAA;
}
.block.selected {
background-color: #A020FF;
}
.btncollapse {
width: 30px;
display: inline-block;
text-align: center;
}
.closed .btncollapse {
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
.title {
display: inline-block;
text-align: center;
width: 80%;
}
.blk_wrapper {
border: 1px solid gray;
}
.inner {
padding: 10px;
}
JavaScript
//---------------------------------------------------------
class base{
constructor(){
this.selected=false;
}
}
class picture extends base {
constructor(){
super();
this.type = 'picture';
this.picture = "//holograph.digital/infxpageedit/img/default.gif";
this.class = 'fred,bert';
}
}
class htmltext extends base{
constructor(){
super();
this.type = "htmltext";
this.text = "Heading...";
this.class = 'fred,harry';
}
}
class groupwrapper extends base{
constructor(){
super();
this.type = "groupwrapper";
this.class = 'sid,sam';
}
}
//============================================================
Vue.directive('bindhtml', {
bind: function (el, binding, vnode) {
var select = $(el);
select
.html(binding.value)
.trigger('change')
.on('keyup', function () {
var bits = binding.expression.split('.');
var path = vnode.context;
var i=0;
while (i < bits.length -1) {
path = path[bits[i++]];
}
if ( typeof path[bits[i]] != 'undefined' ) {
path[bits[i]] = select.html();
}
vnode.context.$emit('change')
})
},
update: function (el, binding, vnode) {
if ( el.innerHTML != binding.value ){
// this damages the cursor position, a bit of a pain !!!!
el.innerHTML =binding.value
}
}
});
Vue.component('holo-block-frame', {
template: "#vue-tmpl-block-frame",
props: ['block'],
data: function(){return {collapsed:false} },
methods: {
outerclasses : function(){
var classes = {blk_wrapper:true,collapsed:this.collapsed,selected:this.block.selected};
classes[this.block.type] = true;
return classes;
},
innerclasses : function(){
var classes = {block:true,open:!this.collapsed,closed:this.collapsed,selected:this.block.selected};
classes['blk_' + this.block.type] = true;
return classes;
},
togglecollapse : function (e) {
this.collapsed = ! this.collapsed;
...