我目前有一個Web應用程序,其視圖使用ExtJS 6編寫:我們當前使用Java小程序,其目的是允許用戶將文件系統中的文件拖放到Web服務器。 我的目標是刪除該小程序,並處理使用ExtJS6拖放&:這可能嗎?使用ExtJS拖放文件6
我試圖在文檔中搜索它,但我發現的唯一主題(https://docs.sencha.com/extjs/6.0/core_concepts/drag_drop.html)是關於拖放框架元素的。
我目前有一個Web應用程序,其視圖使用ExtJS 6編寫:我們當前使用Java小程序,其目的是允許用戶將文件系統中的文件拖放到Web服務器。 我的目標是刪除該小程序,並處理使用ExtJS6拖放&:這可能嗎?使用ExtJS拖放文件6
我試圖在文檔中搜索它,但我發現的唯一主題(https://docs.sencha.com/extjs/6.0/core_concepts/drag_drop.html)是關於拖放框架元素的。
包含在此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);
}
});
爲了支持拖放文件的&下降,您可以使用以下events:
drop
,dragstart
,dragenter
,dragover
,dragleave
,dragexit
。
工作的示例: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
});
}
});
感謝您的回答:我查看了您的代碼。 我認爲,爲了將丟棄的文件提交給服務器,我必須實例化一個FileReader(就像本示例https://fiddle.sencha.com/#fiddle/n9t提供的那個),並提交一個Ajax POST請求到服務器,我是否正確? –
我不認爲你需要'FileReader',你可以使用'FormData'。 –
我使用了一個解決方案,我已經在煎茶論壇發現:
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()確保您不必支持舊瀏覽器。
感謝您的回答:不幸的是,我無法打開鏈接(我沒有訪問該頁面的權限)。 –
我更新了我的答案,並添加了我寫的插件。 – xdn
拖放基本上拖動DOM節點從一個容器到另一個,所以你實際上並沒有拖動文件,您拖動,將代表文件的節點。你打算如何列出你的文件系統?您如何計劃訪問您的文件系統? PHP + Treepanel? HTML5 + Treepanel? –
感謝您的問題:我認爲,在我的情況下,最好的選擇是HTML5 + TreePanel –