0

I have an open dropdown with multiple options. I created a simple pickList out of with two. I am using splice to remove selected values from the array after button click but when the selection is multiple, splice seems to remove all but the ones selected.

For example: in my list to the right - if i choose San Francisco, Miami, Boston and Las Vegas then move them over to the selected box on the right. This works perfect.

enter image description here

The issue is choosing Boston & Miami then clicking the left arrow to remove, removes all but the selected ones. I have used splice before but I do not remember it ignoring the items in array.

And my code component looks like this:

<select [(ngModel)]="foundLocations" multiple="multiple">
    <option *ngFor="let locOption of locations" [ngValue]="locOption" >
      {{ locOption }}
    </option>
</select>
<div class="selectButtons">
  <button (click)="selectThese()">></button>
    <br/>
  <button (click)="removeThese()"><</button>
</div>
<select [(ngModel)]="selectedLocations" multiple="multiple">
    <option *ngFor="let chosen of pickedLocationItems" [ngValue]="chosen" >
      {{ chosen }}
    </option>
</select>

and in my component looks like:

  foundLocations: any;
  selectedLocations: any = [];
  pickedLocationItems: any = [];

  locations: any = ["San Francisco", "Seattle", "Las Vegas", "Toronto", "Boston", "Miami", "Altantic City"];

  selectThese() {
    for (var i = 0; i < this.foundLocations.length; i++) {
      this.checkSelLocation(this.foundLocations[i]);
    }
  }

  checkSelLocation(x: any) {
    console.log("Check sel locations");
    console.log(x);
    this.pickedLocationItems.push(x);
  }

  removeThese() {
    for (var g = 0; g < this.selectedLocations.length; g++) {
      this.pickedLocationItems.splice(g, 1); 
    }
  }

I have a Stackblitz example here.

2 Answers 2

1

To achieve expected result, change you removeThese method as below

  1. Index which you are choosing to splice is wrong(because index of g starts from 0 and actual selected location may not start with index -0 )
  2. First find index by indexOf
  3. Splice using that index

removeThese() { for (var g = 0; g < this.selectedLocations.length; g++) { this.pickedLocationItems.splice(this.pickedLocationItems.indexOf(this.selectedLocations[g]), 1); } }

working code sample for reference- https://stackblitz.com/edit/angular-xwwevl?file=src/app/app.component.ts

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

1 Comment

Took a bit of time for me to realize it was an issue with the index. Thanks, i used your example after almost giving up and it worked perfectly.
0

Splice is the wrong tool here. What you want to do is filter out any elements that are selected like so:

removeThese() {
    this.pickedLocationItems = this.pickedLocationItems.filter(item => !this.selectedLocations.includes(item));
  }

Array.splice removes a range of elements starting at an index, so in order to use that, you would need to find the index of each selected item and splice that index, because the selection may not be contiguous. The way you were using it, you were looping from 0 to the length of the selection array, which does not correspond to the index of the selected elements. Using Array.filter gets the job done in one go by removing all values that exist in the selection array.

Comments

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.