2

I have an Angular application. which contains two drag and drop lists that are working fine. I want to add a filter to search for items inside the lists. The problem is when I filter items, the function transferArrayItem will use the wrong index and this is why it will move the wrong item.
I have added a stackblitz code to show the problem. To reproduce the problem please follow the steps:

  1. over the first list click search and type number 2
  2. try to move the item to the second list, it will move the item 1.

https://stackblitz.com/edit/angular-mwnmo5?file=src%2Fapp%2Fapp.component.ts

2
  • 1
    You'll need to find the position of the dragged element in the original array, since filtering changes the indexing of the elements. Array.findIndex (developer.mozilla.org) Commented Oct 26, 2021 at 7:49
  • that didnt work either. Commented Oct 26, 2021 at 11:52

2 Answers 2

1

I finally found a way to solve the issue with the cleanest code. I am using id with cdkDropList to know the source list, then I am transferring the item manually instead of using the transferArrayItem function provided by cdkDragDrop.

the full code is in
https://stackblitz.com/edit/angular-htpgvx?file=src%2Fapp%2Fapp.component.ts

Sign up to request clarification or add additional context in comments.

Comments

0

https://stackblitz.com/edit/angular-zscthy?file=src%2Fapp%2Fapp.component.ts

You need to update the original a/b object after dropping item from container to another container. So It's not possible to use search-box component to do so.

app.component.html, I added <input> and removed <app-search-box>, added id to <div cdkDropList>

<input
  #search_a
  type="text"
  class="form-control"
  placeholder="Search"
  aria-label="Search"
  aria-describedby="basic-addon1"
/>

<div
  cdkDropList
  [cdkDropListData]="selectedList"
  class="example-list"
  (cdkDropListDropped)="dropItem($event)"
  id="a_drop_list"
>

app.component.ts, I added code to listen input keydown event

fromEvent(this.search_a.nativeElement, 'keydown')
  .pipe(
    debounceTime(550),
    map(x => x['target']['value'])
  )
  .subscribe(value => {
    this.updateFilter_a(value);
  })

Added updateFilter function , it trigger when input keydown

  updateFilter_a(val: any) {
    this.selectedList = [];
    this.selectedList = a.filter(v => v.title.indexOf(val)>= 0 || v.description.indexOf(val) >= 0);
  }

Modified dropItem(added code to delete item in a/b object when user moved item from container to another container)

  dropItem(event: CdkDragDrop<any[]>) {
    if (event.previousContainer !== event.container) {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );

  //dropped item id
  const delete_id = event.container.data[event.currentIndex].id;

  //item drop to a_drop_list
  if(event.container.id === 'a_drop_list') {
    //find object b item index when id == device_id
    var index = b.findIndex(function(o){
      return o.id === delete_id;
    })
    //delete item match id == device_id in obejct b
    if (index !== -1) b.splice(index, 1);
  } else if(event.container.id === 'b_drop_list') {
    var index = a.findIndex(function(o){
      return o.id === delete_id;
    })
    if (index !== -1) a.splice(index, 1);
  }
}

5 Comments

I didnt understand the changes fully. However, it is still not working but now with a different problem. try to type number one in the first search box and delete it. The item number 1 will disappear and never show again
@Sarahbe I edited and fixed issue
this still doesnt work. it still has some bugs.
@Sarahbe what bugs did you face?
in the first search box, type 2. then move any item from the second list to the first list. now delete the filter, the item you have moved will not appear in any of the lists. thank you anyway for the help. please see the solution I have suggested

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.