closedquestion-8.x-3.x-dev/assets/js/closedquestion_dd_helper.js
assets/js/closedquestion_dd_helper.js
function cqInitDDQuestion(settings) {
if (settings['initialised']) {
return;
}
settings['initialised'] = true;
/* define ids of startList and answercontainer */
var questionId = settings.questionid;
var answerContainerId = questionId + "answerContainer";
var answerContainer = jQuery("#" + answerContainerId);
/* set background-image and answerContainer width/height */
answerContainer.width(settings.ddImage.width);
answerContainer.height(settings.ddImage.height);
/* Once the answer container background image is loaded, double check the size */
var image = new Image();
image.answerContainer = answerContainer;
jQuery(image).bind('load', function () {
if (this.width > this.answerContainer.width()) {
this.answerContainer.width(this.width);
}
if (this.height > this.answerContainer.height()) {
this.answerContainer.height(this.height);
}
});
image.src = settings.ddImage.url;
/* turn all elements with class "draggable" in startlist into jquery draggables
*/
jQuery(".cqDdDraggable").draggable({
zIndex: 10000,
containment: "parent"
});
jQuery("#" + answerContainerId + " .cqDdDraggable").attr("questionId", questionId);
/* Try to position draggables */
var length = settings.ddDraggableStartPos.length;
for (var i = 0; i < length; i++) {
var cqvalue = settings.ddDraggableStartPos[i].cqvalue;
var draggable = jQuery("#" + answerContainerId + " .cqDdDraggable[cqvalue=" + cqvalue + "]");
var x = settings.ddDraggableStartPos[i].x - draggable.width() / 2; //substract width/2 because stored coordinated is center
var y = settings.ddDraggableStartPos[i].y - draggable.height() / 2; //idem height/2
//set the css values
draggable.css("left", x);
draggable.css("top", y);
// Force position (fix for timing issue with hidden iframe in Firefox).
draggable.css('position', 'absolute');
}
/*
* Again try to position draggables having images. Because of loading timing
* issues, these draggables might not have had correct heights/widths when
* we first tried to position them. Approach:
*
* 1) clone images and wait for clones' load events
* 2) wrap original image in wrapper div
* 3) give div width of clone image
* 4) position draggable
*/
jQuery("#" + answerContainerId + " .cqDdDraggable").each(function (i) {
var $images = jQuery(this).find('img');
$images.each(function () {
/* 1 */
var $image = jQuery(this);
var imageCSSWidth = $image[0].style.width.length > 0 ? $image[0].style.width : $image.attr('width');
var imageCSSHeight = $image[0].style.height.length > 0 ? $image[0].style.height : $image.attr('height');
var imageClone = new Image();
jQuery(imageClone).bind('load', function () {
/* 2 + 3 */
$image.wrap('<div style="width: ' + imageClone.width + 'px; height:' + imageClone.height + 'px; display:inline-block;"></div>');
/* 4 */
var draggable = $image.closest('.cqDdDraggable');
var cqvalue = settings.ddDraggableStartPos[i].cqvalue;
var draggable = jQuery("#" + answerContainerId + " .cqDdDraggable[cqvalue=" + cqvalue + "]");
var x = settings.ddDraggableStartPos[i].x - draggable.width() / 2; //substract width/2 because stored coordinated is center
var y = settings.ddDraggableStartPos[i].y - draggable.height() / 2; //idem height/2
//set the css values
draggable.css("left", x);
draggable.css("top", y);
});
/* set clone properties */
imageClone.src = this.src;
if (imageCSSWidth && imageCSSHeight) {
//set dimensions if known via CSS
imageClone.width = parseInt(imageCSSWidth, 10);
imageClone.height = parseInt(imageCSSHeight, 10);
}
});
});
/* turn answercontainer into jquery droppable */
answerContainer.droppable({
/* set drop event */
drop: function (event, ui) {
/* user dropped draggable on the answercontainer */
/* get draggable value and coordinates */
var cqvalue = ui.draggable.attr("cqvalue");
var coords = cqGetCenterCoordsDD(jQuery(this), ui.draggable);
var returnString = "";
var length = settings.ddDraggableStartPos.length;
var i;
/* replace (or add) coordinates in ddQuestionsDraggableStartPos */
var found = false;
//replace: walk through ddQuestionsDraggableStartPos to find object with object.cqvalue = value
for (var i = 0; i < length; i++) {
if (settings.ddDraggableStartPos[i].cqvalue === cqvalue) {
//found! set new x and y
settings.ddDraggableStartPos[i].x = Math.round(coords.x);
settings.ddDraggableStartPos[i].y = Math.round(coords.y);
found = true;
}
}
// Add new object when object with object.cqvalue=cqvalue not found in ddQuestionsDraggableStartPos
if (!found) {
settings.ddDraggableStartPos[length] = {
"cqvalue": cqvalue,
"x": coords.x,
"y": coords.y
};
found = false;
}
// Create answer string.
for (i = 0; i < length; i++) {
var draggableVar = settings.ddDraggableStartPos[i];
returnString += "" + draggableVar.cqvalue + "," + draggableVar.x + "," + draggableVar.y + ";";
}
// Update input
settings.formElement.val(returnString).trigger('change');
},
/* define which elements to accept */
accept: "[questionId='" + questionId + "']"
});
/**
* Returns the center coordinates of a draggable in a droppable
*
* @param droppable object
* The Jquery droppable object
* @param draggable object
* The Jquery draggable object
*
* @returns object The coordinates: object.x and object.y
**/
function cqGetCenterCoordsDD(droppable, draggable) {
var xPos = (draggable.offset().left - droppable.offset().left + draggable.width() / 2);
var yPos = (draggable.offset().top - droppable.offset().top + draggable.height() / 2);
return {
x: xPos,
y: yPos
};
}
}