DragAndDrop.js 8.92 KiB
/**
* @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);