Vue - PE Properties Dialog V2

Vue ideas to drive Page Editor Properties dialog

by Ben Clayton

HTML

<script src="https://unpkg.com/vue"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/js/materialize.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/Sortable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.16.0/vuedraggable.min.js"></script>
<div id="propdialog">
  
    Properties: ({{block.name}}) {{blocks.length}} selected <br>
  
  <vue-propedit v-for="(option,idx) in options" :option="option" :blocks="blocks" :trigger="trigger" :block="block" :key="idx"></vue-propedit>

</div>
<hr>

<div id="preview">
  <div class="collection with-header">
      <draggable :list="blocks"
             class="dragArea"
                  :move="beforeMove"
                  @end="onEnd">
         <component  v-for="(block,idx) in blocks" :is="block.componentId" :block="block" :key="idx"></component>
      </draggable>
   </div>
</div>

CSS

label {
  display: inline-block;
  margin-right: 20px;
  width: 60px;
  text-transform: capitalize;
}

.color-edit label {
  width: 230px;
}

#propdialog {
  width: 420px;
  border: 1px solid gray;
  padding: 20px;
}

.propedit {
  margin-bottom: 10px;
  display: inline-block;
}

.propedit .tb-edit {
  width: 200px;
}

.propedit .color-edit {

  width: 400px;
}

.color-edit input[type=range] {
  width: 50px;
}

#preview {
  margin-top: 30px;
  position: relative;
}

.block {
  
}

.boxblock {
  border: 1px solid gray;
  padding-left:20px;
  /* position: absolute; 
}

.boxblock.selected {
  border: 2px solid blue;
}

.circleblock {
  border: 1px solid gray;
  border-radius: 50%;
  padding-top:19px;
  padding-left:10px;
  /* position: absolute; */
}

.circleblock.selected {
  border: 2px solid red;
}

JavaScript

// Code copyright Holograph   2020



var menuitems = {
  importance: {
    control: "select-edit",
    propertyName: "importance",
    label: "Importance",
    options: "h1:h1,h2:h2,h3:h3,h4:h4,h5:h5,h6:h6"
  }
}



Vue.component('vue-propedit', {
  props: ["option", "block", "blocks", "trig","trigger"],
  data: function() {
    return {
      "propertyName": "",
      "label": "",
      "control": "textbox-edit",
      "options": [],
      "blockcopy": {}
    }
  },
  template: `
  	<div class="propedit"> 
      	<component :is="'vue-' + control" :propertyName="propertyName" :label="label" :block="block"></component>
    </div>    
      `,
  watch: {
  	'trigger' : function(){ 
    	this.init();
    },
    'block': {
      handler: function() {
        console.log("*");
        if (this.blockcopy[this.propertyName] != this.block[this.propertyName]){
        	console.log('Current values:',this.propertyName,this.block[this.propertyName],this.blockcopy[this.propertyName] );
        	//this.blockcopy[this.propertyName] = this.block[this.propertyName];
          for(var i=0;i < this.blocks.length; i++){
          		if (this.block !=this.blocks[i] ){
          		this.blocks[i][this.propertyName] = this.block[this.propertyName];
              }
          }
        }
        
      },
      deep: true
    }
  },
  methods: {
    init() {
      var mi;
      if (typeof this.option == 'object') {
        mi = this.option
      }
      // debugger;
      mi = mi || menuitems[this.option] || {
        propertyName: this.option,
        label: this.option,
        control: 'textbox-edit'
      };
      this.propertyName = mi.propertyName;
      this.blockcopy[this.propertyName] = this.block[this.propertyName];
      this.label = mi.label || mi.propertyName;
      this.control = mi.control || 'textbox-edit';
      var str = mi.options || "";
      this.options = str.split(',').map(opt => {
        return {
          text: opt.split(':')[0],
          value:...