1
0
Fork 0

Added a drag & drop upload zip field. Added explaination texts for zip and github

This commit is contained in:
Michael Hackstein 2014-12-15 16:59:12 +01:00
parent 2c026cecb4
commit 88e304fce0
5 changed files with 712 additions and 57 deletions

View File

@ -0,0 +1,534 @@
/*!
* jQuery Upload File Plugin
* version: 3.1.0
* @requires jQuery v1.5 or later & form plugin
* Copyright (c) 2013 Ravishanker Kusuma
* http://hayageek.com/
*/
(function ($) {
if ($.fn.ajaxForm == undefined) {
$.getScript("http://malsup.github.io/jquery.form.js");
}
var feature = {};
feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
feature.formdata = window.FormData !== undefined;
$.fn.uploadFile = function (options) {
// This is the easiest way to have default options.
var s = $.extend({
// These are the defaults.
url: "",
method: "POST",
enctype: "multipart/form-data",
formData: null,
returnType: null,
allowedTypes: "*",
fileName: "file",
formData: {},
dynamicFormData: function () {
return {};
},
maxFileSize: -1,
multiple: true,
dragDrop: true,
autoSubmit: true,
showCancel: true,
showAbort: true,
showDone: true,
showDelete:false,
showError: true,
showStatusAfterSuccess: true,
showStatusAfterError: true,
showFileCounter:true,
fileCounterStyle:"). ",
showProgress:false,
onSelect:function(files){ return true;},
onSubmit: function (files, xhr) {},
onSuccess: function (files, response, xhr) {},
onError: function (files, status, message) {},
deleteCallback: false,
afterUploadAll: false,
uploadButtonClass: "ajax-file-upload",
dragDropStr: "<span><b>Drag &amp; Drop Files</b></span>",
abortStr: "Abort",
cancelStr: "Cancel",
deletelStr: "Delete",
doneStr: "Done",
multiDragErrorStr: "Multiple File Drag &amp; Drop is not allowed.",
extErrorStr: "is not allowed. Allowed extensions: ",
sizeErrorStr: "is not allowed. Allowed Max size: ",
uploadErrorStr: "Upload is not allowed"
}, options);
this.fileCounter = 1;
this.fCounter = 0; //failed uploads
this.sCounter = 0; //success uploads
this.tCounter = 0; //total uploads
var formGroup = "ajax-file-upload-" + (new Date().getTime());
this.formGroup = formGroup;
this.hide();
this.errorLog = $("<div></div>"); //Writing errors
this.after(this.errorLog);
this.responses = [];
if (!feature.formdata) //check drag drop enabled.
{
s.dragDrop = false;
}
var obj = this;
var uploadLabel = $('<div>' + $(this).html() + '</div>');
$(uploadLabel).addClass(s.uploadButtonClass);
//wait form ajax Form plugin and initialize
(function checkAjaxFormLoaded() {
if ($.fn.ajaxForm) {
if (s.dragDrop) {
var dragDrop = $('<div class="ajax-upload-dragdrop" style="vertical-align:top;"></div>');
$(obj).before(dragDrop);
$(dragDrop).append(uploadLabel);
$(dragDrop).append($(s.dragDropStr));
setDragDropHandlers(obj, s, dragDrop);
} else {
$(obj).before(uploadLabel);
}
createCutomInputFile(obj, formGroup, s, uploadLabel);
} else window.setTimeout(checkAjaxFormLoaded, 10);
})();
this.startUpload = function () {
$("." + this.formGroup).each(function (i, items) {
if ($(this).is('form')) $(this).submit();
});
}
this.stopUpload = function () {
$(".ajax-file-upload-red").each(function (i, items) {
if ($(this).hasClass(obj.formGroup)) $(this).click();
});
}
this.getResponses = function () {
return this.responses;
}
var checking = false;
function checkPendingUploads() {
if (s.afterUploadAll && !checking) {
checking = true;
(function checkPending() {
if (obj.sCounter != 0 && (obj.sCounter + obj.fCounter == obj.tCounter)) {
s.afterUploadAll(obj);
checking = false;
} else window.setTimeout(checkPending, 100);
})();
}
}
function setDragDropHandlers(obj, s, ddObj) {
ddObj.on('dragenter', function (e) {
e.stopPropagation();
e.preventDefault();
$(this).css('border', '2px solid #A5A5C7');
});
ddObj.on('dragover', function (e) {
e.stopPropagation();
e.preventDefault();
});
ddObj.on('drop', function (e) {
$(this).css('border', '2px dotted #A5A5C7');
e.preventDefault();
obj.errorLog.html("");
var files = e.originalEvent.dataTransfer.files;
if (!s.multiple && files.length > 1) {
if (s.showError) $("<div style='color:red;'>" + s.multiDragErrorStr + "</div>").appendTo(obj.errorLog);
return;
}
if(s.onSelect(files) == false)
return;
serializeAndUploadFiles(s, obj, files);
});
$(document).on('dragenter', function (e) {
e.stopPropagation();
e.preventDefault();
});
$(document).on('dragover', function (e) {
e.stopPropagation();
e.preventDefault();
ddObj.css('border', '2px dotted #A5A5C7');
});
$(document).on('drop', function (e) {
e.stopPropagation();
e.preventDefault();
ddObj.css('border', '2px dotted #A5A5C7');
});
}
function getSizeStr(size) {
var sizeStr = "";
var sizeKB = size / 1024;
if (parseInt(sizeKB) > 1024) {
var sizeMB = sizeKB / 1024;
sizeStr = sizeMB.toFixed(2) + " MB";
} else {
sizeStr = sizeKB.toFixed(2) + " KB";
}
return sizeStr;
}
function serializeData(extraData) {
var serialized = [];
if (jQuery.type(extraData) == "string") {
serialized = extraData.split('&');
} else {
serialized = $.param(extraData).split('&');
}
var len = serialized.length;
var result = [];
var i, part;
for (i = 0; i < len; i++) {
serialized[i] = serialized[i].replace(/\+/g, ' ');
part = serialized[i].split('=');
result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
}
return result;
}
function serializeAndUploadFiles(s, obj, files) {
for (var i = 0; i < files.length; i++) {
if (!isFileTypeAllowed(obj, s, files[i].name)) {
if (s.showError) $("<div style='color:red;'><b>" + files[i].name + "</b> " + s.extErrorStr + s.allowedTypes + "</div>").appendTo(obj.errorLog);
continue;
}
if (s.maxFileSize != -1 && files[i].size > s.maxFileSize) {
if (s.showError) $("<div style='color:red;'><b>" + files[i].name + "</b> " + s.sizeErrorStr + getSizeStr(s.maxFileSize) + "</div>").appendTo(obj.errorLog);
continue;
}
var ts = s;
var fd = new FormData();
var fileName = s.fileName.replace("[]", "");
fd.append(fileName, files[i]);
var extraData = s.formData;
if (extraData) {
var sData = serializeData(extraData);
for (var j = 0; j < sData.length; j++) {
if (sData[j]) {
fd.append(sData[j][0], sData[j][1]);
}
}
}
ts.fileData = fd;
var pd = new createProgressDiv(obj, s);
var fileNameStr="";
if(s.showFileCounter)
fileNameStr = obj.fileCounter + s.fileCounterStyle + files[i].name
else
fileNameStr = files[i].name;
pd.filename.html(fileNameStr);
var form = $("<form style='display:block; position:absolute;left: 150px;' class='" + obj.formGroup + "' method='" + s.method + "' action='" + s.url + "' enctype='" + s.enctype + "'></form>");
form.appendTo('body');
var fileArray = [];
fileArray.push(files[i].name);
ajaxFormSubmit(form, ts, pd, fileArray, obj);
obj.fileCounter++;
}
}
function isFileTypeAllowed(obj, s, fileName) {
var fileExtensions = s.allowedTypes.toLowerCase().split(",");
var ext = fileName.split('.').pop().toLowerCase();
if (s.allowedTypes != "*" && jQuery.inArray(ext, fileExtensions) < 0) {
return false;
}
return true;
}
function createCutomInputFile(obj, group, s, uploadLabel) {
var fileUploadId = "ajax-upload-id-" + (new Date().getTime());
var form = $("<form method='" + s.method + "' action='" + s.url + "' enctype='" + s.enctype + "'></form>");
var fileInputStr = "<input type='file' id='" + fileUploadId + "' name='" + s.fileName + "'/>";
if (s.multiple) {
if (s.fileName.indexOf("[]") != s.fileName.length - 2) // if it does not endwith
{
s.fileName += "[]";
}
fileInputStr = "<input type='file' id='" + fileUploadId + "' name='" + s.fileName + "' multiple/>";
}
var fileInput = $(fileInputStr).appendTo(form);
fileInput.change(function () {
obj.errorLog.html("");
var fileExtensions = s.allowedTypes.toLowerCase().split(",");
var fileArray = [];
if (this.files) //support reading files
{
for (i = 0; i < this.files.length; i++)
{
fileArray.push(this.files[i].name);
}
if(s.onSelect(this.files) == false)
return;
} else {
var filenameStr = $(this).val();
var flist = [];
fileArray.push(filenameStr);
if (!isFileTypeAllowed(obj, s, filenameStr)) {
if (s.showError) $("<div style='color:red;'><b>" + filenameStr + "</b> " + s.extErrorStr + s.allowedTypes + "</div>").appendTo(obj.errorLog);
return;
}
//fallback for browser without FileAPI
flist.push({name:filenameStr,size:'NA'});
if(s.onSelect(flist) == false)
return;
}
uploadLabel.unbind("click");
form.hide();
createCutomInputFile(obj, group, s, uploadLabel);
form.addClass(group);
if (feature.fileapi && feature.formdata) //use HTML5 support and split file submission
{
form.removeClass(group); //Stop Submitting when.
var files = this.files;
serializeAndUploadFiles(s, obj, files);
} else {
var fileList = "";
for (var i = 0; i < fileArray.length; i++) {
if(s.showFileCounter)
fileList += obj.fileCounter + s.fileCounterStyle + fileArray[i]+"<br>";
else
fileList += fileArray[i]+"<br>";;
obj.fileCounter++;
}
var pd = new createProgressDiv(obj, s);
pd.filename.html(fileList);
ajaxFormSubmit(form, s, pd, fileArray, obj);
}
});
form.css({'margin':0,'padding':0});
var uwidth=$(uploadLabel).width()+10;
if(uwidth == 10)
uwidth =120;
var uheight=uploadLabel.height()+10;
if(uheight == 10)
uheight = 35;
uploadLabel.css({position: 'relative',overflow:'hidden',cursor:'default'});
fileInput.css({position: 'absolute','cursor':'pointer',
'top': '0px',
'width': uwidth,
'height':uheight,
'left': '0px',
'z-index': '100',
'opacity': '0.0',
'filter':'alpha(opacity=0)',
'-ms-filter':"alpha(opacity=0)",
'-khtml-opacity':'0.0',
'-moz-opacity':'0.0'
});
form.appendTo(uploadLabel);
//dont hide it, but move it to
/* form.css({
margin: 0,
padding: 0,
display: 'block',
position: 'absolute',
left: '50px'
});
if (navigator.appVersion.indexOf("MSIE ") != -1) //IE Browser
{
uploadLabel.attr('for', fileUploadId);
} else {
uploadLabel.click(function () {
fileInput.click();
});
}*/
}
function createProgressDiv(obj, s) {
this.statusbar = $("<div class='ajax-file-upload-statusbar'></div>");
this.filename = $("<div class='ajax-file-upload-filename'></div>").appendTo(this.statusbar);
this.progressDiv = $("<div class='ajax-file-upload-progress'>").appendTo(this.statusbar).hide();
this.progressbar = $("<div class='ajax-file-upload-bar " + obj.formGroup + "'></div>").appendTo(this.progressDiv);
this.abort = $("<div class='ajax-file-upload-red " + obj.formGroup + "'>" + s.abortStr + "</div>").appendTo(this.statusbar).hide();
this.cancel = $("<div class='ajax-file-upload-red'>" + s.cancelStr + "</div>").appendTo(this.statusbar).hide();
this.done = $("<div class='ajax-file-upload-green'>" + s.doneStr + "</div>").appendTo(this.statusbar).hide();
this.del = $("<div class='ajax-file-upload-red'>" + s.deletelStr + "</div>").appendTo(this.statusbar).hide();
obj.errorLog.after(this.statusbar);
return this;
}
function ajaxFormSubmit(form, s, pd, fileArray, obj) {
var currentXHR = null;
var options = {
cache: false,
contentType: false,
processData: false,
forceSync: false,
data: s.formData,
formData: s.fileData,
dataType: s.returnType,
beforeSubmit: function (formData, $form, options) {
if (s.onSubmit.call(this, fileArray) != false) {
var dynData = s.dynamicFormData();
if (dynData) {
var sData = serializeData(dynData);
if (sData) {
for (var j = 0; j < sData.length; j++) {
if (sData[j]) {
if (s.fileData != undefined) options.formData.append(sData[j][0], sData[j][1]);
else options.data[sData[j][0]] = sData[j][1];
}
}
}
}
obj.tCounter += fileArray.length;
//window.setTimeout(checkPendingUploads, 1000); //not so critical
checkPendingUploads();
return true;
}
pd.statusbar.append("<div style='color:red;'>" + s.uploadErrorStr + "</div>");
pd.cancel.show()
form.remove();
pd.cancel.click(function () {
pd.statusbar.remove();
});
return false;
},
beforeSend: function (xhr, o) {
pd.progressDiv.show();
pd.cancel.hide();
pd.done.hide();
if (s.showAbort) {
pd.abort.show();
pd.abort.click(function () {
xhr.abort();
});
}
if (!feature.formdata) //For iframe based push
{
pd.progressbar.width('5%');
} else pd.progressbar.width('1%'); //Fix for small files
},
uploadProgress: function (event, position, total, percentComplete) {
//Fix for smaller file uploads in MAC
if(percentComplete > 98) percentComplete =98;
var percentVal = percentComplete + '%';
if (percentComplete > 1) pd.progressbar.width(percentVal)
if(s.showProgress)
{
pd.progressbar.html(percentVal);
pd.progressbar.css('text-align', 'center');
}
},
success: function (data, message, xhr) {
obj.responses.push(data);
pd.progressbar.width('100%')
if(s.showProgress)
{
pd.progressbar.html('100%');
pd.progressbar.css('text-align', 'center');
}
pd.abort.hide();
s.onSuccess.call(this, fileArray, data, xhr);
if (s.showStatusAfterSuccess) {
if (s.showDone) {
pd.done.show();
pd.done.click(function () {
pd.statusbar.hide("slow");
pd.statusbar.remove();
});
} else {
pd.done.hide();
}
if(s.showDelete)
{
pd.del.show();
pd.del.click(function () {
if(s.deleteCallback) s.deleteCallback.call(this, data,pd);
});
}
else
{
pd.del.hide();
}
} else {
pd.statusbar.hide("slow");
pd.statusbar.remove();
}
form.remove();
obj.sCounter += fileArray.length;
},
error: function (xhr, status, errMsg) {
pd.abort.hide();
if (xhr.statusText == "abort") //we aborted it
{
pd.statusbar.hide("slow");
} else {
s.onError.call(this, fileArray, status, errMsg);
if (s.showStatusAfterError) {
pd.progressDiv.hide();
pd.statusbar.append("<span style='color:red;'>ERROR: " + errMsg + "</span>");
} else {
pd.statusbar.hide();
pd.statusbar.remove();
}
}
form.remove();
obj.fCounter += fileArray.length;
}
};
if (s.autoSubmit) {
form.ajaxSubmit(options);
} else {
if (s.showCancel) {
pd.cancel.show();
pd.cancel.click(function () {
form.remove();
pd.statusbar.remove();
});
}
form.ajaxForm(options);
}
}
return this;
}
}(jQuery));

View File

@ -67,7 +67,9 @@
</div>
<div class="tab-pane" id="github">
<div>The repository has to be public. The version has to be a git tag LINKTOTAG.</div>
<div>
Download a foxx application from a public <a href="https://www.github.com">github.com</a> repository. In order to define a version please add a <a href="https://git-scm.com/book/en/v2/Git-Basics-Tagging">git tag</a> to your repository using the following format: "v1.2.3". To connect to github your username and the name of the repository are sufficient.
</div>
<div>
<table>
<tr class="tableRow">
@ -91,19 +93,15 @@
</div>
<div class="tab-pane" id="zip">
<div>Todo how ZIP.</div>
<div>
<table>
<tr class="tableRow">
<th class="collectionInfoTh">
File*:
</th>
<th class="collectionInfoTh">
<input id="zip-file" name="zip-file" type="file"/>
</th>
</tr>
</table>
<p>
Upload a ZIP-packed foxx application to ArangoDB.
The ZIP file has to be created from the folder containing the manifest.json file of your App, do not include the databases folder structure created by ArangoDB.
This is also compatible with the download format for ZIP files on <a href="https://www.github.com">github.com</a>.
Remember to change to a new version number in the manifest.json when uploading an update.
</p>
</div>
<div id="upload-foxx-zip">Upload Foxx.zip</div>
</div>
</div>
</script>

View File

@ -371,7 +371,40 @@
///// NEW CODE
installFoxxFromZip: function() {
installFoxxFromZip: function(files, data) {
var self = this;
$.ajax({
type: "POST",
async: false,
url: "/_admin/aardvark/foxxes/inspect",
data: JSON.stringify(data),
contentType: "application/json"
}).done(function(res) {
$.ajax({
type: "POST",
async: false,
url: '/_admin/foxx/fetch',
data: JSON.stringify({
name: res.name,
version: res.version,
filename: res.filename
}),
processData: false
}).done(function (result) {
if (result.error === false) {
window.modalView.hide();
self.showConfigureDialog(res.configuration, res.name, res.version);
}
}).fail(function (err) {
var error = JSON.parse(err.responseText);
arangoHelper.arangoError("Error: " + error.errorMessage);
});
}).fail(function(err) {
var error = JSON.parse(err.responseText);
arangoHelper.arangoError("Error: " + error.error);
});
self.hideImportModal();
/*
var self = this;
if (this.allowUpload) {
this.showSpinner();
@ -384,53 +417,14 @@
contentType: 'application/octet-stream',
complete: function(res) {
if (res.readyState === 4) {
if (res.status === 201) {
$.ajax({
type: "POST",
async: false,
url: "/_admin/aardvark/foxxes/inspect",
data: res.responseText,
contentType: "application/json"
}).done(function(res) {
console.log("Peter2", res);
$.ajax({
type: "POST",
async: false,
url: '/_admin/foxx/fetch',
data: JSON.stringify({
name: res.name,
version: res.version,
filename: res.filename
}),
processData: false
}).done(function (result) {
console.log("Peter", result);
if (result.error === false) {
window.modalView.hide();
self.showConfigureDialog(res.configuration, res.name, res.version);
}
}).fail(function (err) {
self.hideSpinner();
var error = JSON.parse(err.responseText);
arangoHelper.arangoError("Error: " + error.errorMessage);
});
}).fail(function(err) {
self.hideSpinner();
var error = JSON.parse(err.responseText);
arangoHelper.arangoError("Error: " + error.error);
});
delete self.file;
self.allowUpload = false;
self.hideSpinner();
self.hideImportModal();
return;
}
if (res.status === 201)
}
self.hideSpinner();
arangoHelper.arangoError("Upload error");
}
});
}
*/
},
installFoxxFromStore: function(e) {
@ -685,9 +679,9 @@
event.preventDefault();
var buttons = [];
var modalEvents = {
"click #infoTab a": this.switchModalButton.bind(this),
"click .install-app" : this.installFoxxFromStore.bind(this),
"change #zip-file" : this.uploadSetup.bind(this)
"click #infoTab a" : this.switchModalButton.bind(this),
"click .install-app" : this.installFoxxFromStore.bind(this),
"change #zip-file" : this.uploadSetup.bind(this)
};
buttons.push(
window.modalView.createSuccessButton("Generate", this.addAppAction.bind(this))
@ -706,6 +700,11 @@
minimumResultsForSearch: -1,
width: "336px"
});
$("#upload-foxx-zip").uploadFile({
url: "/_api/upload",
allowedTypes: "zip",
onSuccess: this.installFoxxFromZip.bind(this)
});
var listTempl = this.appStoreTemplate;
$.get("foxxes/fishbowl", function(list) {
var table = $("#appstore-content");

View File

@ -0,0 +1,123 @@
.ajax-file-upload-statusbar {
border: 1px solid #0ba1b5;
margin-top: 10px;
width: 420px;
margin-right: 10px;
margin: 5px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
padding: 5px 5px 5px 5px
}
.ajax-file-upload-filename {
width: 100%;
height: auto;
margin: 0 5px 5px 10px;
color: #807579
}
.ajax-file-upload-progress {
margin: 0 10px 5px 10px;
position: relative;
width: 250px;
border: 1px solid #ddd;
padding: 1px;
border-radius: 3px;
display: inline-block
}
.ajax-file-upload-bar {
background-color: #0ba1b5;
width: 0;
height: 20px;
border-radius: 3px;
color:#FFFFFF;
}
.ajax-file-upload-percent {
position: absolute;
display: inline-block;
top: 3px;
left: 48%
}
.ajax-file-upload-red {
-moz-box-shadow: inset 0 39px 0 -24px #e67a73;
-webkit-box-shadow: inset 0 39px 0 -24px #e67a73;
box-shadow: inset 0 39px 0 -24px #e67a73;
background-color: #e4685d;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
display: inline-block;
color: #fff;
font-family: arial;
font-size: 13px;
font-weight: normal;
padding: 4px 15px;
text-decoration: none;
text-shadow: 0 1px 0 #b23e35;
cursor: pointer;
vertical-align: top;
margin-right:5px;
}
.ajax-file-upload-green {
background-color: #77b55a;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
margin: 0;
padding: 0;
display: inline-block;
color: #fff;
font-family: arial;
font-size: 13px;
font-weight: normal;
padding: 4px 15px;
text-decoration: none;
cursor: pointer;
text-shadow: 0 1px 0 #5b8a3c;
vertical-align: top;
margin-right:5px;
}
.ajax-file-upload {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
font-weight: bold;
padding: 15px 20px;
cursor:pointer;
line-height:20px;
height:25px;
margin:0 10px 10px 0;
display: inline-block;
background: #fff;
border: 1px solid #e8e8e8;
color: #888;
text-decoration: none;
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-moz-box-shadow: 0 2px 0 0 #e8e8e8;
-webkit-box-shadow: 0 2px 0 0 #e8e8e8;
box-shadow: 0 2px 0 0 #e8e8e8;
padding: 6px 10px 4px 10px;
color: #fff;
background: #2f8ab9;
border: none;
-moz-box-shadow: 0 2px 0 0 #13648d;
-webkit-box-shadow: 0 2px 0 0 #13648d;
box-shadow: 0 2px 0 0 #13648d;
vertical-align:middle;
}
.ajax-file-upload:hover {
background: #3396c9;
-moz-box-shadow: 0 2px 0 0 #15719f;
-webkit-box-shadow: 0 2px 0 0 #15719f;
box-shadow: 0 2px 0 0 #15719f;
}
.ajax-upload-dragdrop {
border:2px dotted #A5A5C7;
width:420px;
color: #DADCE3;
text-align:left;
vertical-align:middle;
padding:10px 10px 0px 10px;
}

View File

@ -215,6 +215,7 @@
"frontend/js/lib/jquery.wiggle.min.js",
"frontend/js/lib/jquery.contextmenu.js",
"frontend/js/lib/jquery.hotkeys.js",
"frontend/js/lib/jquery.uploadfile.js",
"frontend/js/lib/select2.min.js",
"frontend/js/lib/handlebars-1.0.rc.1.js",
"frontend/js/lib/underscore.js",