Reputation: 8228
I am trying to prevent moving item which is disabled during sorting using Angular CDK drag-drop
<div cdkDropList class="example-list"
[cdkDropListSortPredicate]="sortPredicateForDisableItem(items)"
(cdkDropListDropped)="drop($event)">
<div
class="example-box"
*ngFor="let item of items"
cdkDrag
[cdkDragDisabled]="item.disabled">{{item.value}}</div>
</div>
In Component,
public items = [
{value: 'I can be dragged 1', disabled: false},
{value: 'I can be dragged 2 ', disabled: false},
{value: 'I cannot be dragged and i want to be fixed in position 3', disabled: true},
{value: 'I can be dragged 4 ', disabled: false,dinesh: 'kumar'},
];
sortPredicateForDisableItem(items: any) {
// This logic fails to prevent moving disabled item
return function(index: number, item: CdkDrag, drop: CdkDropList){
return items[index].disabled === false
}
}
Before sorting
After sorting, Item3 shifting to new position and it can not be fixed in position
Can item which has disabled property can be fixed in position where it belongs? Expectation is , Disabled item always retain in same index/position during sorting. Please advise
Upvotes: 0
Views: 1246
Reputation: 4820
You can't simply "lock" the disabled item in place, since e.g. dragging something from index 0 to index 3 will affect indexes of all items in between. What you have to do is actually not allow drag actions that would change the index of the disabled item.
So, what you need to do is:
I've forked your stackblitz here and prepared a simple solution. I haven't tested it thoroughly, but it should give you basic idea how it should work.
What it does is basically writing custom moveItemInArray
function based on the original one from here:
private moveItemInArrayIfAllowed(
array: any[],
fromIndex: number,
toIndex: number
): void {
const from = this.clamp(fromIndex, array.length - 1);
const to = this.clamp(toIndex, array.length - 1);
if (from === to) {
return;
}
const target = array[from];
const delta = to < from ? -1 : 1;
const affectedItems = array.filter((item, index) =>
delta > 0 ? index >= from && index <= to : index >= to && index <= from
);
// If any of the items affected by the index changes is disabled
// don't move any of the items.
if (affectedItems.some((i) => i.disabled)) {
return;
}
for (let i = from; i !== to; i += delta) {
array[i] = array[i + delta];
}
array[to] = target;
}
private clamp(value: number, max: number): number {
return Math.max(0, Math.min(max, value));
}
Upvotes: 1