ngx-tagify
                                
                                 ngx-tagify copied to clipboard
                                
                                    ngx-tagify copied to clipboard
                            
                            
                            
                        Angular library that wraps https://github.com/yaireo/tagify/
ngx-tagify
Proper Angular library that wraps @yaireo/tagify.
It allows multiple instances of tagify, implements ControlValueAccessor (for use with ngModel and reactive forms), and includes proper type declarations.
- Install
- Component
- Usage with ngModel
- Usage with Reactive Forms
- Predefined values
- Inputs
- Outputs
 
- Service
- Styling
- FAQ
Install
Install via npm:
npm install ngx-tagify
Import module:
import { TagifyModule } from 'ngx-tagify'; 
@NgModule({
  imports: [
    ...
    TagifyModule,
    ...
  ]
})
export class AppModule {}
Include styling (see below).
Component
You can use the <tagify> component either with ngModel or with reactive forms.
Either way, it takes a string or an array of TagData, i.e. an Object that contains a unique property value:
interface TagData {
  value: string;
  [key: string]: any;
}
If a string is passed, it gets parsed for tags by Tagify. The returned string is the stringified tags array or, if mode: 'mix', the mixed text and tags string.
Usage with ngModel
Import FormsModule to your module.
<tagify
  [(ngModel)]="tags"
  inputClass="form-control"
  [settings]="settings"
  [whitelist]="whitelist$"
  [readonly]="readonly"
  [disabled]="disabled"
  (add)="onAdd($event)"
  (remove)="onRemove($event)"
></tagify>
import { Component } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { TagData, TagifySettings } from 'ngx-tagify';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
    
  tags: TagData[] = [{ value: 'foo' }];
  // tags = 'foo'; -> if you want to pass as string
    
  settings: TagifySettings = {
    placeholder: 'Start typing...',
    blacklist: ['fucking', 'shit'],
    callbacks: {
      click: (e) => { console.log(e.detail); }
    }
  };
  
  whitelist$ = new BehaviorSubject<string[]>(['hello', 'world']);
  
  readonly = false;
  
  disabled = false;
  
  onAdd(tagify) {
    console.log('added a tag', tagify);  
  }
  
  onRemove(tags) {
    console.log('removed a tag', tags);
  }
  
}
Note: The component only recognizes reference changes, it won't deep check for changes within the array.
this.tags.push({value: 'bar'}); won't do anything.
Instead, use this.tags = this.tags.concat([{value: 'bar'}]); (or similar) to update changes.
Usage with Reactive Forms
Import ReactiveFormsModule to your module.
<form [formGroup]="form">
  <tagify formControlName="tags"></tagify>
</form>
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  
  form = new FormGroup({
    tags: new FormControl([{ value: 'Reactive' }])
  });
    
  ngOnInit(): void {
      
    this.form.valueChanges.subscribe(value => {
      console.log('form value changed', value);
    });
      
  }
  
}
Predefined values
Use ngModel or reactive forms with an initial string value that gets parsed by Tagify.
If you want to pass predefined tags as text, but receive a tags array as output, pass the value as text between <tagify></tagify>. Mixed text & tags are also supported.
<tagify>tag 1, tag 2</tagify>
<tagify [settings]="{ mode: 'mix' }">
  [[Eric Cartman]] and [[kyle]] do not know [[homer simpson]] because he's a relic.
</tagify>
Angular has problems with hard-coded single curly braces. Use property binding to add predefined tags with json syntax.
originalText = '[[{"id":200, "value":"cartman", "title":"Eric Cartman"}]] and [[kyle]] do not know [[{"value":"homer simpson", "readonly":true}]] because he\'s a relic.';
<tagify [settings]="{ mode: 'mix' }">
  {{ originalText }}
</tagify>
Inputs
| settings | Type: TagifySettingsSee tagify/Settings. | 
| inputClass | Type: stringApply one or more CSS classes to the input field (e.g. Bootstrap's form-control). | 
| whitelist | Type: Observable<string[]|TagData[]>Execution of the observable updates the whitelist of tagify. You can listen to user's inputs and update the whitelist respectively using this observable. | 
| readonly | Type: booleanDynamically change readonly status. | 
| disabled | Type: booleanDynamically change disabled status. | 
| name | Type: stringUse the name attribute if you want to access the tagify component via the service. This name should be unique. | 
Outputs
| add | Fires when a tag has been added. | 
| remove | Fires when a tag has been removed. | 
| tInput | Listen to the inputevent of the tagify input element. | 
Listen to all other events by defining respective callbacks (tagify/Events).
Service
You can also gain access to the full tagify API via a service.
Provide a name, such that the tagify instance will be available via the service.
<tagify name="example"></tagify>
<button (click)="addTags()">Add tags</button>
import { Component } from '@angular/core';
import { TagifyService } from 'ngx-tagify';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  
  constructor(
    private tagifyService: TagifyService
  ) {}
  
  addTags() {
    this.tagifyService.get('example').addTags(['this', 'is', 'cool']);
  }
  
}
The original Tagify class is also exposed and can be used for type declarations or custom implementations.
import { Tagify } from 'ngx-tagify';
const tagify: Tagify = new Tagify(inputElement);
Styling
You have two options to include the styling of Tagify.
Option 1: Modify your angular.json by adding the .scss file to the styles property.
"options": {
  "styles": [
    "node_modules/ngx-tagify/styles/tagify.scss",
    "src/styles.scss"
  ]
}
Option 2: If you want to override some of the styling, import it to a sass file. Have a look at tagify/CSS Variables and respective demo page for details.
// src/styles.scss
@import "ngx-tagify/styles/tagify";
.tagify
  --tags-border-color: #ff0000;
Usage with Bootstrap
If you are using Bootstrap as CSS framework (as used in the demo), you might need to tweak some styles in order that Tagify looks pretty:
.tagify
  --tag-pad: 0 0.5rem;  
  line-height: 1.5;
.tagify__input:empty::before
  line-height: inherit;
.tagify.form-control
  height: unset;
FAQ
I'm getting TS compilation error!
You are getting TypeScript compilation error with an error output like this:
 node_modules/@types/yaireo__tagify/index.d.ts:475:1
    475 export = Tagify;
        ~~~~~~~~~~~~~~~~
    This module is declared with using 'export =', and can only be used with a default import when using the 'allowSyntheticDefaultImports' flag.
To resolve this issue, set allowSyntheticDefaultImports within compilerOptions in your tsconfig.json:
{
  "compilerOptions": {
    
    "allowSyntheticDefaultImports": true,
    
  }
}