Commit 424cfd3c by Christina Roberts

Merge pull request #1372 from MITx/feature/dhm/drag

Auto expand on hover of drag&drop unit
parents a98c924d 574d6e8e
...@@ -87,7 +87,10 @@ $(document).ready(function() { ...@@ -87,7 +87,10 @@ $(document).ready(function() {
$('.unit').draggable({ $('.unit').draggable({
axis: 'y', axis: 'y',
handle: '.drag-handle', handle: '.drag-handle',
stack: '.unit', zIndex: 999,
start: initiateHesitate,
drag: checkHoverState,
stop: removeHesitate,
revert: "invalid" revert: "invalid"
}); });
...@@ -95,7 +98,10 @@ $(document).ready(function() { ...@@ -95,7 +98,10 @@ $(document).ready(function() {
$('.id-holder').draggable({ $('.id-holder').draggable({
axis: 'y', axis: 'y',
handle: '.section-item .drag-handle', handle: '.section-item .drag-handle',
stack: '.id-holder', zIndex: 999,
start: initiateHesitate,
drag: checkHoverState,
stop: removeHesitate,
revert: "invalid" revert: "invalid"
}); });
...@@ -179,10 +185,12 @@ function toggleSections(e) { ...@@ -179,10 +185,12 @@ function toggleSections(e) {
if($button.hasClass('is-activated')) { if($button.hasClass('is-activated')) {
$section.addClass('collapsed'); $section.addClass('collapsed');
$section.find('.expand-collapse-icon').removeClass('collapsed').addClass('expand'); // first child in order to avoid the icons on the subsection lists which are not in the first child
$section.find('header .expand-collapse-icon').removeClass('collapse').addClass('expand');
} else { } else {
$section.removeClass('collapsed'); $section.removeClass('collapsed');
$section.find('.expand-collapse-icon').removeClass('expand').addClass('collapse'); // first child in order to avoid the icons on the subsection lists which are not in the first child
$section.find('header .expand-collapse-icon').removeClass('expand').addClass('collapse');
} }
} }
...@@ -271,9 +279,67 @@ function removePolicyMetadata(e) { ...@@ -271,9 +279,67 @@ function removePolicyMetadata(e) {
saveSubsection() saveSubsection()
} }
CMS.HesitateEvent.toggleXpandHesitation = null;
function initiateHesitate(event, ui) {
CMS.HesitateEvent.toggleXpandHesitation = new CMS.HesitateEvent(expandSection, 'dragLeave', true);
$('.collapsed').on('dragEnter', CMS.HesitateEvent.toggleXpandHesitation, CMS.HesitateEvent.toggleXpandHesitation.trigger);
$('.collapsed').each(function() {
this.proportions = {width : this.offsetWidth, height : this.offsetHeight };
// reset b/c these were holding values from aborts
this.isover = false;
});
}
function checkHoverState(event, ui) {
// copied from jquery.ui.droppable.js $.ui.ddmanager.drag & other ui.intersect
var draggable = $(this).data("ui-draggable"),
x1 = (draggable.positionAbs || draggable.position.absolute).left + (draggable.helperProportions.width / 2),
y1 = (draggable.positionAbs || draggable.position.absolute).top + (draggable.helperProportions.height / 2);
$('.collapsed').each(function() {
// don't expand the thing being carried
if (ui.helper.is(this)) {
return;
}
$.extend(this, {offset : $(this).offset()});
var droppable = this,
l = droppable.offset.left,
r = l + droppable.proportions.width,
t = droppable.offset.top,
b = t + droppable.proportions.height;
if (l === r) {
// probably wrong values b/c invisible at the time of caching
droppable.proportions = { width : droppable.offsetWidth, height : droppable.offsetHeight };
r = l + droppable.proportions.width;
b = t + droppable.proportions.height;
}
// equivalent to the intersects test
var intersects = (l < x1 && // Right Half
x1 < r && // Left Half
t < y1 && // Bottom Half
y1 < b ), // Top Half
c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
if(!c) {
return;
}
this[c] = true;
this[c === "isout" ? "isover" : "isout"] = false;
$(this).trigger(c === "isover" ? "dragEnter" : "dragLeave");
});
}
function removeHesitate(event, ui) {
$('.collapsed').off('dragEnter', CMS.HesitateEvent.toggleXpandHesitation.trigger);
CMS.HesitateEvent.toggleXpandHesitation = null;
}
function expandSection(event) { function expandSection(event) {
$(event.delegateTarget).removeClass('collapsed'); $(event.delegateTarget).removeClass('collapsed', 400);
$(event.delegateTarget).find('.expand-collapse-icon').removeClass('expand').addClass('collapse'); // don't descend to icon's on children (which aren't under first child) only to this element's icon
$(event.delegateTarget).children().first().find('.expand-collapse-icon').removeClass('expand', 400).addClass('collapse');
} }
function onUnitReordered(event, ui) { function onUnitReordered(event, ui) {
......
...@@ -18,33 +18,31 @@ CMS.HesitateEvent = function(executeOnTimeOut, cancelSelector, onlyOnce) { ...@@ -18,33 +18,31 @@ CMS.HesitateEvent = function(executeOnTimeOut, cancelSelector, onlyOnce) {
this.timeoutEventId = null; this.timeoutEventId = null;
this.originalEvent = null; this.originalEvent = null;
this.onlyOnce = (onlyOnce === true); this.onlyOnce = (onlyOnce === true);
} };
CMS.HesitateEvent.DURATION = 400; CMS.HesitateEvent.DURATION = 800;
CMS.HesitateEvent.prototype.trigger = function(event) { CMS.HesitateEvent.prototype.trigger = function(event) {
console.log('trigger'); if (event.data.timeoutEventId == null) {
if (this.timeoutEventId === null) { event.data.timeoutEventId = window.setTimeout(
this.timeoutEventId = window.setTimeout(this.fireEvent, CMS.HesitateEvent.DURATION); function() { event.data.fireEvent(event); },
this.originalEvent = event; CMS.HesitateEvent.DURATION);
// is it wrong to bind to the below v $(event.currentTarget)? event.data.originalEvent = event;
$(this.originalEvent.delegateTarget).on(this.cancelSelector, this.untrigger); $(event.data.originalEvent.delegateTarget).on(event.data.cancelSelector, event.data, event.data.untrigger);
} }
} };
CMS.HesitateEvent.prototype.fireEvent = function(event) { CMS.HesitateEvent.prototype.fireEvent = function(event) {
console.log('fire'); event.data.timeoutEventId = null;
this.timeoutEventId = null; $(event.data.originalEvent.delegateTarget).off(event.data.cancelSelector, event.data.untrigger);
$(this.originalEvent.delegateTarget).off(this.cancelSelector, this.untrigger); if (event.data.onlyOnce) $(event.data.originalEvent.delegateTarget).off(event.data.originalEvent.type, event.data.trigger);
if (this.onlyOnce) $(this.originalEvent.delegateTarget).off(this.originalEvent.type, this.trigger); event.data.executeOnTimeOut(event.data.originalEvent);
this.executeOnTimeOut(this.originalEvent); };
}
CMS.HesitateEvent.prototype.untrigger = function(event) { CMS.HesitateEvent.prototype.untrigger = function(event) {
console.log('untrigger'); if (event.data.timeoutEventId) {
if (this.timeoutEventId) { window.clearTimeout(event.data.timeoutEventId);
window.clearTimeout(this.timeoutEventId); $(event.data.originalEvent.delegateTarget).off(event.data.cancelSelector, event.data.untrigger);
$(this.originalEvent.delegateTarget).off(this.cancelSelector, this.untrigger);
} }
this.timeoutEventId = null; event.data.timeoutEventId = null;
} };
\ No newline at end of file \ No newline at end of file
...@@ -209,6 +209,14 @@ $.widget("ui.draggable", $.ui.mouse, { ...@@ -209,6 +209,14 @@ $.widget("ui.draggable", $.ui.mouse, {
// computation of pageY or scrollTop() or caching of scrollTop at same state as pageY // computation of pageY or scrollTop() or caching of scrollTop at same state as pageY
// btw: known bug in jqueryui http://bugs.jqueryui.com/ticket/5718 // btw: known bug in jqueryui http://bugs.jqueryui.com/ticket/5718
if (this.scrollParent.is(document) && this.cssPosition === 'relative') { if (this.scrollParent.is(document) && this.cssPosition === 'relative') {
// need to catch the original parent having been shoved down during drag (perhaps by
// events)
// update cached originals if it shifted
if (this.offset && this.offset.parent && this.offset.parent.top !== this._getParentOffset().top) {
var deltaY = this.offset.parent.top - this._getParentOffset().top;
this.offset.parent.top = this._getParentOffset().top;
this.originalPageY -= deltaY;
}
this.helper[0].style.top = (event.pageY - this.originalPageY) +"px"; this.helper[0].style.top = (event.pageY - this.originalPageY) +"px";
} }
else this.helper[0].style.top = this.position.top+"px"; else this.helper[0].style.top = this.position.top+"px";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment