267 lines
8.8 KiB
JavaScript
267 lines
8.8 KiB
JavaScript
(function(requirejs, require, define) {
|
|
define(['edx-ui-toolkit/js/utils/html-utils'], function(HtmlUtils) {
|
|
return {
|
|
initializeBaseTargets: initializeBaseTargets,
|
|
initializeTargetField: initializeTargetField,
|
|
destroyTargetField: destroyTargetField
|
|
};
|
|
|
|
function initializeBaseTargets(state) {
|
|
(function(c1) {
|
|
while (c1 < state.config.targets.length) {
|
|
processTarget(state, state.config.targets[c1]);
|
|
|
|
c1 += 1;
|
|
}
|
|
}(0));
|
|
}
|
|
|
|
function initializeTargetField(draggableObj) {
|
|
var iconElOffset;
|
|
|
|
if (draggableObj.targetField.length === 0) {
|
|
draggableObj.originalConfigObj.target_fields.every(function(targetObj) {
|
|
processTarget(draggableObj.state, targetObj, true, draggableObj);
|
|
|
|
return true;
|
|
});
|
|
} else {
|
|
iconElOffset = draggableObj.iconEl.position();
|
|
|
|
draggableObj.targetField.every(function(targetObj) {
|
|
targetObj.offset.top = iconElOffset.top + targetObj.y;
|
|
targetObj.offset.left = iconElOffset.left + targetObj.x;
|
|
|
|
return true;
|
|
});
|
|
}
|
|
}
|
|
|
|
function destroyTargetField(draggableObj) {
|
|
var indexOffset, lowestRemovedIndex;
|
|
|
|
indexOffset = 0;
|
|
lowestRemovedIndex = draggableObj.state.targets.length + 1;
|
|
|
|
draggableObj.targetField.every(function(target) {
|
|
target.el.remove();
|
|
|
|
if (lowestRemovedIndex > target.indexInStateArray) {
|
|
lowestRemovedIndex = target.indexInStateArray;
|
|
}
|
|
|
|
draggableObj.state.targets.splice(target.indexInStateArray - indexOffset, 1);
|
|
indexOffset += 1;
|
|
|
|
return true;
|
|
});
|
|
|
|
draggableObj.state.targets.every(function(target) {
|
|
if (target.indexInStateArray > lowestRemovedIndex) {
|
|
target.indexInStateArray -= indexOffset;
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
draggableObj.targetField = [];
|
|
}
|
|
|
|
function processTarget(state, obj, fromTargetField, draggableObj) {
|
|
var $targetEl, borderCss, $numTextEl, targetObj;
|
|
|
|
borderCss = '';
|
|
if (state.config.targetOutline === true) {
|
|
borderCss = 'border: 1px dashed gray; ';
|
|
}
|
|
|
|
$targetEl = $(
|
|
HtmlUtils.joinHtml(
|
|
HtmlUtils.HTML('<div style="display: block; position: absolute; width: '),
|
|
obj.w,
|
|
HtmlUtils.HTML('px; height: '),
|
|
obj.h,
|
|
HtmlUtils.HTML('px; top: '),
|
|
obj.y,
|
|
HtmlUtils.HTML('px; left: '),
|
|
obj.x,
|
|
HtmlUtils.HTML('px; '),
|
|
borderCss,
|
|
HtmlUtils.HTML('"aria-dropeffect=""></div>')
|
|
).toString()
|
|
);
|
|
if (fromTargetField === true) {
|
|
$targetEl.appendTo(draggableObj.iconEl);
|
|
} else {
|
|
$targetEl.appendTo(state.baseImageEl.parent());
|
|
}
|
|
|
|
$targetEl.mousedown(function(event) {
|
|
event.preventDefault();
|
|
});
|
|
|
|
if (state.config.onePerTarget === false) {
|
|
$numTextEl = $(
|
|
HtmlUtils.joinHtml(
|
|
HtmlUtils.HTML('<div style=" display: block; position: absolute;'),
|
|
HtmlUtils.HTML('width: 24px; height: 24px; top: '),
|
|
obj.y,
|
|
HtmlUtils.HTML('px; left: '),
|
|
obj.x,
|
|
obj.w - 24,
|
|
HtmlUtils.HTML('px; border: 1px solid black; text-align: center; z-index: 500;'),
|
|
HtmlUtils.HTML('background-color: white; font-size: 0.95em; color: #009fe2; ">0</div>')
|
|
).toString()
|
|
);
|
|
} else {
|
|
$numTextEl = null;
|
|
}
|
|
|
|
targetObj = {
|
|
uniqueId: state.getUniqueId(),
|
|
|
|
id: obj.id,
|
|
|
|
x: obj.x,
|
|
y: obj.y,
|
|
|
|
w: obj.w,
|
|
h: obj.h,
|
|
|
|
el: $targetEl,
|
|
offset: $targetEl.position(),
|
|
|
|
draggableList: [],
|
|
|
|
state: state,
|
|
|
|
targetEl: $targetEl,
|
|
|
|
numTextEl: $numTextEl,
|
|
updateNumTextEl: updateNumTextEl,
|
|
|
|
removeDraggable: removeDraggable,
|
|
addDraggable: addDraggable,
|
|
|
|
type: 'base',
|
|
draggableObj: null
|
|
};
|
|
|
|
if (fromTargetField === true) {
|
|
targetObj.offset = draggableObj.iconEl.position();
|
|
targetObj.offset.top += obj.y;
|
|
targetObj.offset.left += obj.x;
|
|
|
|
targetObj.type = 'on_drag';
|
|
targetObj.draggableObj = draggableObj;
|
|
}
|
|
|
|
if (state.config.onePerTarget === false) {
|
|
$numTextEl.appendTo(state.baseImageEl.parent());
|
|
$numTextEl.mousedown(function(event) {
|
|
event.preventDefault();
|
|
});
|
|
$numTextEl.mouseup(function() {
|
|
cycleDraggableOrder.call(targetObj);
|
|
});
|
|
}
|
|
|
|
targetObj.indexInStateArray = state.targets.push(targetObj) - 1;
|
|
|
|
if (fromTargetField === true) {
|
|
draggableObj.targetField.push(targetObj);
|
|
}
|
|
}
|
|
|
|
function removeDraggable(draggable) {
|
|
var c1;
|
|
|
|
this.draggableList.splice(draggable.onTargetIndex, 1);
|
|
|
|
// An item from the array was removed. We need to updated all indexes accordingly.
|
|
// Shift all indexes down by one if they are higher than the index of the removed item.
|
|
c1 = 0;
|
|
while (c1 < this.draggableList.length) {
|
|
if (this.draggableList[c1].onTargetIndex > draggable.onTargetIndex) {
|
|
this.draggableList[c1].onTargetIndex -= 1;
|
|
}
|
|
|
|
c1 += 1;
|
|
}
|
|
|
|
draggable.onTarget = null;
|
|
draggable.onTargetIndex = null;
|
|
|
|
if (this.type === 'on_drag') {
|
|
this.draggableObj.numDraggablesOnMe -= 1;
|
|
}
|
|
|
|
this.updateNumTextEl();
|
|
}
|
|
|
|
function addDraggable(draggable) {
|
|
draggable.onTarget = this;
|
|
draggable.onTargetIndex = this.draggableList.push(draggable) - 1;
|
|
|
|
if (this.type === 'on_drag') {
|
|
this.draggableObj.numDraggablesOnMe += 1;
|
|
}
|
|
|
|
this.updateNumTextEl();
|
|
}
|
|
|
|
/*
|
|
* function cycleDraggableOrder
|
|
*
|
|
* Parameters:
|
|
* none - This function does not expect any parameters.
|
|
*
|
|
* Returns:
|
|
* undefined - The return value of this function is not used.
|
|
*
|
|
* Description:
|
|
* Go through all draggables that are on the current target, and decrease their
|
|
* z-index by 1, making sure that the bottom-most draggable ends up on the top.
|
|
*/
|
|
function cycleDraggableOrder() {
|
|
var c1, lowestZIndex, highestZIndex;
|
|
|
|
if (this.draggableList.length < 2) {
|
|
return;
|
|
}
|
|
|
|
highestZIndex = -10000;
|
|
lowestZIndex = 10000;
|
|
|
|
for (c1 = 0; c1 < this.draggableList.length; c1 += 1) {
|
|
if (this.draggableList[c1].zIndex < lowestZIndex) {
|
|
lowestZIndex = this.draggableList[c1].zIndex;
|
|
}
|
|
|
|
if (this.draggableList[c1].zIndex > highestZIndex) {
|
|
highestZIndex = this.draggableList[c1].zIndex;
|
|
}
|
|
}
|
|
|
|
for (c1 = 0; c1 < this.draggableList.length; c1 += 1) {
|
|
if (this.draggableList[c1].zIndex === lowestZIndex) {
|
|
this.draggableList[c1].zIndex = highestZIndex;
|
|
} else {
|
|
this.draggableList[c1].zIndex -= 1;
|
|
}
|
|
|
|
this.draggableList[c1].iconEl.css('z-index', this.draggableList[c1].zIndex);
|
|
if (this.draggableList[c1].labelEl !== null) {
|
|
this.draggableList[c1].labelEl.css('z-index', this.draggableList[c1].zIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateNumTextEl() {
|
|
if (this.numTextEl !== null) {
|
|
this.numTextEl.text(this.draggableList.length);
|
|
}
|
|
}
|
|
}); // End-of: define([], function () {
|
|
}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define) {
|