* Trigger the given range of options in response to user interaction. * Should only be called in multi-selection mode. * @param trigger The option that was triggered * @param from The start index of the options to toggle * @param to The end index of the options to toggle * @param on W
(trigger: CdkOption<T> | null, from: number, to: number, on: boolean)
| 661 | * @param on Whether to toggle the option range on |
| 662 | */ |
| 663 | protected triggerRange(trigger: CdkOption<T> | null, from: number, to: number, on: boolean) { |
| 664 | if (this.disabled || (trigger && trigger.disabled)) { |
| 665 | return; |
| 666 | } |
| 667 | this._lastTriggered = trigger; |
| 668 | const isEqual = this.compareWith ?? Object.is; |
| 669 | const updateValues = [...this.options] |
| 670 | .slice(Math.max(0, Math.min(from, to)), Math.min(this.options.length, Math.max(from, to) + 1)) |
| 671 | .filter(option => !option.disabled) |
| 672 | .map(option => option.value); |
| 673 | const selected = [...this.value]; |
| 674 | for (const updateValue of updateValues) { |
| 675 | const selectedIndex = selected.findIndex(selectedValue => |
| 676 | isEqual(selectedValue, updateValue), |
| 677 | ); |
| 678 | if (on && selectedIndex === -1) { |
| 679 | selected.push(updateValue); |
| 680 | } else if (!on && selectedIndex !== -1) { |
| 681 | selected.splice(selectedIndex, 1); |
| 682 | } |
| 683 | } |
| 684 | let changed = this.selectionModel.setSelection(...selected); |
| 685 | if (changed) { |
| 686 | this._onChange(this.value); |
| 687 | this.valueChange.next({ |
| 688 | value: this.value, |
| 689 | listbox: this, |
| 690 | option: trigger, |
| 691 | }); |
| 692 | } |
| 693 | } |
| 694 | |
| 695 | /** |
| 696 | * Sets the given option as active. |