mirror of
https://github.com/Dahlgren/arma-server-web-admin.git
synced 2024-08-30 17:22:10 +00:00
Mission upload
This commit is contained in:
parent
d06cd5f064
commit
4f452ba588
@ -1,32 +0,0 @@
|
|||||||
define(function (require) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var $ = require('jquery'),
|
|
||||||
_ = require('underscore'),
|
|
||||||
Backbone = require('backbone'),
|
|
||||||
Marionette = require('marionette'),
|
|
||||||
FormView = require('marionette-formview'),
|
|
||||||
Settings = require('app/models/settings'),
|
|
||||||
tpl = require('text!tpl/forms/settings.html');
|
|
||||||
|
|
||||||
return FormView.extend({
|
|
||||||
template: _.template(tpl),
|
|
||||||
|
|
||||||
fields: {
|
|
||||||
path: {
|
|
||||||
el: ".mission",
|
|
||||||
required: "Please select a file."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize: function () {
|
|
||||||
var self = this;
|
|
||||||
new Mission().fetch({success: function (model, response, options) {
|
|
||||||
self.model = model;
|
|
||||||
self.runInitializers();
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
40
public/js/app/views/missions/form.js
Normal file
40
public/js/app/views/missions/form.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
define(function (require) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var $ = require('jquery'),
|
||||||
|
_ = require('underscore'),
|
||||||
|
Backbone = require('backbone'),
|
||||||
|
Marionette = require('marionette'),
|
||||||
|
FormView = require('marionette-formview'),
|
||||||
|
IframeTransport = require('jquery.iframe-transport'),
|
||||||
|
Mission = require('app/models/mission'),
|
||||||
|
tpl = require('text!tpl/missions/form.html');
|
||||||
|
|
||||||
|
return Marionette.ItemView.extend({
|
||||||
|
template: _.template(tpl),
|
||||||
|
|
||||||
|
initialize: function (options) {
|
||||||
|
this.missions = options.missions;
|
||||||
|
this.model = new Mission();
|
||||||
|
this.bind("ok", this.submit);
|
||||||
|
},
|
||||||
|
|
||||||
|
submit: function (modal) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
modal.preventClose();
|
||||||
|
|
||||||
|
var $form = $("form");
|
||||||
|
$.ajax("/api/missions", {
|
||||||
|
files: $form.find(":file"),
|
||||||
|
iframe: true
|
||||||
|
}).complete(function(data) {
|
||||||
|
modal.close();
|
||||||
|
self.missions.fetch();
|
||||||
|
Backbone.history.navigate('#missions', true)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -7,6 +7,7 @@ define(function (require) {
|
|||||||
Backbone = require('backbone'),
|
Backbone = require('backbone'),
|
||||||
Marionette = require('marionette'),
|
Marionette = require('marionette'),
|
||||||
ListItemView = require('app/views/missions/list_item'),
|
ListItemView = require('app/views/missions/list_item'),
|
||||||
|
FormView = require('app/views/missions/form'),
|
||||||
tpl = require('text!tpl/missions/list.html'),
|
tpl = require('text!tpl/missions/list.html'),
|
||||||
|
|
||||||
template = _.template(tpl);
|
template = _.template(tpl);
|
||||||
@ -15,5 +16,15 @@ define(function (require) {
|
|||||||
itemView: ListItemView,
|
itemView: ListItemView,
|
||||||
itemViewContainer: "tbody",
|
itemViewContainer: "tbody",
|
||||||
template: template,
|
template: template,
|
||||||
|
|
||||||
|
events: {
|
||||||
|
"click #upload": "upload"
|
||||||
|
},
|
||||||
|
|
||||||
|
upload: function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var view = new FormView({missions: this.collection});
|
||||||
|
new Backbone.BootstrapModal({ content: view }).open()
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
247
public/js/lib/jquery.iframe-transport.js
Normal file
247
public/js/lib/jquery.iframe-transport.js
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
// This [jQuery](https://jquery.com/) plugin implements an `<iframe>`
|
||||||
|
// [transport](https://api.jquery.com/jQuery.ajax/#extending-ajax) so that
|
||||||
|
// `$.ajax()` calls support the uploading of files using standard HTML file
|
||||||
|
// input fields. This is done by switching the exchange from `XMLHttpRequest`
|
||||||
|
// to a hidden `iframe` element containing a form that is submitted.
|
||||||
|
|
||||||
|
// The [source for the plugin](https://github.com/cmlenz/jquery-iframe-transport)
|
||||||
|
// is available on [Github](https://github.com/) and licensed under the [MIT
|
||||||
|
// license](https://github.com/cmlenz/jquery-iframe-transport/blob/master/LICENSE).
|
||||||
|
|
||||||
|
// ## Usage
|
||||||
|
|
||||||
|
// To use this plugin, you simply add an `iframe` option with the value `true`
|
||||||
|
// to the Ajax settings an `$.ajax()` call, and specify the file fields to
|
||||||
|
// include in the submssion using the `files` option, which can be a selector,
|
||||||
|
// jQuery object, or a list of DOM elements containing one or more
|
||||||
|
// `<input type="file">` elements:
|
||||||
|
|
||||||
|
// $("#myform").submit(function() {
|
||||||
|
// $.ajax(this.action, {
|
||||||
|
// files: $(":file", this),
|
||||||
|
// iframe: true
|
||||||
|
// }).complete(function(data) {
|
||||||
|
// console.log(data);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
// The plugin will construct hidden `<iframe>` and `<form>` elements, add the
|
||||||
|
// file field(s) to that form, submit the form, and process the response.
|
||||||
|
|
||||||
|
// If you want to include other form fields in the form submission, include
|
||||||
|
// them in the `data` option, and set the `processData` option to `false`:
|
||||||
|
|
||||||
|
// $("#myform").submit(function() {
|
||||||
|
// $.ajax(this.action, {
|
||||||
|
// data: $(":text", this).serializeArray(),
|
||||||
|
// files: $(":file", this),
|
||||||
|
// iframe: true,
|
||||||
|
// processData: false
|
||||||
|
// }).complete(function(data) {
|
||||||
|
// console.log(data);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
// ### Response Data Types
|
||||||
|
|
||||||
|
// As the transport does not have access to the HTTP headers of the server
|
||||||
|
// response, it is not as simple to make use of the automatic content type
|
||||||
|
// detection provided by jQuery as with regular XHR. If you can't set the
|
||||||
|
// expected response data type (for example because it may vary depending on
|
||||||
|
// the outcome of processing by the server), you will need to employ a
|
||||||
|
// workaround on the server side: Send back an HTML document containing just a
|
||||||
|
// `<textarea>` element with a `data-type` attribute that specifies the MIME
|
||||||
|
// type, and put the actual payload in the textarea:
|
||||||
|
|
||||||
|
// <textarea data-type="application/json">
|
||||||
|
// {"ok": true, "message": "Thanks so much"}
|
||||||
|
// </textarea>
|
||||||
|
|
||||||
|
// The iframe transport plugin will detect this and pass the value of the
|
||||||
|
// `data-type` attribute on to jQuery as if it was the "Content-Type" response
|
||||||
|
// header, thereby enabling the same kind of conversions that jQuery applies
|
||||||
|
// to regular responses. For the example above you should get a Javascript
|
||||||
|
// object as the `data` parameter of the `complete` callback, with the
|
||||||
|
// properties `ok: true` and `message: "Thanks so much"`.
|
||||||
|
|
||||||
|
// ### Handling Server Errors
|
||||||
|
|
||||||
|
// Another problem with using an `iframe` for file uploads is that it is
|
||||||
|
// impossible for the javascript code to determine the HTTP status code of the
|
||||||
|
// servers response. Effectively, all of the calls you make will look like they
|
||||||
|
// are getting successful responses, and thus invoke the `done()` or
|
||||||
|
// `complete()` callbacks. You can only communicate problems using the content
|
||||||
|
// of the response payload. For example, consider using a JSON response such as
|
||||||
|
// the following to indicate a problem with an uploaded file:
|
||||||
|
|
||||||
|
// <textarea data-type="application/json">
|
||||||
|
// {"ok": false, "message": "Please only upload reasonably sized files."}
|
||||||
|
// </textarea>
|
||||||
|
|
||||||
|
// ### Compatibility
|
||||||
|
|
||||||
|
// This plugin has primarily been tested on Safari 5 (or later), Firefox 4 (or
|
||||||
|
// later), and Internet Explorer (all the way back to version 6). While I
|
||||||
|
// haven't found any issues with it so far, I'm fairly sure it still doesn't
|
||||||
|
// work around all the quirks in all different browsers. But the code is still
|
||||||
|
// pretty simple overall, so you should be able to fix it and contribute a
|
||||||
|
// patch :)
|
||||||
|
|
||||||
|
// ## Annotated Source
|
||||||
|
|
||||||
|
(function($, undefined) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Register a prefilter that checks whether the `iframe` option is set, and
|
||||||
|
// switches to the "iframe" data type if it is `true`.
|
||||||
|
$.ajaxPrefilter(function(options, origOptions, jqXHR) {
|
||||||
|
if (options.iframe) {
|
||||||
|
options.originalURL = options.url;
|
||||||
|
return "iframe";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register a transport for the "iframe" data type. It will only activate
|
||||||
|
// when the "files" option has been set to a non-empty list of enabled file
|
||||||
|
// inputs.
|
||||||
|
$.ajaxTransport("iframe", function(options, origOptions, jqXHR) {
|
||||||
|
var form = null,
|
||||||
|
iframe = null,
|
||||||
|
name = "iframe-" + $.now(),
|
||||||
|
files = $(options.files).filter(":file:enabled"),
|
||||||
|
markers = null,
|
||||||
|
accepts = null;
|
||||||
|
|
||||||
|
// This function gets called after a successful submission or an abortion
|
||||||
|
// and should revert all changes made to the page to enable the
|
||||||
|
// submission via this transport.
|
||||||
|
function cleanUp() {
|
||||||
|
files.each(function(i, file) {
|
||||||
|
var $file = $(file);
|
||||||
|
$file.data("clone").replaceWith($file);
|
||||||
|
});
|
||||||
|
form.remove();
|
||||||
|
iframe.one("load", function() { iframe.remove(); });
|
||||||
|
iframe.attr("src", "javascript:false;");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove "iframe" from the data types list so that further processing is
|
||||||
|
// based on the content type returned by the server, without attempting an
|
||||||
|
// (unsupported) conversion from "iframe" to the actual type.
|
||||||
|
options.dataTypes.shift();
|
||||||
|
|
||||||
|
// Use the data from the original AJAX options, as it doesn't seem to be
|
||||||
|
// copied over since jQuery 1.7.
|
||||||
|
// See https://github.com/cmlenz/jquery-iframe-transport/issues/6
|
||||||
|
options.data = origOptions.data;
|
||||||
|
|
||||||
|
if (files.length) {
|
||||||
|
form = $("<form enctype='multipart/form-data' method='post'></form>").
|
||||||
|
hide().attr({action: options.originalURL, target: name});
|
||||||
|
|
||||||
|
// If there is any additional data specified via the `data` option,
|
||||||
|
// we add it as hidden fields to the form. This (currently) requires
|
||||||
|
// the `processData` option to be set to false so that the data doesn't
|
||||||
|
// get serialized to a string.
|
||||||
|
if (typeof(options.data) === "string" && options.data.length > 0) {
|
||||||
|
$.error("data must not be serialized");
|
||||||
|
}
|
||||||
|
$.each(options.data || {}, function(name, value) {
|
||||||
|
if ($.isPlainObject(value)) {
|
||||||
|
name = value.name;
|
||||||
|
value = value.value;
|
||||||
|
}
|
||||||
|
$("<input type='hidden' />").attr({name: name, value: value}).
|
||||||
|
appendTo(form);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add a hidden `X-Requested-With` field with the value `IFrame` to the
|
||||||
|
// field, to help server-side code to determine that the upload happened
|
||||||
|
// through this transport.
|
||||||
|
$("<input type='hidden' value='IFrame' name='X-Requested-With' />").
|
||||||
|
appendTo(form);
|
||||||
|
|
||||||
|
// Borrowed straight from the JQuery source.
|
||||||
|
// Provides a way of specifying the accepted data type similar to the
|
||||||
|
// HTTP "Accept" header
|
||||||
|
if (options.dataTypes[0] && options.accepts[options.dataTypes[0]]) {
|
||||||
|
accepts = options.accepts[options.dataTypes[0]] +
|
||||||
|
(options.dataTypes[0] !== "*" ? ", */*; q=0.01" : "");
|
||||||
|
} else {
|
||||||
|
accepts = options.accepts["*"];
|
||||||
|
}
|
||||||
|
$("<input type='hidden' name='X-HTTP-Accept'>").
|
||||||
|
attr("value", accepts).appendTo(form);
|
||||||
|
|
||||||
|
// Move the file fields into the hidden form, but first remember their
|
||||||
|
// original locations in the document by replacing them with disabled
|
||||||
|
// clones. This should also avoid introducing unwanted changes to the
|
||||||
|
// page layout during submission.
|
||||||
|
markers = files.after(function(idx) {
|
||||||
|
var $this = $(this),
|
||||||
|
$clone = $this.clone().prop("disabled", true);
|
||||||
|
$this.data("clone", $clone);
|
||||||
|
return $clone;
|
||||||
|
}).next();
|
||||||
|
files.appendTo(form);
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
// The `send` function is called by jQuery when the request should be
|
||||||
|
// sent.
|
||||||
|
send: function(headers, completeCallback) {
|
||||||
|
iframe = $("<iframe src='javascript:false;' name='" + name +
|
||||||
|
"' id='" + name + "' style='display:none'></iframe>");
|
||||||
|
|
||||||
|
// The first load event gets fired after the iframe has been injected
|
||||||
|
// into the DOM, and is used to prepare the actual submission.
|
||||||
|
iframe.one("load", function() {
|
||||||
|
|
||||||
|
// The second load event gets fired when the response to the form
|
||||||
|
// submission is received. The implementation detects whether the
|
||||||
|
// actual payload is embedded in a `<textarea>` element, and
|
||||||
|
// prepares the required conversions to be made in that case.
|
||||||
|
iframe.one("load", function() {
|
||||||
|
var doc = this.contentWindow ? this.contentWindow.document :
|
||||||
|
(this.contentDocument ? this.contentDocument : this.document),
|
||||||
|
root = doc.documentElement ? doc.documentElement : doc.body,
|
||||||
|
textarea = root.getElementsByTagName("textarea")[0],
|
||||||
|
type = textarea && textarea.getAttribute("data-type") || null,
|
||||||
|
status = textarea && textarea.getAttribute("data-status") || 200,
|
||||||
|
statusText = textarea && textarea.getAttribute("data-statusText") || "OK",
|
||||||
|
content = {
|
||||||
|
html: root.innerHTML,
|
||||||
|
text: type ?
|
||||||
|
textarea.value :
|
||||||
|
root ? (root.textContent || root.innerText) : null
|
||||||
|
};
|
||||||
|
cleanUp();
|
||||||
|
completeCallback(status, statusText, content, type ?
|
||||||
|
("Content-Type: " + type) :
|
||||||
|
null);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Now that the load handler has been set up, submit the form.
|
||||||
|
form[0].submit();
|
||||||
|
});
|
||||||
|
|
||||||
|
// After everything has been set up correctly, the form and iframe
|
||||||
|
// get injected into the DOM so that the submission can be
|
||||||
|
// initiated.
|
||||||
|
$("body").append(form, iframe);
|
||||||
|
},
|
||||||
|
|
||||||
|
// The `abort` function is called by jQuery when the request should be
|
||||||
|
// aborted.
|
||||||
|
abort: function() {
|
||||||
|
if (iframe !== null) {
|
||||||
|
iframe.unbind("load").attr("src", "javascript:false;");
|
||||||
|
cleanUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})(jQuery);
|
@ -1,8 +0,0 @@
|
|||||||
<form class="form-horizontal" role="form">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="file" class="col-sm-2 control-label">File</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="file" class="form-control path" id="file" data-field="file" placeholder="Mission to upload">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
8
public/js/tpl/missions/form.html
Normal file
8
public/js/tpl/missions/form.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<form class="form-horizontal" role="form" enctype="multipart/form-data">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mission" class="col-sm-2 control-label">Mission File</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="file" class="form-control path" name="mission" id="mission" data-field="mission">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
@ -7,4 +7,6 @@
|
|||||||
|
|
||||||
<!-- want to insert collection items, here -->
|
<!-- want to insert collection items, here -->
|
||||||
<tbody></tbody>
|
<tbody></tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<a class="btn btn-primary" id="upload" href="#">Upload new mission</a>
|
||||||
|
@ -17,12 +17,11 @@ exports.index = function(req, res){
|
|||||||
};
|
};
|
||||||
|
|
||||||
exports.create = function(req, res){
|
exports.create = function(req, res){
|
||||||
res.send('create mission');
|
|
||||||
|
|
||||||
var missionFile = req.files.mission;
|
var missionFile = req.files.mission;
|
||||||
|
|
||||||
fs.readFile(missionFile.path, function (err, data) {
|
fs.readFile(missionFile.path, function (err, data) {
|
||||||
var newPath = config.path + '/mpmissions' + missionFile.name;
|
var newPath = config.path + '/mpmissions/' + missionFile.name;
|
||||||
|
console.log(newPath);
|
||||||
fs.writeFile(newPath, data, function (err) {
|
fs.writeFile(newPath, data, function (err) {
|
||||||
res.json(missionFile);
|
res.json(missionFile);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user