var FileMetadata = require("lalala/modules/file-metadata"), Overlay = require("lalala/modules/overlay"); function MultipleFilesUploader(xfiles_element) { this.$el = $(xfiles_element); this.$file_container = this.$el.find(".file-container"); this.$form = this.$el.closest("form"); this.state = { files: {}, files_counter: 0 }; this.render_isempty_message_if_needed(); this.make_xfile_template(); this.make_items_sortable(); this.show_amount_of_files(); this.remove_hidden_fields_from_checkboxes(this.$file_container); this.bind_events(); } // // Templates, views, etc. // MultipleFilesUploader.prototype.make_xfile_template = function() { var $template = this.$el.find("template.x-file-template"); var template = $template.get(0); var $wrapper = $(""); var $content; if (template) { if (template.content) { $content = $(template.content.children); $wrapper.append($content); } else { $content = $.trim($template.html()); $wrapper.append($content); } $template.remove(); this.xfile_template = $wrapper.get(0); } else { this.xfile_template = null; } }; MultipleFilesUploader.prototype.render_isempty_message_if_needed = function() { if (this.$file_container.find("x-file").length === 0) { this.$file_container[0].innerHTML = [ "
", "
", "Browse or drag files in here...", "
", "
" ].join(""); this.set_data_inspection_html(""); } }; MultipleFilesUploader.prototype.set_data_inspection_html = function(html) { this.$el.find("header .data-inspection").html(html); }; MultipleFilesUploader.prototype.clear_file_container = function() { this.$file_container.empty(); this.$file_container.append("
"); }; MultipleFilesUploader.prototype.show_amount_of_files = function() { var amount_of_files = this.$file_container.find("x-file").length; var word = (amount_of_files === 1 ? "file" : "files"); this.set_data_inspection_html( amount_of_files + " " + word ); }; MultipleFilesUploader.prototype.remove_hidden_fields_from_checkboxes = function($element) { $element.find("input[type=\"checkbox\"]").each(function() { var name = $(this).attr("name"); $element.find('[name="' + name + '"][type="hidden"]').remove(); }); }; // // Handle file // MultipleFilesUploader.prototype.handle_file = function(file) { this.state.files_counter++; this.state.files[this.state.files_counter.toString()] = file; // element file.$el = $(this.xfile_template).clone(); file.$el.attr("file-id", this.state.files_counter.toString()); file.el = file.$el.get(0); // waiting class file.$el.addClass("waiting"); // make thumbnail if (file.type.indexOf("image") == -1) { var fake_thumb = document.createElement("div"); fake_thumb.className = "thumb no-image"; file.el.insertBefore(fake_thumb, file.el.firstChild); } else { file.readThumbnailData(158, 110, function(canvas) { file.el.insertBefore(canvas, file.el.firstChild); }); } // if there are no files yet in the file container, empty it. // this is done to remove messages, etc. if (this.$file_container.find("x-file").length === 0) { this.clear_file_container(); } // add file element to dom this.$file_container.children(".inner-wrapper").append(file.el); // data inspection this.show_amount_of_files(); // bind events file.on("start", this.file_start_handler); file.on("progress", this.file_progess_handler); file.on("err", this.file_err_handler); file.on("done:uploading", this.file_done_uploading_handler); file.on("done:processing", this.file_done_processing_handler); file.on("done", this.file_done_handler); }; // // Events - File handlers // // -> this = file // MultipleFilesUploader.prototype.file_start_handler = function(e) { this.$el.removeClass("waiting"); this.$el.addClass("uploading"); }; MultipleFilesUploader.prototype.file_progess_handler = function(e) { if (this.$el.hasClass("error")) return; // if there are no transform -> upload percentage if (this.transforms === 0) { this.$el.find(".upload-bar").css("width", this.upload_percentage + "%"); // if there are -> transform percentage } else { this.$el.find(".process-bar").css("width", this.transforms_percentage + "%"); } }; MultipleFilesUploader.prototype.file_err_handler = function(e) { console.error("Error", this); this.$el.addClass("error"); this.$el.find(".upload-bar").css("width", "100%"); this.$el.find(".process-bar").css("width", "100%"); }; MultipleFilesUploader.prototype.file_done_uploading_handler = function(e) { this.$el.find(".upload-bar").addClass("done"); this.$el.removeClass("uploading"); this.$el.addClass("processing"); }; MultipleFilesUploader.prototype.file_done_processing_handler = function(e) { this.$el.find(".process-bar").addClass("done"); }; MultipleFilesUploader.prototype.file_done_handler = function(e) { var name = this.$el.closest("x-files").attr("name"); var pairs = format_asset_metadata(this.metadata, name + "[]"); for (var i in pairs) { var input = document.createElement("input"); input.type = "hidden"; input.name = pairs[i].name; input.value = pairs[i].value; this.el.appendChild(input); } this.$el.removeClass("processing"); this.$el.addClass("uploaded"); // title this.$el.find(".title").html(this.metadata.file_name); // attr var id = this.$el.find("input[name$=\"[id]\"]").val(); if (id) this.$el.attr("data-src-original", "//c.assets.sh/" + id + "/thumb"); }; // // Events - General // MultipleFilesUploader.prototype.bind_events = function() { var choose_handler = $.proxy(this.choose_click_handler, this); var delete_handler = $.proxy(this.xfile_btn_delete_click_handler, this); var meta_handler = $.proxy(this.xfile_btn_meta_click_handler, this); this.$el.on("click", ".choose", choose_handler); this.$el.on("click", "x-file [data-action=\"delete\"]", delete_handler); this.$el.on("click", "x-file [data-action=\"meta\"]", meta_handler); // when processing/uploading files -> disable form Haraway.on("busy", $.proxy(function() { this.$form.on("submit", this.defer_submit); }, this)); // when not processing/uploading files -> resume default behaviour Haraway.on("idle", $.proxy(function() { this.$form.off("submit", this.defer_submit); }, this)); }; MultipleFilesUploader.prototype.choose_click_handler = function(e) { var accept = this.$el.attr("accept").split(","); var profile = this.$el.attr("profile"); // prevent default e.preventDefault(); // show choose dialog Haraway.choose(accept, true, profile, $.proxy(this.handle_file, this)); }; MultipleFilesUploader.prototype.defer_submit = function(e) { var $form = $(e.currentTarget); // prevent default behaviour e.preventDefault(); // disable submit button $form.find("input[type=\"submit\"]").attr("disabled", "disabled"); // once processing/uploading is complete // enable submit button and submit form Haraway.once("idle", function() { $form.find("input[type=submit]").attr("disabled", null); $form.submit(); }); }; MultipleFilesUploader.prototype.xfile_btn_delete_click_handler = function(e) { var $xfile = $(e.currentTarget).closest("x-file"); if ($xfile.length) this.toggle_destroy($xfile); }; MultipleFilesUploader.prototype.xfile_btn_meta_click_handler = function(e) { var $xfile = $(e.currentTarget).closest("x-file"), fum; var main_overlay = Overlay.get_instance(); // check status, must be uploaded file if (!$xfile.hasClass("uploaded")) return; // new metadata overlay-content block fum = new FileMetadata($xfile, this); main_overlay.append_content(fum.$el); main_overlay.$el.find("select").chosen({ width: "80%" }); main_overlay.show("file-metadata"); }; // // Destroy // MultipleFilesUploader.prototype.toggle_destroy = function($xfile) { if ($xfile.hasClass("about-to-destroy")) { this.set_to_not_destroy($xfile); } else { this.set_to_destroy($xfile); } }; MultipleFilesUploader.prototype.set_to_destroy = function($xfile) { var $destroy, $id; // add class $xfile.addClass("about-to-destroy"); // input $destroy = $xfile.find("[name$=\"_destroy]\"]"); if ($destroy.length === 0) { $id = $xfile.find("[name$=\"[id]\"]"); $destroy = $(""); $destroy.attr("type", "hidden"); $destroy.attr("name", $id.attr("name").replace("id", "_destroy")); $id.after($destroy); } // set $destroy.attr("value", "1"); }; MultipleFilesUploader.prototype.set_to_not_destroy = function($xfile) { $xfile.removeClass("about-to-destroy"); $xfile.find("[name$=\"_destroy]\"]").attr("value", "0"); }; // // Sortable // MultipleFilesUploader.prototype.make_items_sortable = function() { this.$el.sortable({ containment: "parent", items: "x-file", handle: "[data-action=\"move\"]" }); }; // // Extra's // function format_asset_metadata(value, prefix) { var results = [], i; if (value instanceof Array) { for (i in value) { results = results.concat(format_asset_metadata(value[i], prefix + "[]")); } return results; } if (value === Object(value)) { for (i in value) { if (value.hasOwnProperty(i)) { results = results.concat(format_asset_metadata(value[i], prefix + "[" + i + "]")); } } return results; } return [{ name: prefix, value: value }]; } // // -> EXPORT // module.exports = MultipleFilesUploader;