var Grid; exports.init = function() { var instances = []; this.$el = $(".grid"); this.$el.each(function() { instances.push(new Grid(this)); }); }; Grid = (function() { var __bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; }; function G(grid_element) { this.selected_images = []; this.transform_html(grid_element); this.bind_mouse_events(); this.setup_mouse_selection(); } G.prototype.transform_html = function(grid_element) { var fragment, el, el_images, el_input, data_attr, $grid, $original_list; // elements $grid = $(grid_element); $original_list = $grid.children("ul:first-child"); // data -> attributes data_attr = "data-accessible-attributes"; data_attr = $original_list.attr(data_attr) data_attr = data_attr ? data_attr.split(",") : []; // document fragment for the images fragment = document.createDocumentFragment(); // transform images html $grid.find("li").not(":last-child").each(function() { var grid_piece = document.createElement("li"); grid_piece.innerHTML = this.innerHTML.replace("<a", "<a class=\"image\""); var overlay = document.createElement("div"); overlay.className = "overlay"; grid_piece.appendChild(overlay); fragment.appendChild(grid_piece); }); // create new container elements el = document.createElement("div"); el.className = "mod-grid"; el_images = document.createElement("ul"); el_images.className = "images"; el_images.appendChild(fragment); el_actions = document.createElement("div"); el_actions.className = "actions"; el_actions.innerHTML = "" + $grid.find("li:last-child").html() + '<a class="button" rel="choose-files">Choose files</a>' + '<div class="files-description"></div>' + '<a class="button unavailable" rel="edit">Edit selected</a>' + '<a class="button unavailable" rel="destroy">destroy selected</a>'; // merge el.appendChild(el_actions); el.appendChild(el_images); // replace original with new $original_list.replaceWith(el); // bind to instance this.$el = $(el); // other layout stuff this.$el.closest(".inputs").addClass("next"); }; G.prototype.check_edit_and_destroy_buttons = function() { var grid = this; this.$el.children(".actions").find('[rel="edit"], [rel="destroy"]').each(function() { var $btn = $(this); if (grid.selected_images.length === 0) { $btn.addClass("unavailable"); } else { $btn.removeClass("unavailable"); } }); }; // // Events // G.prototype.bind_mouse_events = function() { this.$el.children(".images") .on("mouseleave", "li", this.row_mouseleave) .on("mouseleave", "li label", this.row_label_mouseleave) .on("mouseenter", "li label", this.row_label_mouseenter) .on("mouseenter", "li .image", this.row_image_mouseenter) .on("click", "li a", function(e) { e.preventDefault(); }) .on("click", "li .attributes .close-button", this.close_button_click); this.$el.children(".actions") .children("a[rel=\"choose-files\"]").on("click", this.choose_files_button_click).end() .children("input[type=\"file\"]").on("change", this.file_input_change).trigger("change").end() .children("a[rel=\"edit\"]").on("click", __bind(this.edit_or_destroy_selected_button_click, this)).end() .children("a[rel=\"destroy\"]").on("click", __bind(this.edit_or_destroy_selected_button_click, this)); }; G.prototype.row_mouseleave = function(e) { $(this).removeClass("properties"); }; G.prototype.row_label_mouseenter = function(e) { $(this).parent().addClass("move"); }; G.prototype.row_label_mouseleave = function(e) { $(this).parent().addClass("properties").removeClass("move"); }; G.prototype.row_image_mouseenter = function(e) { var $p = $(this).parent(); if ($p.hasClass("edit-block")) return; $p.addClass("properties"); }; G.prototype.choose_files_button_click = function(e) { $(this).parent().children("input[type=\"file\"]").trigger("click"); }; G.prototype.file_input_change = function(e) { var val = this.files || $(this).val(); var $fd = $(this).parent().children(".files-description"); if (typeof val === "object") { val = val.length; $fd[0].innerHTML = val + " file" + (val === 1 ? "" : "s") + " chosen"; $fd.show(); } }; G.prototype.edit_or_destroy_selected_button_click = function(e) { var i = 0, j = this.selected_images.length, $e = $(e.currentTarget), action = $e.attr("rel"); if ($e.hasClass("unavailable")) return; for (; i<j; ++i) { var id = this.selected_images[i]; var $row = $("#" + id).parent(); $row.removeClass("selected"); this["set_to_" + action]($row[0]); } this.selected_images.length = 0; this.check_edit_and_destroy_buttons(); }; G.prototype.close_button_click = function(e) { $(this).closest("li").removeClass("edit-block"); }; // // Mouse selection // G.prototype.setup_mouse_selection = function() { var grid = this; this.$el.selectable({ filter: "li", cancel: ".actions,.button,input,textarea,button", selecting: function(e, ui) { $row = $(ui.selecting); if (!$row.hasClass("will-destroy") && !$row.hasClass("edit-block")) { $row.addClass("selected"); } }, unselecting: function(e, ui) { $(ui.unselecting).removeClass("selected"); }, stop: function(e, ui) { var new_selected_images = []; grid.$el.find(".images > li").each(function() { var $t = $(this), id; if ($t.hasClass("selected")) { id = $t.children('input[type="hidden"]:first').attr("id"); new_selected_images.push(id + ""); id = null; } }); grid.selected_images = new_selected_images; grid.check_edit_and_destroy_buttons(); } }); }; // // Edit // G.prototype.toggle_edit = function(row) { if ($(row).hasClass("edit-block")) { this.set_to_not_edit(row); } else { this.set_to_edit(row); } }; G.prototype.set_to_edit = function(row) { $(row).addClass("edit-block"); }; G.prototype.set_to_not_edit = function(row) { $(row).removeClass("edit-block"); } // // Destroy // G.prototype.toggle_destroy = function(row) { if ($(row).find('input[name$="[_destroy]"]').length) { this.set_to_not_destroy(row); } else { this.set_to_destroy(row); } }; G.prototype.set_to_destroy = function(row) { var $row = $(row); var input_id_name = $row.find('input[name$="[id]"]')[0].name; var input_destroy = document.createElement("input"); $(input_destroy).attr({ name: input_id_name.replace("[id]", "[_destroy]"), type: "hidden", value: "1" }); $row.append(input_destroy); $row.addClass("will-destroy"); }; G.prototype.set_to_not_destroy = function(row) { $(row).find('input[name$="[_destroy]"]').remove(); $(row).removeClass("will-destroy"); }; // // The end // return G; })();