ngx-chips icon indicating copy to clipboard operation
ngx-chips copied to clipboard

onTagEdited not firing?

Open m-ghaoui opened this issue 6 years ago • 22 comments

I'm submitting a ... (check one with "x")

[x] bug report => search github for a similar issue or PR before submitting
[ ] support request/question

Notice: feature requests will be ignored, submit a PR if you'd like

Current behavior I have a tag-input with (onTagEdited)="onTagEdited($event)". I double click on a tag, make changes, and the tag automatically reverts back to the old value.

Expected behavior I expect the onTagEdited event to fire and the tag to be renamed.

Minimal reproduction of the problem with instructions (if applicable)

What do you use to build your app?. Please specify the version "@angular/cli": "^1.7.3"

Angular version:

    "@angular/animations": "^5.2.9",
    "@angular/cdk": "^5.2.4",
    "@angular/common": "^5.2.9",
    "@angular/compiler": "^5.2.9",
    "@angular/core": "^5.2.9",
    "@angular/forms": "^5.2.9",
    "@angular/http": "^5.2.9",
    "@angular/material": "^5.2.4",
    "@angular/material-moment-adapter": "^5.2.4",
    "@angular/platform-browser": "^5.2.9",
    "@angular/platform-browser-dynamic": "^5.2.9",
    "@angular/router": "^5.2.9",

ngx-chips version: "ngx-chips": "^1.7.7"

Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ] Chrome 67.0.3389.0 (Official build) canary (64-bits) Firefox Quantum 59.0.2 (64-bits)

m-ghaoui avatar Apr 05 '18 08:04 m-ghaoui

I reverted back to the version I used when I first wrote the code:

"ngx-chips": "1.6.2",

and the event does fire.

image

m-ghaoui avatar Apr 05 '18 08:04 m-ghaoui

Hi are you using a validator? Please post some code.

Gbuomprisco avatar Apr 05 '18 09:04 Gbuomprisco

Sure,

Here is the relevant tag:

</form> <!-- Note, the form is above the tag-input -->

<tag-input [(ngModel)]="trainingTagsInTrainingList" [identifyBy]="'Guid'" [displayBy]="'Name'" [addOnBlur]="true" [clearOnBlur]="true"
    (onAdd)="onTagAdd($event)" (onRemove)="onTagRemove($event)" (onTagEdited)="onTagEdited($event)" placeholder="+Tag"
    secondaryPlaceholder="Voeg tag toe" [editable]="true">
    <tag-input-dropdown #tagInputDropDownTags [autocompleteItems]="trainingTagsList" [identifyBy]="'Guid'" [displayBy]="'Name'"
    [showDropdownIfEmpty]="true" [focusFirstElement]="false">
    </tag-input-dropdown>
</tag-input>

I do have a FormBuilder and a bunch of form fields with the formControlName tag.

But the <tag-input> is below the <form> element and uses [(ngModel)]. As far as I know, I am not using a validator in the <tag-input>.

The trainingsInTagList and trainingTagsList looks like this:

trainingTagsInTrainingList: GuidName[]; // The model
trainingTagsList: GuidName[]; // The values for the tag-input-dropdown

Event handlers:

public onTagAdd(item: GuidName) {
    this.addTag(item); 
}

public onTagRemove(item: GuidName) {
    this.removeTag(item);
}

public async onTagEdited(item: GuidName) {
    await this.renameTag(item); // <-- This line does not get hit in version 1.7.7, but it does get hit in version 1.6.2
}

GuidName class:

export class GuidName {
  Guid: string | undefined;
  Name: string | undefined;
  Selected: boolean;

  constructor(guid: string | undefined, name: string | undefined) {
    this.Guid = guid;
    this.Name = name;
    this.Selected = false;
  }
}

The onTagEdited() handler does not even get hit on version 1.7.7, but it does with 1.6.2.

Could it be because onTagEdited is async? It works in 1.6.2.

m-ghaoui avatar Apr 06 '18 07:04 m-ghaoui

I don't think being async is the problem (I tried this too). I introduced a feature to validate the tag when it gets edited: the behavior you see is exactly what happens when the validator detects an invalid tag, so for some reason the editing is not passing the validation.

I don't see problems in your code though and can't reproduce using a similar configuration to yours. Just to make sure, can you try v1.7.8? Also, it may seem silly, but the tag won't be added if the same one is already in the list, so make sure you're adding a new item

Gbuomprisco avatar Apr 06 '18 08:04 Gbuomprisco

It does no seem to work. The line does not get hit.

"ngx-chips": "1.7.8",

Incidentally, this version does not work either,

"ngx-chips": "1.8.0",

m-ghaoui avatar Apr 09 '18 13:04 m-ghaoui

Also, it may seem silly, but the tag won't be added if the same one is already in the list, so make sure you're adding a new item

I'm renaming it to a unique item. For example:

one two three ---> one, twooooooooooooooo, three. It jumps back to one, two, three

m-ghaoui avatar Apr 09 '18 13:04 m-ghaoui

Here is the line being hit with version 1.6.2

image

m-ghaoui avatar Apr 09 '18 13:04 m-ghaoui

Can you upload an online reproduction of the issue? I haven't been able to reproduce

Gbuomprisco avatar Apr 09 '18 13:04 Gbuomprisco

Ok. I'll try. You need to give me some time.

m-ghaoui avatar Apr 09 '18 14:04 m-ghaoui

Use stackblitz as in my demo, it's really quick :) you can fork the demo and start from there

Gbuomprisco avatar Apr 09 '18 14:04 Gbuomprisco

I think I'm having the same problem, I try to return the value to be put in the field but it does not work.

   <tag-input [onAdding]="transform"
            [validators]="validatorsTag"
            [errorMessages]="errorMessages"
            (onTagEdited)="onTagEdited($event)"
             (onSelect)="onSelect($event)"
             (onBlur)="onBlur()"
              [editable]="true"
              [identifyBy]="'hour'"
              [displayBy]="'hour'"
              formControlName="timesheet"
              theme="dark"
              placeholder="+ Horários"
              [secondaryPlaceholder]="'Adicione horários'"></tag-input>


onTagEdited(value): Observable<any> {
    const index = value.hour.indexOf(':');
    const reg = new RegExp('^[0-9]*$');
    console.log('tag', value)
    if (value.hour.length < 4 || !reg.test(value.hour)) {
      console.log(this.hourSelectedBeforeAlter)
      return Observable.of(this.hourSelectedBeforeAlter);
    }

    if (index === -1) {
      const val = value.hour.split('');
      const formated = {
        _id: (value._id) ? value._id : null,
        hour: val[0] + val[1] + ':' + val[2] + val[3]
      };
      return Observable.of(formated);
    } else {
      const val = value.split('');
      const formated = {
        _id: (value._id) ? value._id : null,
        hour: val[0] + val[1] + ':' + val[3] + val[4]
      };
      return Observable.of(formated);
    }
  }

Image and video hosting by TinyPic

You can observe that I select the item and change it, however according to my code it needs to return to the value that was previously in the code, I put consoles logs to make sure it would arrive correctly and it is, however at the moment of returning it does not work.

The behavior that I expect pe when put for example 22dd: 00 it returns to 22:00 because it is not a valid value.

renanmoraes avatar Apr 11 '18 19:04 renanmoraes

Some news on this case, but still with problems on this subject. Please ask for an opinion, I know it is not for you but it would be very interesting to do.

ThalesMatoso avatar Apr 27 '18 14:04 ThalesMatoso

@renanmoraes you're not going to be able to edit the tag using that hook. You will need onAdding

Gbuomprisco avatar Apr 29 '18 10:04 Gbuomprisco

I've been suffering a bug which I believe is this same one: when using identifiers (different from the display strings) and a tag is edited, it is always found to be a duplicate of itself and the edit is undone.

One solution would be to skip duplicate checking when editing tags, since allowDupes is defined to "tags with the same value" -- so tags with the same display string should always be allowed.

The right solution for me, however, is to just check for duplicate display strings -- since that's what I want to avoid duplicating.

jsalvata avatar Jun 01 '18 16:06 jsalvata

Just in case it helps anyone, I've worked around the issue by adding this to my component (apologies for the crudeness):

 ...
  @ViewChild('tagInput') private tagInput: TagInputComponent;
 ...
  ngOnInit() {
    (this.tagInput as any).findDupe= (function (this: any, tag: any): CustomerEmail | undefined {
      return this.items.find((item: any) => item.display === tag.display && item.value !== tag.value);
    }).bind(this.tagInput);
 ...

jsalvata avatar Jun 01 '18 17:06 jsalvata

Any updates?

gelevanog avatar Sep 04 '18 11:09 gelevanog

Any updates?

michgerts avatar Sep 25 '18 09:09 michgerts

Would also love any updates on this. I can get the event to fire partially, but it seems to fire before the edit is complete, so the visible text in the tag changes, but the updated value returned does not.

Example: Tag "Ewok" is edited. The text now reads "Blue Ewok." When I include onTagEdited, the text changes to "Blue Ewok" but all other data in the html, and the value returned are still "Ewok"

designcouch avatar Mar 13 '19 19:03 designcouch

any updates for this issue. I'm still having it on ngx-chips: 2.0.2

andn99 avatar Aug 15 '19 13:08 andn99

I would love to hear about updates or workarounds here.

michgerts avatar Sep 09 '19 09:09 michgerts

If you are using different values for [identifyBy] & [displayBy] ; once you edited the tag and enter the changes will be undone; using the same display and identify values will make it work!

anmolio avatar Feb 20 '20 12:02 anmolio

If you are using different values for [identifyBy] & [displayBy] ; once you edited the tag and enter the changes will be undone; using the same display and identify values will make it work!

I tried and it works. Many thank.

truongtokiet avatar Jun 10 '21 07:06 truongtokiet