I am sure that automatic sorting will not, at least by default. Minimal self-sufficient examples are our friend. Well, despite the fact that there can be more examples on the Internet, and while it is difficult to prove a negative result, I will show that in the default case there is no automatic sorting and try to guess where the problem is.
Sorry, only after I realized that you are using pure JS and are probably using AngularJS and not Angular2. No matter what, the following should be somewhat helpful.
First we need a simple code base, we can use Angular -CLI to create the base ( https://www.npmjs.com/package/angular-cli ): then follow How to configure Angular -quickstart with ng2-dragula , and we will have one same starting base.
Now replace the contents of app.component.html with:
<div><button (click)="inOrderGreekAlphabet()">In Order Greek Alphabet</button></div> <div><button (click)="reversedGreekAlphabet()">Reversed Greek Alphabet</button></div> <div><button (click)="displyStateOfItems()">Display state of Items</button></div> <div> <div class='wrapper'> <div class='container' [dragula]='"first-bag"' [dragulaModel]="items"> <div *ngFor="let item of items">{{item}}</div> </div> </div> </div>
Replace the contents of app.component.ts with:
import {Component} from '@angular/core'; import {DragulaService} from 'ng2-dragula/ng2-dragula'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], viewProviders: [DragulaService] }) export class AppComponent { public items: string[]; private GREEK_ALPHABET:string[] = ["alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa", "lambda", "mu", "nu", "xi", "omicron", "pi", "rho", "sigma", "tau", "upsilon", "phi", "chi", "psi", "omega"]; constructor() { this.inOrderGreekAlphabet(); } public inOrderGreekAlphabet(){ this.items = this.GREEK_ALPHABET.slice(); } public reversedGreekAlphabet() { this.items = this.GREEK_ALPHABET.reverse(); } public displyStateOfItems(){ alert(JSON.stringify(this.items)); } }
If you run the above, you will find that the model is synchronized with the list, as shown on the screen using the "Display item status" button. However, if we remove [dragulaModel]="items" from app.component.html , we find that the model is out of sync. Itβs not that dragula does something extra, but actually does something less.
Now, to fix the problem ...
When synchronizing the local state, we can try this in several ways:
First of all, note that when [dragulaModel]="items" is added, the list is synchronized with the array, but we still need a hook for our user server synchronization code, more on this later.
If we ignore the structure of dragula and perhaps try to create a setter-receiver for the elements. However, if we rename all element instances to _items, then add:
//This is to demonstrate an issue, this is NOT A Solution! get items():string[]{ console.log("call from getter: could do server sync here?"); return this._items; } set items(i:string[]){ console.log("call from setter: or perhaps here?"); this._items = i; }
However, the above DOES NOT WORK , or rather, it can work, but viewing the console logs shows that the installer is called once, and then all subsequent access is performed using the getter and that the receiver is called many times during drag and drop, if the user freezes and moves, perhaps hundreds of calls can be generated in seconds. In addition, it would be nice to tell the user whether the page needs to be saved or not, by comparing the array in a potentially unlimited list, an indefinite number of times just doesn't seem like a good idea, and although there may be pure Java / TypeScript solutions that could solve this problem, provide the ability to perform checks only once when the item is deleted.
Add the following code, replacing the constructor and removing this setter / getter, because it was a stupid idea (we are only really interested in the drop, but the fullness never hurts):
constructor(private dragulaService: DragulaService) { dragulaService.drag.subscribe((value) => { console.log(`drag: ${value[0]}`); this.onDrag(value.slice(1)); }); dragulaService.drop.subscribe((value) => { console.log(`drop: ${value[0]}`); this.onDrop(value.slice(1)); }); dragulaService.over.subscribe((value) => { console.log(`over: ${value[0]}`); this.onOver(value.slice(1)); }); dragulaService.out.subscribe((value) => { console.log(`out: ${value[0]}`); this.onOut(value.slice(1)); }); this.inOrderGreekAlphabet(); } private onDrag(args) { let [e, el] = args;
Above was taken from https://github.com/valor-software/ng2-dragula#events and provides the ability to manually implement synchronization without using the dragulaModel directive, but we can also build this directive, as shown in the following section of the documentation ( https: / /github.com/valor-software/ng2-dragula#special-events-for-ng2-dragula ), so instead of doing the above, we minimally (and in this case, we must use the dragulaModel directive):
constructor(private dragulaService: DragulaService) { dragulaService.dropModel.subscribe((value) => { console.log(`dropModel: ${value[0]}`); this.onDropModel(value); }); this.inOrderGreekAlphabet(); } private onDropModel(args){ let [bagName, el, target, source] = args;
And you should have a good working solution.