components icon indicating copy to clipboard operation
components copied to clipboard

bug(Chip Input): matChipInputSeparatorKeyCodes won't recognize ";" and doesn't recognize pasted text

Open Criedor opened this issue 3 years ago • 12 comments

Reproduction

Use StackBlitz to reproduce your issue: https://stackblitz.com/edit/angular-cr3nwj?file=src/app/chips-autocomplete-example.ts

Steps to reproduce:

  1. Using a mat-form-field with mat-chip-list and an input.
  2. Declare the [matChipInputSeparatorKeyCodes]="separatorKeysCodes", with separatorKeysCodes: number[] = [ENTER, COMMA, SEMICOLON, 188];
  3. Use a ";" in the input to trigger the chipEnd event. But i won't trigger. Neither by pressing the semicolon (EU Keyboard keys: shift + ,")
  4. 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

Criedor avatar Dec 04 '20 09:12 Criedor

for the paste function there is a work around: https://github.com/angular/components/issues/11690

Criedor avatar Dec 04 '20 10:12 Criedor

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?

crisbeto avatar Dec 07 '20 17:12 crisbeto

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

Criedor avatar Dec 08 '20 08:12 Criedor

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.

crisbeto avatar Dec 12 '20 09:12 crisbeto

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)

MikaStark avatar Jan 11 '21 14:01 MikaStark

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.

dominik1996 avatar Apr 06 '21 11:04 dominik1996

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?

AlexElin avatar Jun 17 '21 10:06 AlexElin

there's a similar issue https://github.com/angular/components/issues/13989 to the one @dominik1996 has mentioned but only for cyrillic input

AlexElin avatar Jun 17 '21 10:06 AlexElin

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

wawyed avatar Sep 27 '21 16:09 wawyed

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.

angular-robot[bot] avatar Mar 13 '22 15:03 angular-robot[bot]

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.

angular-robot[bot] avatar Apr 01 '22 15:04 angular-robot[bot]

Did you find any solution related to the same? TestKey.ENTER is throwing CORS error in my case.

adityagantayat avatar Jul 27 '22 10:07 adityagantayat

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);

DaSchTour avatar Oct 20 '22 18:10 DaSchTour