How to limit the number of items displayed in an NgSelect dropdown panel?

2.6k views Asked by At

So I am using Angular ngselect to display a dropdown which contains a bunch of options. Due to the restrictions of the screen, I want to limit the number of items displayed in the dropdown to let's say 3 and the user can scroll through the remaining ones.

I a using ng-select inside a reactive form and [![It looks something like this][1]][1]

When I click payment method, the layout seems to be fine as it only contains 2 items. [![enter image description here][2]][2]

But when click on the other dropdown, it gets cut off as the size of the dropdown doesn't fit inside the container

[![enter image description here][3]][3]

Another approach that I tried was to append this ng select dropdown to body by writing appendTo="body"

When the dropdown pops up it looks something like this [![enter image description here][4]][4]

But the major problem with this approach is that when I scroll through the parent which in this case is the body, the dropdown gets stuck to the same place where it was originated whereas the ideal behavior should be that it should move along with the ngselect element.

[![enter image description here][5]][5]

How can i limit the number of elements displayed so that it fits inside the container. [1]: https://i.stack.imgur.com/HdfAb.png [2]: https://i.stack.imgur.com/WRvk7.png [3]: https://i.stack.imgur.com/P1W2w.png [4]: https://i.stack.imgur.com/5augz.png [5]: https://i.stack.imgur.com/8Nitf.png

1

There are 1 answers

3
10101101 On

Take a look here issue on github

Here bottom one example

And here version with checkbox

Here an basic example with only 4 items visible. As You can see, hence slice:0:4 in *ngFor directive. Also there is a check if there are more than 4 items selected in the span with "more..." text.

<ng-select
    [items]="daysOfWeek"
    [multiple]="true"
    bindLabel="name"
    bindValue="order"
    placeholder="Select days"
    [(ngModel)]="selectedDays">
    <ng-template ng-multi-label-tmp let-items="items" let-clear="clear">
        <div class="ng-value" *ngFor="let item of items | slice:0:4">
            <span class="ng-value-label">{{item.name}}</span>
            <span class="ng-value-icon right" (click)="clear(item)" aria-hidden="true">×</span>
        </div>
        <div class="ng-value" *ngIf="items.length > 4">
            <span class="ng-value-label">{{items.length - 4}} more...</span>
        </div>
    </ng-template>
</ng-select>

And then in the component

export class MultiSelectCustomExampleComponent implements OnInit {

    daysOfWeek: DayOfWeek[] = [];
    selectedDays: DayOfWeek[] = [];

    constructor() {
    }

    ngOnInit() {
        this.daysOfWeek = [
            new DayOfWeek("Monday", 1),
            new DayOfWeek("Tuesday", 2),
            new DayOfWeek("Wednesday", 3),
            new DayOfWeek("Thursday", 4),
            new DayOfWeek("Friday", 5),
            new DayOfWeek("Saturday", 6),
            new DayOfWeek("Sunday", 7),
        ];
    }
}

And some model for the list

export class DayOfWeek {

    name: string;
    order: number;
    
    constructor(name: string, order: number) {
        this.name = name;
        this.order = order;
    }
}