first commit

This commit is contained in:
2025-08-02 16:30:27 +02:00
commit 23646bfcee
14851 changed files with 1750626 additions and 0 deletions

View File

@@ -0,0 +1,351 @@
/*global window, $, jQuery*/
if (typeof String.prototype.trim !== 'function') {
String.prototype.trim = function () {
"use strict";
return this.replace(/^\s+|\s+$/g, '');
};
}
(function ($, undef) {
"use strict";
$.treeDragDrop = {
defaults: {
selectedClass: "tdd-selected",
collapsedClass: "tdd-collapsed",
expandedClass: "tdd-expanded",
beforeClass: "tdd-before",
afterClass: "tdd-after",
cursorGrabbingUrl: null,
inFolderThreshhold: 100,
cursorAt: {left: 10, top: -40},
dragContainer: $('<div class="tdd-dragContainer" />'),
marker: $('<div />'),
attributes: ["id", "class"],
getUrl: null,
updateUrl: null
}
};
// helpers
function debug() {
if (window.console && window.console.log) {
//window.console.log(arguments);
}
}
function getContext(el) {
return el.closest(".treeDragDrop");
}
function getOptions(el) {
return el.closest(".treeDragDrop").data("options");
}
function serializeTree(el, ctx) {
var data = [],
intestingAttr = getOptions(el).attributes;
el.children("li").each(function (index, value) {
var obj = {},
attr = {};
obj.data = $(value).clone().children().remove().end().text().trim();
$.each(intestingAttr, function (index, attribute) {
if ($(value).attr(attribute) !== undef) {
if (attribute === "class") {
attr.classname = $(value).attr(attribute);
} else {
attr[attribute] = $(value).attr(attribute);
}
}
});
obj.attr = attr;
if ($(value).children("ul").length > 0) {
obj.children = serializeTree($(value).children("ul"));
}
data.push(obj);
});
return data;
}
function sendTree(treeData, updateUrl) {
var ajaxData;
//treeData = serializeTree(tree);
debug(treeData);
if (updateUrl !== null) {
ajaxData = {tree: treeData};
$.post(updateUrl, ajaxData, function (res) {
//TODO: error handling
return true;
}).done(function (msg) {
showInfoMessage('Uloženo','success');
}).fail(function(xhr, status, error) {
showInfoMessage('Chyba: ' + xhr.responseText,'danger');
});
}
}
// handlers
$.treeDragDrop.handlers = {
handleDraggableStart: function (e, o)
{
debug("handleDraggableStart");
var options = getOptions($(e.target));
$(e.target).addClass(options.selectedClass);
document.onmousemove = function () {
return false;
};
$(e.target).data('position', $(e.target).index());
options.dropped = false;
//$("body").css("cursor", "url(" + options.cursorGrabbingUrl + ") , move").addClass("cursorGrabbing");
},
handleDraggableDrag: function (e, o) {
debug("handleDraggableDrag");
},
handleDraggableStop: function (e, o) {
debug("handleDraggableStop");
var ctx = getContext($(e.target)),
options = getOptions($(e.target)),
tree = $(".tdd-tree", ctx),
target = $(e.target);
// remove the mousemove Listener
$("li, .tdd-tree", ctx).unbind("mousemove").removeClass(options.selectedClass);
var data = {
id: target.data('id'),
target: target.closest("ul").closest("li").data("id"),
position: target.index(),
after: target.prev().data('id'),
before: target.next().data('id'),
};
if ($(e.target).data('position') <= data.position)
data.position++;
// build the array and post the ajax
debug("handleDraggableStop: sendTree");
sendTree(data, options.updateUrl);
//$("body").removeClass("cursorGrabbing").css("cursor", "auto");
},
handleDroppableOut: function (e, o) {
debug("handleDroppableOut", e.target);
$(e.target).unbind("mousemove");
},
handleDroppableOver: function (e, o) {
debug("handleDroppableOver", e.target);
var options = getOptions($(e.target)),
selectedClass = options.selectedClass,
beforeClass = options.beforeClass,
afterClass = options.afterClass,
marker = options.marker;
if ($(e.target).is("li")) {
// bind MouseMove to the item to check if the draggable should be appended or placed before or after the item
$(e.target).bind("mousemove", function (mme) {
//debug("handleDroppableOver mousemove", mme.currentTarget);
var target = $(mme.target).closest("li, ul"),
x = mme.pageX - target.offset().left,
y = mme.pageY - target.offset().top,
threshhold = options.inFolderThreshhold;
// threshhold for apending or placing before/ater
// will grow according to the deepness of nesting
if (target.find("ul").length !== 0) {
threshhold = Math.min(options.inFolderThreshhold * (target.find("ul").length + 1), target.width() * 0.75);
}
marker.removeClass(beforeClass, afterClass);
// prevent dropping items in itself
if (target.hasClass(selectedClass) || target.parents("." + selectedClass).length !== 0) {
marker.detach();
} else if (target.parents(".tdd-trashbin").length !== 0) {
target.parents(".tdd-trashbin").append(marker);
} else {
// append to item
if (x > threshhold) {
// append to ul if there is one
if (target.is("li") && target.children("ul").length !== 0) {
target.children("ul").append(marker);
} else if (target.is("li")) {
target.append(marker);
}
// place before item
} else if (y < target.height() / 2) {
marker.addClass(beforeClass);
target.before(marker);
// place after item
} else {
marker.addClass(afterClass);
target.after(marker);
}
}
return false;
});
// if tree is empty items may be put in the ul
//} else if ($(e.target).hasClass("tdd-tree")/* && $(".tdd-tree").children().length === 0 */) {
} else if ($(e.target).hasClass("tdd-tree")) {
debug("tree");
marker.removeClass(beforeClass, afterClass);
marker.addClass(beforeClass);
$(e.target).append(marker);
} else if ($(e.target).hasClass("tdd-trashbin")) {
debug("trashbin");
$(e.target).append(marker);
}
return false;
},
handleDroppableDrop: function (e, o)
{
debug("handleDroppableDrop");
var draggable = $(o.draggable),
dropable = $(e.target),
marker = $.treeDragDrop.defaults.marker,
ctx = draggable.data("tddCtx"),
options = ctx.data("options");
// remove selection
draggable.removeClass(options.selectedClass);
if (options.dropped)
return true;
options.dropped = true;
// if its the trashbin put them all next to each other (no nesting)
if (dropable.parents(".tdd-trashbin").length !== 0 || dropable.hasClass("tdd-trashbin")) {
$(".tdd-trashbin").append(draggable);
$("li", draggable).each(function (index, value) {
$(".tdd-trashbin").append(value);
});
// put the item directly in the tree ul if it contains no other element
} else if (dropable.hasClass("tdd-tree") && $(".tdd-tree").children().length === 0) {
$(".tdd-tree").append(draggable);
// otherwise put it before the marker, which will be detached asap
} else {
marker.before(draggable);
if (draggable.parent().is("li")) {
draggable.wrap("<ul></ul>");
}
}
marker.detach();
//clean up empty uls if its not the tree or trashbin
$("ul", ctx).not(".tdd-trashbin, .tdd-tree").each(function () {
if ($(this).children().length === 0) {
debug($(this));
$(this).remove();
}
});
// adjust expand/collapse icons
$("li", ctx).has("ul").not("li." + options.collapsedClass).addClass(options.expandedClass);
$("li", ctx).not("li:has(ul)").removeClass(options.expandedClass).removeClass(options.collapsedClass);
return false;
},
// toggle expand/collapse
handleClick: function (e) {
var target = $(e.target),
ctx = getContext($(e.target)),
tree = $(".tdd-tree", ctx),
options = getOptions($(e.target)),
collapsed = options.collapsedClass,
expanded = options.expandedClass;
if (target.children("ul").length === 0) {
return false;
} else {
if (target.hasClass(collapsed)) {
target.removeClass(collapsed).addClass(expanded);
target.children("ul").show();
} else {
target.removeClass(expanded).addClass(collapsed);
target.children("ul").hide();
}
}
debug("handleClick: sendTree");
sendTree(tree, options.updateUrl);
e.stopImmediatePropagation();
}
};
// the Prototype
$.fn.treeDragDrop = function (options) {
//extend the global default with the options for the element
options = $.extend({}, $.treeDragDrop.defaults, options);
return this.each(function () {
var ctx = $(this),
data = ctx.data('treeDragDrop');
// init the element
if (!data) {
$("li", ctx).draggable({
addClasses: false,
cursorAt: $.treeDragDrop.defaults.cursorAt,
helper: "clone",
appendTo: "body",
opacity: 0.2,
delay: 10,
handle: ".drag-drop-mover",
//create: $.treeDragDrop.handlers.handleDraggableCreate,
start: $.treeDragDrop.handlers.handleDraggableStart,
//drag: $.treeDragDrop.handlers.handleDraggableDrag,
stop: $.treeDragDrop.handlers.handleDraggableStop
});
$("li, ul", ctx).droppable({
addClasses: false,
greedy: true,
tolerance: "pointer",
drop: $.treeDragDrop.handlers.handleDroppableDrop,
over: $.treeDragDrop.handlers.handleDroppableOver,
out: $.treeDragDrop.handlers.handleDroppableOut
}).data("tddCtx", ctx);
$.treeDragDrop.defaults.marker.bind("mousemove", function () { return false; });
$.treeDragDrop.defaults.marker.bind("mouseover", function () { return false; });
ctx.data('options', options);
ctx.data('treeDragDrop', {inited: true});
}
});
};
}(jQuery));