components
components copied to clipboard
bug(Chip Input): matChipInputSeparatorKeyCodes won't recognize ";" and doesn't recognize pasted text
Reproduction
Use StackBlitz to reproduce your issue: https://stackblitz.com/edit/angular-cr3nwj?file=src/app/chips-autocomplete-example.ts
Steps to reproduce:
- Using a mat-form-field with mat-chip-list and an input.
- Declare the [matChipInputSeparatorKeyCodes]="separatorKeysCodes", with separatorKeysCodes: number[] = [ENTER, COMMA, SEMICOLON, 188];
- Use a ";" in the input to trigger the chipEnd event. But i won't trigger. Neither by pressing the semicolon (EU Keyboard keys: shift + ,")
- The input wont trigger the chipEnd after pasting text into the input and doesnt check for the separatorKeys in the pasted text.
Expected Behavior
The chipEnd event should be triggered after typing the Semicolon into to the input. Also should pasted text be regnozed and processed based on the declared separatorKeys. For example: separatorKeys [COMMA] Pasted text: "name1, name2, name3" After pasting chipEnd event triggers and created 3 chips: "name1", "name2", "name3"
Actual Behavior
Semicolon doesn't trigger any event and will just display in the input. Pasted text also doesn't trigger any event and will just display in the input.
Environment
- Angular: 11.0.0
- CDK/Material: 11.0.0
- Browser(s): Google Chrome
- Operating System (e.g. Windows, macOS, Ubuntu): Windows 10 Pro
for the paste function there is a work around: https://github.com/angular/components/issues/11690
As you mentioned, the paste issue is known and we can't do much about it on our end, because there's no nice way to convert a character to its key code so we know where to split a string. As for the semicolon separator issue, it seems to work for me. Maybe it's due to your keyboard layout?
I asked some Friends to test it: French Keyboard also works. German Keyboards don`t. I used https://keycode.info/ to test the keycode: For me "shift"+"," give the keycode: 188 event.key ; event.location 0 (General keys) event.which(deprecated) 188 event.code Comma
What appears to be happening is that the semicolon is at a different key in the German keyboard than the English one. I don't think there's a good way around it, apart from having an option for separator characters as well. It has the added benefit of supporting the case where the user pastes in a string that needs to be split into chips. The problem is that having both a separatorKeyCodes
and separatorCharacters
might be confusing from an API standpoint.
Commas seem to not be reconized in test harnesses (MatChipInputHarness)
In my component.ts file I declare separator keys codes with the following :
readonly separatorKeysCodes = [ENTER, COMMA];
It's working very well on my browser but when I want to test it :
it('should add email when email and a comma or return is entered', async () => {
expect(chips.length).toBe(0);
await toEmailChipListInput.setValue('[email protected]');
await toEmailChipListInput.sendSeparatorKey(TestKey.ENTER);
await toEmailChipListInput.setValue('[email protected]');
await toEmailChipListInput.sendSeparatorKey(','); // <--- doesn't work
chips = await toEmailChipList.getChips();
expect(chips.length).toBe(2);
expect(await chips[0].getText()).toBe('[email protected]');
expect(await chips[1].getText()).toBe('[email protected]');
});
sendSeparatorKey with common comma (,) doesn't trigger the right behavior. I'm french so on a french computer/keyboard (AZERTY)
Another problem that is caused by this bug is that you can't enter the German letter 'ü' (keycode 186) into the input field. (Pasting works and even the big 'Ü' works.) Edit: This is browser specific. Entering 'ü' doesn't work for Chrome / Edge but for Firefox it does.
probably KeyboardEvent.key
(docs) should be used for chips' separator keys instead of KeyboardEvent.keyCode
(it's deprecated) becuase KeyboardEvent.key
"...returns the value of the key pressed by the user, taking into consideration the state of modifier keys such as Shift as well as the keyboard locale and layout."
@crisbeto what do you think?
there's a similar issue https://github.com/angular/components/issues/13989 to the one @dominik1996 has mentioned but only for cyrillic input
Commas seem to not be reconized in test harnesses (MatChipInputHarness)
In my component.ts file I declare separator keys codes with the following :
readonly separatorKeysCodes = [ENTER, COMMA];
It's working very well on my browser but when I want to test it :
it('should add email when email and a comma or return is entered', async () => { expect(chips.length).toBe(0); await toEmailChipListInput.setValue('[email protected]'); await toEmailChipListInput.sendSeparatorKey(TestKey.ENTER); await toEmailChipListInput.setValue('[email protected]'); await toEmailChipListInput.sendSeparatorKey(','); // <--- doesn't work chips = await toEmailChipList.getChips(); expect(chips.length).toBe(2); expect(await chips[0].getText()).toBe('[email protected]'); expect(await chips[1].getText()).toBe('[email protected]'); });
sendSeparatorKey with common comma (,) doesn't trigger the right behavior. I'm french so on a french computer/keyboard (AZERTY)
So after debugging, looks like TestBed uses charCodeAt for keyCode events and then MatChipInput expect that to match the list of separatorKeysCodes which don't match as charCode != keyCode
Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.
Find more details about Angular's feature request process in our documentation.
Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.
We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.
You can find more details about the feature request process in our documentation.
Did you find any solution related to the same? TestKey.ENTER is throwing CORS error in my case.
For me the await chipInput.sendSeparatorKey(TestKey.ENTER);
even does not work. The test harness seams to be broken.
I would recommend to use Spectator Event Helpers they work a lot better.
Instead of this which does not work
const chipInput = await loader.getHarness(MatChipInputHarness);
await chipInput.setValue('Label 3');
await chipInput.sendSeparatorKey(TestKey.ENTER);
const chips = await loader.getAllHarnesses(MatChipHarness);
expect(chips.length).toBe(3);
You can to this, which also is not async
const input = spectator.query('input');
spectator.typeInElement('Label 3', input);
spectator.dispatchKeyboardEvent(input, 'keydown', ENTER);
const chips = spectator.queryAll(MatChip);
expect(chips.length).toBe(3);