/** * @author Benjamin Baer <benjamin.baer@math.uzh.ch> */ /* global $ */ /* global EventEmitter */ /* @depend QfqEvents.js */ /* @depend Alert.js */ /* @depend ElementUpdate.js */ /** * Qfq Namespace * * @namespace QfqNS */ var QfqNS = QfqNS || {}; (function (n) { 'use strict'; /** * */ n.DragAndDrop = function ($hook) { this.$container = $hook; this.eventEmitter = new EventEmitter(); this.dropZones = []; this.elements = []; this.active = false; this.api = $hook.data("dnd-api"); this.draggedId = ""; this.lastChild = ""; this.$tempObject = {}; }; n.DragAndDrop.prototype.on = n.EventEmitter.onMixin; n.DragAndDrop.prototype.buildDropArea = function(position, relatedId, otherPos) { var that = this; var $dropArea = {}; if (this.$container.data("columns")) { $dropArea = $("<tr />", { class: "qfqDropTarget" }); var $fluff = $("<td />", { class: "qfqDropTarget", colspan: this.$container.data("columns") }); $fluff.appendTo($dropArea); } else { $dropArea = $("<div />", { class: "qfqDropTarget" }); } $dropArea.data("position", position); $dropArea.data("related", relatedId); $dropArea.data("other-pos", otherPos); $dropArea.on("dragenter", function(e) { e.preventDefault(); $dropArea.addClass("qfqTargetDisplay"); }); $dropArea.on("dragover", function(e) { e.preventDefault(); e.originalEvent.dataTransfer.dropEffect = "move"; }); $dropArea.on("drop", function(e) { e.originalEvent.preventDefault(); that._moveObjectBefore(e, $dropArea); }); return $dropArea; }; n.DragAndDrop.prototype.setDropZones = function($objects) { var that = this; $objects.each(function() { var $dropZone = $(this); $dropZone.on("dragenter", function(e) { e.preventDefault(); $dropZone.addClass("qfqTargetDisplay"); e.Effect = "all"; that._handleDragEnter(e); }); $dropZone.on("dragleave", function(e) { e.preventDefault(); $dropZone.removeClass("qfqTargetDisplay"); that._handleDragLeave(e); }); $dropZone.on("dragover", function(e) { e.preventDefault(); e.stopPropagation(); }); $dropZone.on("drop", function(e) { e.preventDefault(); e.stopPropagation(); that._dropHandler(e); }); $dropZone.css("z-index", 5); that.dropZones.push($dropZone); }); }; n.DragAndDrop.prototype.setElements = function($objects) { var that = this; $objects.each(function() { var $element = $(this); $element.prop("draggable", true); $element.on("dragstart", function(e) { that.draggedId = $element[0].id; }); that.elements.push($element); }); }; n.DragAndDrop.prototype._handleDragEnter = function(event) { var $tempObject = $("#" + this.draggedId).clone(); $tempObject.css("opacity", 0.5); $tempObject.css("z-index", 0); $tempObject.off(); if (this.$tempObject[0]) { if ($tempObject[0].id !== this.$tempObject[0].id) { this.$tempObject = $tempObject; this.$tempObject.appendTo($("#" + event.currentTarget.id)); } } else { this.$tempObject = $tempObject; this.$tempObject.appendTo($("#" + event.currentTarget.id)); } }; n.DragAndDrop.prototype._handleDragLeave = function(event) { if(this.$tempObject[0]) { this.$tempObject.remove(); this.$tempObject = {}; } }; n.DragAndDrop.prototype.makeBasketCase = function() { var dzSelector = this.$container.data("dnd-dropzone") || false; var elSelector = this.$container.data("dnd-element") || false; if (elSelector) { this.setElements($("." + elSelector)); } if (dzSelector) { this.setDropZones($("." + dzSelector)); } }; n.DragAndDrop.prototype._dropHandler = function(event) { if(this.$tempObject[0]) { this.$tempObject.remove(); this.$tempObject = {}; } $("#" + this.draggedId).appendTo($("#" + event.currentTarget.id)); }; n.DragAndDrop.prototype._buildOrderDropZones = function($object, e) { this.removeDropAreas(); //if ($object[0].id !== this.draggedId) { //if ($object.data("dnd-position") !== $("#" + this.draggedId).data("dnd-position") + 1) { var $dropArea = this.buildDropArea("before", $object.data("dnd-id"), $object.data("dnd-position")); //$dropArea.hide(); $object.before($dropArea); //$dropArea.slideDown(500, 'swing'); var $lastDrop = this.buildDropArea("after", $object.data("dnd-id"), $object.data("dnd-position")); //$lastDrop.hide(); $object.after($lastDrop); //$lastDrop.slideDown(500, 'swing'); //$lastDrop.appendTo(this.$container); //} /*if ($object[0].id === this.lastChild) { var $lastDrop = this.buildDropArea("after", $object.data("dnd-id"), $object.data("dnd-position")); $lastDrop.appendTo(this.$container); }*/ //} }; n.DragAndDrop.prototype.removeDropAreas = function() { if (this.$container.data("column")) { this.$container.children(".qfqTempTable").remove(); } this.$container.children(".qfqDropTarget").remove(); }; n.DragAndDrop.prototype.removeDropTarget = function(e) { console.log(e); }; n.DragAndDrop.prototype.makeSortable = function() { var that = this; var numberOfChildren = this.$container.children().length; var count = 0; this.$container.children().each( function() { count++; var child = $(this); if (numberOfChildren === count) { that.lastChild = child[0].id; } child.data("dnd-position", count); child.prop("draggable", true); child.on("dragstart", function(e) { e.originalEvent.dataTransfer.setData("text", child[0].id); that.draggedId = child[0].id; that.active = true; e.originalEvent.dataTransfer.effectAllowed = "move"; }); child.on("dragenter", function(e) { if (that.active) { that._buildOrderDropZones($(this), e); } }); child.on("dragend", function() { that.active = false; that.removeDropAreas(); }); }); }; n.DragAndDrop.prototype._moveObjectBefore = function(e, $hook) { var id = e.originalEvent.dataTransfer.getData("text"); var $object = $("#" + id); var posTo = $hook.data("position"); if (posTo === "after") { this.lastChild = $object[0].id; } $hook.before(document.getElementById(id)); this._buildOrderUpdate($object, $hook.data("position"), $hook.data("related"), $hook.data("other-pos")); this.removeDropAreas(); }; n.DragAndDrop.prototype._buildOrderUpdate = function($object, position, otherId, otherPos) { var jObject = {}; jObject.dragId = $object.data("dnd-id"); jObject.dragPosition = $object.data("dnd-position"); jObject.setTo = position; jObject.hoverId = otherId; jObject.hoverPosition = otherPos; this._sendToAPI(jObject); }; n.DragAndDrop.prototype._sendToAPI = function(object) { var that = this; $.getJSON(this.api, object, function(data) { that._successHandler(data); }); }; n.DragAndDrop.prototype._successHandler = function(data) { if (data.status === "error") { var alert = new n.Alert({ type: data.status, message: data.message, modal: true, buttons: [{ label: "Ok", eventName: "ok" }] }); alert.show(); console.error(data.message); } else { console.log("status:" + data.status + " message: " + data.message); if (data['element-update']) { var configuration = data['element-update']; n.ElementUpdate.updateAll(configuration); } } }; })(QfqNS);