記事ディレクトリ
sortablejs は、強力な JavaScript ドラッグ アンド ドロップ ライブラリです。
例証する
Angular プロジェクトで sortablejs ドラッグ アンド ドロップ ライブラリを使用する場合、sortablejs コマンドをカプセル化し、次のパラメーターをサポートする、セカンダリ パッケージ化された Angular ドラッグ アンド ドロップ ライブラリである ngx-sortablejs を使用する必要があります。
@Directive({
selector: "[sortablejs]",
})
export class SortablejsDirective {
// 拖拽列表的数据项
@Input() sortablejs: SortableData; // array or a FormArray
// 指定拖拽的容器
@Input() sortablejsContainer: string;
// 拖拽相关的配置项
@Input() sortablejsOptions: Options;
@Input() sortablejsCloneFunction: (item: any) => any;
// 在一个拖拽实例被创建并初始化好之后,会立即emit出这个拖拽实例。
@Output() sortablejsInit = new EventEmitter<Sortable>()
}
基本的な使い方
1.プレーンバージョン
<div
class="container"
[sortablejs]="items"
[sortablejsOptions]="draggableOptions"
>
<div *ngFor="let item of items" class="item">
{
{ item.name }}
</div>
</div>
import {
SortableOptions } from 'sortablejs';
draggableOptions: SortableOptions = {
};
2.ドラッグできるアイテムのスタイルを設定する
<div
class="container"
[sortablejs]="items"
[sortablejsOptions]="draggableOptions"
>
<ng-container *ngFor="let item of items">
<div *ngIf="item.id !== '002'" class="item sortable-item">
{
{ item.name }}
</div>
<div *ngIf="item.id === '002'" class="item">
{
{ item.name }},这个项不可被拖起
</div>
</ng-container>
</div>
draggableOptions: SortableOptions = {
// 允许拖拽的项的类名,只有这个类名的项才可以拖起
draggable: '.sortable-item',
};
.sortable-item {
background-color: antiquewhite;
}
3. 選択したアイテムのスタイルを設定する
draggableOptions: SortableOptions = {
// 拖拽项被选中时的类名
chosenClass: 'sortable-chosen',
};
.sortable-chosen {
background-color: lightblue;
}
4. ドラッグ時に追従する影のスタイルを設定する
draggableOptions: SortableOptions = {
// 项被拖拽的过程中跟随它的那个影子的类名
ghostClass: 'sortable-ghost',
};
.sortable-ghost {
background-color: lightgray;
}
5. ドラッグ中のスタイルを設定する
draggableOptions: SortableOptions = {
dragClass: 'sortable-drag',
};
.sortable-drag {
background-color: orange;
border-bottom: none;
}
6. 現在のリスト コンテナでドラッグ アンド ドロップによる並べ替えを実行できるかどうかを設定する
draggableOptions2: SortableOptions = {
sort: false, // 值为false,组内不可拖拽排序
group: {
name: 'china',
pull: true, // 组内的项可以被拖出去到其它组
}
};
7.ドラッグハンドルを設定する
<div
class="container"
[sortablejs]="items"
[sortablejsOptions]="draggableOptions"
>
<div *ngFor="let item of items" class="item sortable-item">
<div class="sortable-handle">手柄</div>
{
{ item.name }}
</div>
</div>
draggableOptions: SortableOptions = {
// draggable: '.sortable-item',
// 可拖拽项的手柄的类名,只有按住手柄才能拖起。(如果将上面那行注释放开,那就不只有手柄能拖拽了)
handle: '.sortable-handle',
};
8. 複数のリスト間でドラッグ&ドロップ [グループ]
例 1 [名前]
構成アイテムの group 属性に同じ名前を持つ 2 つのドラッグ グループ間のアイテムは、互いにドラッグできます。
// 甲组
draggableOptions1: SortableOptions = {
group: {
name: 'wmm',
}
};
// 乙组
draggableOptions2: SortableOptions = {
group: {
name: 'wmm',
}
};
例 2 [入れる]
複数のドラッグ グループに異なる名前が付けられている場合、put を使用して、他のグループの条件を満たすアイテムのみを現在のリストにドラッグできるように指定できます。
// 甲组
draggableOptions1: SortableOptions = {
group: {
name: 'wmm',
}
};
// 乙组
draggableOptions2: SortableOptions = {
group: {
name: 'china',
}
};
// 丙组
draggableOptions3: SortableOptions = {
group: {
name: 'happy',
/**
* put字段的值可以指定为以下四种:
* true: 可以将其它指定组的项拖进本组
* false: 其它任何组的项都不能拖到本组
* ['wmm', 'china']: 只能将甲组和乙组的项拖到本组。['china']: 只能将乙组的项拖到本组。
* function: 自定义函数,可进行复杂逻辑判断,根据返回true或false,来判断当前被拖拽的项是否能往本组里放。
*/
put: ['china'], // 指定甲组和乙组的项可以往丙组里面放
}
};
例 3 [put 関数]
ドラッググループが複数ある場合、関数として put の値を指定し、関数内で複雑な判定を行うことで、ドラッグしたアイテムをこのグループにドラッグできるかどうかを指定できます。
<div
class="container2"
[sortablejs]="items2"
[sortablejsOptions]="draggableOptions2"
>
乙组
<div
*ngFor="let item of items2"
class="item sortable-item2"
[ngClass]="{
'can-move-to-happy': item.name.indexOf('乙 5') === -1
}"
>
{
{ item.name }}
{
{ item.name.indexOf("乙 5") !== -1 ? "--该项不可用被拖进丙组" : "" }}
</div>
</div>
// 乙组
draggableOptions2: SortableOptions = {
group: {
name: 'china',
}
};
// 丙组
draggableOptions3: SortableOptions = {
group: {
name: 'happy',
/**
* put的值可以是一个自定义function,可进行复杂逻辑判断。
* 根据返回true或false,来判断当前被拖拽的项是否能往本组里放。
*/
put: (
to: Sortable,
from: Sortable,
dragEl: HTMLElement,
event: SortableEvent
) => {
// 判断:只有带有样式类名为'can-move-to-happy'的项,才能被拖进本组。
return dragEl?.classList.contains('can-move-to-happy');
},
}
};
例 4 [プル]
draggableOptions2: SortableOptions = {
group: {
name: 'china',
/**
* 从一个列表中拖动到另一个列表时,是否允许拖动。 默认值:true。
* true:允许拖动
* false:不允许拖动
* 'clone':克隆一个副本拖到其它组
* function:自定义函数,可进行复杂逻辑判断,根据返回true或false,来判断被拖拽的项是否可从本组移出去。
*/
pull: (
to: Sortable,
from: Sortable,
dragEl: HTMLElement,
event: SortableEvent
) => {
return !dragEl?.classList.contains('can-move-to-happy');
},
},
};
この例ではスクリーンショットを撮りません。
9.ネストされた複数のドラッググループ
<div
class="grandpa-container"
[sortablejs]="treeItems"
[sortablejsOptions]="draggableOptions"
>
<div
*ngFor="let grandpa of treeItems"
class="item"
[id]="grandpa.id"
[ngClass]="{
a: grandpa.name.indexOf('甲') !== -1,
b: grandpa.name.indexOf('乙') !== -1,
c: grandpa.name.indexOf('丙') !== -1
}"
>
{
{ grandpa?.name }}
<ng-container *ngIf="grandpa?.children?.length">
<div
class="father-container"
[id]="grandpa.id"
[sortablejs]="grandpa?.children"
[sortablejsOptions]="draggableOptions"
>
<div
*ngFor="let father of grandpa?.children"
class="item"
[id]="father.id"
[ngClass]="{
a: father.name.indexOf('甲') !== -1,
b: father.name.indexOf('乙') !== -1,
c: father.name.indexOf('丙') !== -1
}"
>
{
{ father?.name }}
<ng-container *ngIf="father?.children?.length">
<div
class="son-container"
[id]="father.id"
[sortablejs]="father?.children"
[sortablejsOptions]="draggableOptions"
>
<div
*ngFor="let son of father?.children"
class="item"
[id]="son.id"
[ngClass]="{
a: son.name.indexOf('甲') !== -1,
b: son.name.indexOf('乙') !== -1,
c: son.name.indexOf('丙') !== -1
}"
>
{
{ son?.name }}
</div>
</div>
</ng-container>
</div>
</div>
</ng-container>
</div>
</div>
public draggableOptions: SortableOptions = {
group: {
name: 'wmm',
}
// 元素 从其它拖拽分组 拖进 本拖拽分组 时触发
onAdd: (event: SortableEvent) => {
console.log('onAdd event:', event);
console.log('自身id:', event.item.id);
console.log('当前所属父id:', event.to.id);
console.log('在当前分组中的index:', event.newIndex);
},
// 元素在本拖拽分组中的位置发生改变时触发
onUpdate: (event: SortableEvent) => {
console.log('onUpdate event:', event);
},
};
public treeItems: {
id: string;
name: string;
children?: any[] = [];
} = [];
ngOnInit(): void {
// 初始化 treeItems
for (let i = 0; i < 5; i++) {
let grandpa: any = {
id: `0${
i}`, name: `甲 0${
i}`, children: [] };
if (i === 1) {
let fathers: any = [];
for (let j = 0; j < 5; j++) {
const fatherItem: any = {
id: `00${
j}`,
name: `乙 00${
j}`,
};
if (j === 4) {
let sons: any = [];
for (let k = 0; k < 5; k++) {
const sonItem = {
id: `000${
k}`,
name: `丙 000${
k}`,
};
sons.push(sonItem);
}
fatherItem.children = sons;
}
fathers.push(fatherItem);
}
grandpa.children = fathers;
}
this.treeItems.push(grandpa);
}
}
最初のドラッグ アンド ドロップ:
2 回目のドラッグ アンド ドロップ:
学びの源
その他の設定項目とコールバック メソッド: http://www.sortablejs.com/options.html
その他の例: http://sortablejs.github.io/Sortable/
並べ替え可能なリポジトリ: https://github.com/SortableJS/ 並べ替え可能な
ngx -sortablejs リポジトリ https://github.com/sortablejs/ngx-sortablejs#readme