Vue-jstree

file/folder tree for vue example (menu, drag-drop)

by abernov

HTML

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-context-menu"></script>


<div id="app">
    
<h2>Tree View: drag-drop, ctrl-key and menu available.</h2>
    <div>
        <div style="width:840px; margin: 0 auto;">
            <div style="width:49%; display:inline-block; vertical-align: top;">
                <p style="text-align:left">Search Text<input type="text" @keyup="inputKeyUp" v-model="searchText" /></p>
                <p>
                   <button @click="fillData">Add files to selected folders</button>
                   <input type="text" style="width:20%" v-model="filesToAdd" />
                </p>

     <v-jstree :data="data" :item-events="itemEvents" draggable @item-drop="itemDrop" ref="tree">
       <template scope="_">
         <div style="display: inherit; width: 200px"
           @click.ctrl="itemCtrlClick(_.vm, $event)"
           @click.exact="itemClick(_.vm, $event)"          
           @contextmenu.prevent="$refs.ctx.open($event, _.vm)">
           <i :class="_.vm.themeIconClasses" role="presentation" v-if="!_.model.loading"></i>
           {{_.model.text}}
<!--           
           <button style="border: 0px; background-color: transparent; cursor: pointer;" @click="customItemClick(_.vm, _.model, $event)"><i class="fa fa-remove"></i></button>
           
-->           
         </div>
       </template>
     </v-jstree>

<!--
<v-jstree :data="data" :item-events="itemEvents" draggable @item-drop="itemDrop" @item-click="itemClick" ref="tree"></v-jstree> 
-->

            </div>
            <div style="width:50%; display:inline-block;">
                <textarea  style="height:300px; width:100%;">
                  {{data}}
                </textarea>
            </div>
        </div>
    </div>
    
<!--
 <context-menu id="testingctx" ref="ctx" @ctx-open="onCtxOpen" @ctx-cancel="resetCtxLocals"...

CSS

h2 {
  color:red;
  font-size: 150% 
}

Vue

const RootNodeValue = 'Root'

Vue.use(VueContextMenu)
 
const app =  new Vue({
  created: function () {
            window.addEventListener('keydown', this.keyDownListener)
  },
  destroyed: function() {
  window.removeEventListener('keydown', this.keyDownListener);
  },
  el: '#app',
  data() {
    return {
      fileIdx: 0,   
      filesToAdd: 1,
      folderIdx: 3,
      searchText: '',
      editingItem: {},
      editingNode: null,
      itemEvents: {
              mouseover: function () {
                  console.log('mouseover')
              }
      },
      data: [
        {
          "text": "Root",
          "value": RootNodeValue,
          "dragDisabled": true,
//          "disabled": true,
          "isLeaf": true,  
          "opened": true,  //does not work
          "isfolder": true,
          "icon": "fa fa-warning icon-state-danger",
          "children": [
               {
                "text": "Folder1",
                "isfolder": true
               },
               {
                "text": "Folder2",
                "isfolder": true
               },
               {
                "text": "Folder3",
                "isfolder": true
               }
           ]
        }
      ]
    }
  },
  methods: {
    btnKeyDown: function (event) {
     alert("BtnKeyDown")
    },
    keyDownListener: function (event) {
      if (event.keyCode === 46) //del
          this.removeNodes()
    },
    onCtxOpen(node) {
      this.editingNode = node
      this.editingItem = node.model   
//       alert('menu open ' + node.model.text)  
//        this.menuData = locals
    },  
    itemClick: function (node, e) {
      this.editingNode = node
      let item = node.model
      this.editingItem = item            
//      if ( item.dropDisabled !== true ) {
//        item.opened = !(item.opened && item.value !== "Root")
//      }
      console.log(node.model.text + ' clicked !')
//      alert("click : " + node.model.text)
      this.deselectNodeChildren...