npm explorer

@yaireo/tagify

v4.36.0

lightweight, efficient Tags input component in Vanilla JS / React / Angular [super customizable, tiny size & top performance]

tagstaggingcomponenttagui
0/weekUpdated 3 weeks agoMITUnpacked: 4.7 MB
Published by Yair Even-Or
npm install @yaireo/tagify
RepositoryHomepagenpm






Tagify - tags input component


Transforms an input field or a textarea into a Tags component, in an easy, customizable way,
with great performance and small code footprint, exploded with features.


Vanilla ⚑ React ⚑ Vue ⚑ Angular


πŸ‘‰ See Many Examples πŸ‘ˆ



















Table of Contents


- Table of Contents
- Installation
- Option 1 - import from CDN:
- Option 2 - import as a Node module:
- Basic Usage Examples
- Debugging
- Features
- Building the project
- Output files:
- Adding tags dynamically
- Output value
- Modify original input value format
- Ajax whitelist
- Persisted data
- Edit tags
- Validations
- Drag \& Sort
- Integration example:
- DOM Templates
- Example of overriding the tag template:
- Suggestions list
- Example for a suggestion item alias
- Example whitelist:
- Mixed-Content
- Single-Value
- React
- Update regarding onChange prop:
- Updating the component's state
- Vue
- jQuery version
- jQuery.tagify.js
- HTML input \& textarea attributes
- Caveats
- FAQ
- CSS Variables
- Suggestions Dropdown CSS variables
- Full list of Tagify's SCSS variables
- Methods
- Events
- Hooks
- Settings

Installation

$3

Place these lines before any other code which is (or will be) using Tagify (Example here)
``html



`

Tagify will then be available globally.
To load specific version use
@ - for example: unpkg.com/@yaireo/tagify@3.1.0

$3


`sh
npm i @yaireo/tagify --save
`

Basic Usage Examples

- Many demos with code examples can be seen here
- CodeSandbox live demo

`js
import Tagify from '@yaireo/tagify'

var inputElem = document.querySelector('input') // the 'input' element which will be transformed into a Tagify component
var tagify = new Tagify(inputElem, {
// A list of possible tags. This setting is optional if you want to allow
// any possible tag to be added without suggesting any to the user.
whitelist: ['foo', 'bar', 'and baz', 0, 1, 2]
})
`

The above example shows the most basic whitelist array setting possible, with a mix
of Strings and Numbers but the array also support Objects which has a must-have property of
value:

`js
whitelist: [{value: 'foo', id: '123', email: 'foo@whatever.com'}, ...]
`

The value property is what will be used when actually defining the value property of the original input element (inputElem in the example above) which was transformed
into a Tagify component, and so when the form data is sent to the server, it will contain all the values (which are the selected tags in the component).

For selected tags to show a different text than what is defined in value for a whitelist item, see the tagTextProp setting

⚠️ Important:
Don't forget to include
tagify.css file in your project.
CSS location:
@yaireo/tagify/dist/tagify.css
SCSS location:
@yaireo/tagify/src/tagify.scss
See SCSS usecase & example

$3


There are several places in the source code which emits
console.warn logs to help identify issues.
Those will only work if
Tagify.logger.enabled flag is set to true.
To disable the default logging, set the following global variable:


`js
window.TAGIFY_DEBUG = false

var tagify = new Tagify(...)
`


Features


* Can be applied to input & textarea elements
* Supports mix content (text and tags together)
* Supports single-value mode (like

`


Validations


For "regular" tags (not mix-mode or select-mode) the easiest way is to use the
pattern setting and use a Regex, or
apply the
pattern attribute directly on the input which will be "transformed" into a Tagify component (for vanilla code where the input tag is fully accessible to developers).

If the pattern setting does not meet your needs, use the validate setting, which receives a tag data object as an argument and should return true if validation is passing, or false/string of not.
A string may be returned as the reason of the validation failure so it would be printed as the
title attribute of the invalid tag.

Here's an example for async validation for an added tag. The idea is to listen to "add" event,
and when it fires, first set the tag to "loading" state, run an async call, and then set the loading state (of the tag) back to
false.
If the custom async validation failed, call the
replaceTag Tagify method and set the __isValid tag data property to the error string which will
be shown when hovering the tag.


Note - there is a setting to keep invalid tags (
keepInvalidTags) and if it's set to true, the user can see the reason for the invalidation by
hovering the tag and see the browser's native tooltip via the
title attribute:

`js
{
empty : "empty",
exceed : "number of tags exceeded",
pattern : "pattern mismatch",
duplicate : "already exists",
notAllowed : "not allowed"
}
`

The texts for those (invalid tags) titles can be customized from the settings:

`js
new Tagify(inputElement, {
texts: {
duplicate: "Duplicates are not allowed"
}
})
`

Or by directly manipulating the Tagify function prototype:

`js
Tagify.prototype.TEXTS = {...Tagify.prototype.TEXTS, {duplicate: "Duplicates are not allowed"}}
`

Drag & Sort

To be able to sort tags by dragging, a 3rd-party script is needed.

I have made a very simple drag & drop (~11kb unminified) script which uses HTML5 native API and
it is available to download via NPM or Github
but any other drag & drop script may work. I could not find on the whole internet a decent lightweight script.

$3

`js
var tagify = new Tagify(inputElement)

// bind "DragSort" to Tagify's main element and tell
// it that all the items with the below "selector" are "draggable"
var dragsort = new DragSort(tagify.DOM.scope, {
selector: '.'+tagify.settings.classNames.tag,
callbacks: {
dragEnd: onDragEnd
}
})

// must update Tagify's value according to the re-ordered nodes in the DOM
function onDragEnd(elm){
tagify.updateValueByDOMTags()
}
`


DOM Templates


It's possible to control the templates for some of the HTML elements Tagify is using by
modifying the
settings.templates Object with your own custom functions which must return an HTML string.

Available templates are: wrapper, input, tag, dropdown, dropdownItem, dropdownContent, dropdownHeader, dropdownFooter and the optional dropdownItemNoMatch
which is a special template for rendering a suggestion item (in the dropdown list) only if there were no matches found for the typed input, for example:

`js
// ...more tagify settings...
templates: {
dropdownItemNoMatch: data =>


No suggestion found for: ${data.value}

}
`

View templates

$3

Each template function is automatically bound with this pointing to the current Tagify instance.
It is imperative to preserve the class names and also the
this.getAttributes(tagData) for proper functionality.

`js
new Tagify(inputElem, {
templates: {
tag(tagData, tagify){
return
contenteditable='false'
spellcheck='false'
tabIndex="${this.settings.a11y.focusableTags ? 0 : -1}"
class="${this.settings.classNames.tag} ${tagData.class ? tagData.class : ""}"
${this.getAttributes(tagData)}>


${tagData[this.settings.tagTextProp] || tagData.value}

,

dropdownFooter(suggestions){
var hasMore = suggestions.length - this.settings.dropdown.maxItems;

return hasMore > 0
?


${hasMore} more items. Refine your search.

: '';
}
}
})
`

Suggestions list


suggestions list dropdown

The suggestions list is a whitelist Array of Strings or Objects which was set in the settings Object when the Tagify instance was created, and can be set later directly on the instance: tagifyInstance.whitelist = ["tag1", "tag2", ...].

The suggestions dropdown will be appended to the document's element and will be rendered by default in a position below (bottom of) the Tagify element.
Using the keyboard arrows up/down will highlight an option from the list, and hitting the Enter key to select.

It is possible to tweak the list dropdown via 2 settings:

- enabled - this is a numeral value that tells Tagify when to show the suggestions dropdown, when a minimum of N characters were typed.
-
maxItems - Limits the number of items the suggestions list will render

`javascript
var input = document.querySelector('input'),
tagify = new Tagify(input, {
whitelist : ['aaa', 'aaab', 'aaabb', 'aaabc', 'aaabd', 'aaabe', 'aaac', 'aaacc'],
dropdown : {
classname : "color-blue",
enabled : 0, // show the dropdown immediately on focus
maxItems : 5,
position : "text", // place the dropdown near the typed text
closeOnSelect : false, // keep the dropdown open after selecting a suggestion
highlightFirst: true
}
});
`

Will render

`html



aaab

aaabb

aaabc

aaabd

aaabe



`

By default searching the suggestions is using fuzzy-search (see settings).

If you wish to assign alias to items (in your suggestion list), add the searchBy property to whitelist items you wish
to have an alias for.

In the below example, typing a part of a string which is included in the searchBy property, for example land midd" -
the suggested item which matches the value "Israel" will be rendered in the suggestions (dropdown) list.

$3

`javascript
whitelist = [
...
{ value:'Israel', code:'IL', searchBy:'holy land, desert, middle east' },
...
]
`

Another handy setting is dropdown.searchKeys which, like the above dropdown.searchBy setting, allows
expanding the search of any typed terms to more than the
value property of the whitelist items (if items are a Collection).

$3

`javascript
[
{
value : 123456,
nickname : "foo",
email : "foo@mail.com"
},
{
value : 987654,
nickname : "bar",
email : "bar@mail.com"
},
...more..
]
`

Modified searchKeys setting to also search in other keys:
`javascript
{
dropdown: {
searchKeys: ["nickname", "email"] // fuzzy-search matching for those whitelist items' properties
}
}
`

Mixed-Content

See demo here

This feature must be toggled using these settings:

`js
{
// mixTagsInterpolator: ["{{", "}}"], // optional: interpolation before & after string
mode: 'mix', // <-- Enable mixed-content
pattern: /@|#/ // <-- Text starting with @ or # (if single, String can be used here instead of Regex)
}
`

When mixing text with tags, the original textarea (or input) element will have a value as follows:

[[cartman]]⁠ and [[kyle]]⁠ do not know [[Homer simpson]]⁠

If the initial value of the textarea or input is formatted as the above example, Tagify will try to
automatically convert everything between
[[ & ]] to a tag, if tag exists in the whitelist, so make
sure when the Tagify instance is initialized, that it has tags with the correct
value property that match
the same values that appear between
[[ & ]].

Applying the setting dropdown.position:"text" is encouraged for mixed-content tags, because the suggestions list
looks weird when there is already a lot of content on multiple lines.

If a tag does not exist in the whitelist, it may be created by the user and all you should do is listen to the add event and update your local/remote state.

Single-Value

Similar to native 's element name attribute
value | String/Array | βœ” | Initial value.
defaultValue | String/Array | | Same as
value prop
placeholder | String | βœ” | placeholder text for the component
readOnly | Boolean | βœ” | Toggles
readonly state. With capital O.
tagifyRef | Object | |
useRef hook refference for the component inner instance of vanilla Tagify (for methods access)
showDropdown | Boolean/String | βœ” | if
true shows the suggestions dropdown. if assigned a String, show the dropdown pre-filtered.
loading | Boolean | βœ” | Toggles
loading state for the whole component
whitelist | Array | βœ” | Sets the
whitelist which is the basis for the suggestions dropdown & autocomplete
className | String | | Component's optional class name to be added
InputMode | String | |
"textarea" will create a