2015-11-06 47 views
1

我目前有一個Web應用程序,其視圖使用ExtJS 6編寫:我們當前使用Java小程序,其目的是允許用戶將文件系統中的文件拖放到Web服務器。 我的目標是刪除該小程序,並處理使用ExtJS6拖放&:這可能嗎?使用ExtJS拖放文件6

我試圖在文檔中搜索它,但我發現的唯一主題(https://docs.sencha.com/extjs/6.0/core_concepts/drag_drop.html)是關於拖放框架元素的。

+1

拖放基本上拖動DOM節點從一個容器到另一個,所以你實際上並沒有拖動文件,您拖動,將代表文件的節點。你打算如何列出你的文件系統?您如何計劃訪問您的文件系統? PHP + Treepanel? HTML5 + Treepanel? –

+0

感謝您的問題:我認爲,在我的情況下,最好的選擇是HTML5 + TreePanel –

回答

3

包含在此fiddle中的窗口允許用戶拖放&將文件從文件系統拖放到Web服務器。

的源代碼:

Ext.application({ 
    name: 'Fiddle', 

    launch: function() { 

     var store = Ext.create('Ext.data.Store', { 
      fields: ['name', 'size', 'file', 'status'] 
     }); 

     var postDocument = this.postDocument; 

     Ext.widget('container', { 

      renderTo: Ext.getBody(), 

      items: [{ 
       multiSelect: true, 
       xtype: 'grid', 
       id: 'UploadGrid', 
       columns: [{ 
        header: 'Name', 
        dataIndex: 'name', 
        flex: 2 
       }, { 
        header: 'Size', 
        dataIndex: 'size', 
        flex: 1, 
        renderer: Ext.util.Format.fileSize 
       }, { 
        header: 'Status', 
        dataIndex: 'status', 
        flex: 1, 
        renderer: this.rendererStatus 
       }], 

       viewConfig: { 
        emptyText: 'Drop Files Here', 
        deferEmptyText: false 
       }, 
       store: store, 

       listeners: { 

        drop: { 
         element: 'el', 
         fn: 'drop' 
        }, 

        dragstart: { 
         element: 'el', 
         fn: 'addDropZone' 
        }, 

        dragenter: { 
         element: 'el', 
         fn: 'addDropZone' 
        }, 

        dragover: { 
         element: 'el', 
         fn: 'addDropZone' 
        }, 

        dragleave: { 
         element: 'el', 
         fn: 'removeDropZone' 
        }, 

        dragexit: { 
         element: 'el', 
         fn: 'removeDropZone' 
        }, 

       }, 

       noop: function(e) { 
        e.stopEvent(); 
       }, 

       addDropZone: function(e) { 
        if (!e.browserEvent.dataTransfer || Ext.Array.from(e.browserEvent.dataTransfer.types).indexOf('Files') === -1) { 
         return; 
        } 

        e.stopEvent(); 

        this.addCls('drag-over'); 
       }, 

       removeDropZone: function(e) { 
        var el = e.getTarget(), 
         thisEl = this.getEl(); 

        e.stopEvent(); 


        if (el === thisEl.dom) { 
         this.removeCls('drag-over'); 
         return; 
        } 

        while (el !== thisEl.dom && el && el.parentNode) { 
         el = el.parentNode; 
        } 

        if (el !== thisEl.dom) { 
         this.removeCls('drag-over'); 
        } 

       }, 

       drop: function(e) { 
        e.stopEvent(); 
        Ext.Array.forEach(Ext.Array.from(e.browserEvent.dataTransfer.files), function(file) { 
         store.add({ 
          file: file, 
          name: file.name, 
          size: file.size, 
          status: 'Ready' 

         }); 
        }); 
        this.removeCls('drag-over'); 
       }, 

       tbar: [{ 
        text: "Upload", 
        handler: function() { 
         for (var i = 0; i < store.data.items.length; i++) { 
          if (!(store.getData().getAt(i).data.status === "Uploaded")) { 
           store.getData().getAt(i).data.status = "Uploading"; 
           store.getData().getAt(i).commit(); 
           //replace "insert your upload url here" with the real url 
           postDocument("insert your upload url here", store, i); 
          } 
         } 

        } 
       }, { 
        text: "Erase EVERYTHING", 
        handler: function() { 
         store.reload(); 
        } 
       }, { 
        text: "Erase uploaded files", 
        handler: function() { 
         for (var i = 0; i < store.data.items.length; i++) { 
          var record = store.getData().getAt(i); 
          if ((record.data.status === "Uploaded")) { 
           store.remove(record); 
           i--; 
          } 
         } 
        } 
       }, { 
        text: "Erase selected files", 
        handler: function() { 
         store.remove(Ext.getCmp('UploadGrid').getSelection()); 
        } 
       }] 


      }], 

      padding: 20 


     }); 

    }, 

    rendererStatus: function(value, metaData, record, rowIndex, colIndex, store) { 
     var color = "grey"; 
     if (value === "Ready") { 
      color = "blue"; 
     } else if (value === "Uploading") { 
      color = "orange"; 
     } else if (value === "Uploaded") { 
      color = "green"; 
     } else if (value === "Error") { 
      color = "red"; 
     } 
     metaData.tdStyle = 'color:' + color + ";"; 
     return value; 
    }, 

    postDocument: function(url, store, i) { 
     var xhr = new XMLHttpRequest(); 
     var fd = new FormData(); 
     fd.append("serverTimeDiff", 0); 
     xhr.open("POST", url, true); 
     fd.append('index', i); 
     fd.append('file', store.getData().getAt(i).data.file); 
     //xhr.setRequestHeader("Content-Type","multipart/form-data"); 
     xhr.setRequestHeader("serverTimeDiff", 0); 
     xhr.onreadystatechange = function() { 
      if (xhr.readyState == 4 && xhr.status == 200) { 
       //handle the answer, in order to detect any server side error 
       if (Ext.decode(xhr.responseText).success) { 
        store.getData().getAt(i).data.status = "Uploaded"; 
       } else { 
        store.getData().getAt(i).data.status = "Error"; 
       } 
       store.getData().getAt(i).commit(); 
      } else if (xhr.readyState == 4 && xhr.status == 404) { 
       store.getData().getAt(i).data.status = "Error"; 
       store.getData().getAt(i).commit(); 
      } 
     }; 
     // Initiate a multipart/form-data upload 
     xhr.send(fd); 
    } 
}); 
2

爲了支持拖放文件的&下降,您可以使用以下events
dropdragstartdragenterdragoverdragleavedragexit

工作的示例:https://fiddle.sencha.com/#fiddle/10v9

Ext.application({ 
    name: 'Fiddle', 

    launch: function() { 

     var store = Ext.create('Ext.data.Store', { 
      fields: ['name', 'size', 'file'] 
     }); 

     Ext.widget('container', { 

      renderTo: Ext.getBody(), 

      items: [{ 
       xtype: 'grid', 

       columns: [{ 
        header: 'Name', 
        dataIndex: 'name', 
        flex: 2 
       }, { 
        header: 'Size', 
        dataIndex: 'size', 
        flex: 1, 
        renderer: Ext.util.Format.fileSize 
       }], 

       viewConfig: { 
        emptyText: 'Drop Files Here', 
        deferEmptyText: false 
       }, 
       store: store, 

       listeners: { 

        drop: { 
         element: 'el', 
         fn: 'drop' 
        }, 

        dragstart: { 
         element: 'el', 
         fn: 'addDropZone' 
        }, 

        dragenter: { 
         element: 'el', 
         fn: 'addDropZone' 
        }, 

        dragover: { 
         element: 'el', 
         fn: 'addDropZone' 
        }, 

        dragleave: { 
         element: 'el', 
         fn: 'removeDropZone' 
        }, 

        dragexit: { 
         element: 'el', 
         fn: 'removeDropZone' 
        }, 

       }, 

       noop: function(e) { 
        e.stopEvent(); 
       }, 

       addDropZone: function(e) { 
        if (!e.browserEvent.dataTransfer || Ext.Array.from(e.browserEvent.dataTransfer.types).indexOf('Files') === -1) { 
         return; 
        } 

        e.stopEvent(); 

        this.addCls('drag-over'); 
       }, 

       removeDropZone: function(e) { 
        var el = e.getTarget(), 
         thisEl = this.getEl(); 

        e.stopEvent(); 


        if (el === thisEl.dom) { 
         this.removeCls('drag-over'); 
         return; 
        } 

        while (el !== thisEl.dom && el && el.parentNode) { 
         el = el.parentNode; 
        } 

        if (el !== thisEl.dom) { 
         this.removeCls('drag-over'); 
        } 

       }, 

       drop: function(e) { 
        e.stopEvent(); 

        Ext.Array.forEach(Ext.Array.from(e.browserEvent.dataTransfer.files), function(file) { 
         store.add({ 
          file: file, 
          name: file.name, 
          size: file.size 
         }); 
         console.log(file); 
        }); 

        this.removeCls('drag-over'); 
       } 


      }], 

      padding: 20 


     }); 

    } 
}); 
+0

感謝您的回答:我查看了您的代碼。 我認爲,爲了將丟棄的文件提交給服務器,我必須實例化一個FileReader(就像本示例https://fiddle.sencha.com/#fiddle/n9t提供的那個),並提交一個Ajax POST請求到服務器,我是否正確? –

+0

我不認爲你需要'FileReader',你可以使用'FormData'。 –

1

我使用了一個解決方案,我已經在煎茶論壇發現:

Ext.define('FileDropper', { 
    extend: 'Ext.plugin.Abstract', 
    alias: 'plugin.filedropper', 

    overCls: '', 

    init: function(c) { 
     this.target = c; 
     c.on({ 
      element: 'el', 
      scope: this, 
      dragover: this.onDragOver, 
      dragenter: this.onDragEnter, 
      dragLeave: this.onDragLeave, 
      drop: this.onDrop 
     }); 
    }, 

    onDragOver: function(e) { 
     e.stopEvent(); 
    }, 

    onDragEnter: function(e) { 
     this.target.addCls(this.overCls); 
     e.stopEvent(); 
    }, 

    onDragLeave: function() { 
     this.target.removeCls(this.overCls); 
    }, 

    onDrop: function(e) { 
     var callback = this.callback, 
      scope = this.scope || this; 

     e.stopEvent(); 
     this.target.removeCls(this.overCls); 
     if (callback) { 
      callback.call(scope, e.browserEvent.dataTransfer.files); 
     } 
    } 
}); 

的插件添加到您的看法是這樣的:

Ext.define('MyPanel', { 
    extend: 'Ext.Panel', 

    // ... your content 

    plugins: [{ 
     ptype: 'filedroppper' 
     overCls: 'foo' 
     callback: function(files) { 
      // handle your upload 
     } 
    }] 
}); 

您只需處理回調中丟棄的文件:

callback: function (files) { 
     var url = 'example.org' 
     var xhr = new XMLHttpRequest(); 
     var fd = new FormData(); 

     xhr.open("POST", url, true); 
     xhr.onreadystatechange = function() { 
      if (xhr.readyState == 4 && xhr.status == 200) { 
       // Handle response. 
       alert(xhr.responseText); // handle response. 
      } 
     }; 

     for (var i = 0; i < files.length; i++) { 
      fd.append('files', files.item(i)); 
     } 

     // Initiate a multipart/form-data upload 
     xhr.send(fd); 
    } 

但是,如果您使用FormData()確保您不必支持舊瀏覽器。

+0

感謝您的回答:不幸的是,我無法打開鏈接(我沒有訪問該頁面的權限)。 –

+0

我更新了我的答案,並添加了我寫的插件。 – xdn