Skip to content

Commit 0707d1e

Browse files
Check for the first available space to move the item up
This takes the selected elements width and its position to check for the first item above. When no direct item is found find the first item in the row above and move the item above that.
1 parent e2f1b79 commit 0707d1e

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

src/dd-draggable.ts

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
8383
this._mouseMove = this._mouseMove.bind(this);
8484
this._mouseUp = this._mouseUp.bind(this);
8585
this._keyEvent = this._keyEvent.bind(this);
86+
this._sortByRow = this._sortByRow.bind(this);
8687
this.enable();
8788
}
8889

@@ -176,6 +177,57 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
176177
return this._node().grid
177178
}
178179

180+
_itemNode(item) {
181+
return item['gridstackNode']
182+
}
183+
184+
_nodePosition(node) {
185+
return {
186+
width: node.w - 1,
187+
height: node.h,
188+
column: node.x,
189+
row: node.y
190+
}
191+
}
192+
193+
_items() {
194+
return document.querySelectorAll('.grid-stack-item:not(.grid-stack-placeholder)')
195+
}
196+
197+
_sortByRow(a, b) {
198+
return this._itemNode(a).y - this._itemNode(b).y
199+
}
200+
201+
// Find the first item above the selectedNode.
202+
// Add the items row and its height, this should be the same as the selectedNodes row, if so, the item is in the row directly
203+
// above the selectedNode.
204+
// Also check if the item column overlaps the selectedNodes columns and include the items width in this calculation
205+
_findItemAbove () {
206+
const selectedNode = this._nodePosition(this._node())
207+
208+
return Array.from(this._items()).filter(item => {
209+
const itemNode = this._nodePosition(this._itemNode(item))
210+
211+
if ((itemNode.row + itemNode.height) !== selectedNode.row) { return false }
212+
if (selectedNode.column < itemNode.column) { return false }
213+
if (selectedNode.column > (itemNode.column + itemNode.width)) { return false }
214+
return item
215+
})[0]
216+
}
217+
218+
// When we have not found any items in the row directly above the selectedNode.
219+
// Look for the first item it can find above the selectedNodes row.
220+
_findFirstItemAbove () {
221+
const selectedNode = this._nodePosition(this._node())
222+
223+
return Array.from(this._items()).filter(item => {
224+
if (item === this.el) { return false }
225+
const itemNode = this._nodePosition(this._itemNode(item))
226+
227+
if (itemNode.row < selectedNode.row) { return item }
228+
}).sort(this._sortByRow).reverse()[0]
229+
}
230+
179231
protected _elNewCoordinates(event: KeyboardEvent, element: HTMLElement) {
180232
const selectedNode = this._node();
181233
const cellHeight = this._grid().getCellHeight() * selectedNode.h
@@ -197,7 +249,10 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
197249
case 'ArrowUp':
198250
if (selectedNode.y === 0) { break }
199251

200-
yCoord = -cellHeight
252+
let itemAbove = this._findItemAbove()
253+
if (itemAbove === undefined) { itemAbove = this._findFirstItemAbove() }
254+
255+
yCoord = -(this._itemNode(itemAbove).h * this._grid().getCellHeight())
201256
break
202257
case 'ArrowDown':
203258
yCoord = cellHeight

0 commit comments

Comments
 (0)