Tiny Text Field Based Tags Input Plugin - Tagify

File Size: 831 KB
Views Total: 88580
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   
Tiny Text Field Based Tags Input Plugin - Tagify

Tagify is a powerful and full-featued tags input JavaScript library designed to create animated, editable, sortable, high-performance tags/tokens input on your modern web apps.

Please note that this library has deprecated jQuery support starting from v4.23.0, so you can now implement Tagify using Vanilla JavaScript.

Highlighted Features:

  • Auto prevents duplicate tags.
  • Auto split input text into tags by comma or Enter key.
  • Auto suggestion list.
  • Auto expands input while typing.
  • Allows to edit tags on double-click.
  • Allows to resort tags with drag'n'drop.
  • Allows to set blacklist.
  • Works with text fields like input, textarea, etc.
  • Compatible with the latest Bootstrap framework.
  • Works with React, Angular, Vue.js, and Vanilla JS.
  • And more...

Install & download with NPM:

# NPM
$ npm i @yaireo/tagify

How to use it:

1. Import the Tagify into your web project:

<!-- Core Stylesheet -->
<link href="/dist/tagify.css" rel="stylesheet" type="text/css" />

<!-- Core JavaScript -->
<script src="/dist/tagify.min.js"></script>

<!-- Polyfills for IE -->
<script src="/dist/tagify.polyfills.min.js"></script>
// OR import it as a module
import Tagify from '@yaireo/tagify'

2. Create an input or textarea element for the tags input.

<input name="input-example" value="jQuery, Script" autofocus>

<textarea name="textarea-example" placeholder="Websites">
  [{"value":"jQuery"}, {"value":"Script"}]
</textarea>

3. Initialize the Tagify and done.

var input = document.querySelector('input[name=input-example]');
new Tagify(input, {
    // options here
});

var textarea = document.querySelector('textarea[name=textarea-example]'),
    tagify = new Tagify(textarea, {
    // options here
});

4. Available configuration options to customize the tags input.

tagify(input, {

  // [regex] split tags by any of these delimiters ("null" to cancel)
  delimiters: ",", 

  // regex pattern to validate input by. 
  pattern: null, 

  // tag data Object property which will be displayed as the tag's text
  tagTextProp: 'value',

  // placeholder text
  placeholder: '',

  // maximum number of tags
  maxTags: Infinity, 

  // use 'select' for single-value dropdown-like select box
  // use 'mix' as value to allow mixed-content
  // use 'integrated' to skip the creation of the wrapper
  // the 'pattern' setting must be set to some character.
  mode: null,

  // interpolation for mix mode
  // everything between these will become a tag
  mixTagsInterpolator: ['[[', ']]'],

  // define conditions in which typed mix-tags content is allowing a tag to be created after.
  mixTagsAllowedAfter: /,|\.|\:|\s/,

  // allow tuplicate tags
  duplicates: false, 

  // trim the tag's value
  trim: true,

  // should ONLY use tags allowed in whitelist
  enforceWhitelist: false, 

  // disable manually typing/pasting/editing tags
  userInput: true,

  // allow the component as a whole to recieve focus. 
  focusable: false,

  // tries to autocomplete the input's value while typing
  autoComplete: {
    enabled: true,
    rightKey: false, // If true, when → is pressed, use the suggested value to create a tag, else just 
    auto-completes the input. In mixed-mode this is ignored and treated as "true"
    tabKey: false, // If true, pressing tab key would only auto-complete (if a suggesiton is highlighted) but will not convert to a tag (like rightKey does) also, unless clicked again (considering the addTagOn setting).
  },

  // is this list has any items, then only allow tags from this list
  whitelist: [], 

  // a list of non-allowed tags
  blacklist: [], 

  // automatically adds the text which was inputed as a tag when blur event happens
  addTagOnBlur: true, 

  // if the tagify field (in a normal mode) has any non-tag input in it, convert it to a tag on any of these events: blur away from the field, click "tab"/"enter" key
  addTagOn: ['blur', 'tab', 'enter'],

  // by default, the native way of inputs' onChange events is kept, and it only fires when the field is blured.
  onChangeAfterBlur: true,

  // automatically converts pasted text into tags
  pasteAsTags: true,

  // exposed callbacks object to be triggered on events: 'add' / 'remove' tags
  callbacks: {}, 

  // false or null will disallow editing
  editTags: {{
    clicks: 2, // Number of clicks to enter "edit-mode": 1 for single click. Any other value is considered as double-click
    keepInvalid: true, // keeps invalid edits as-is until esc is pressed while in focus
  }},

  // object consisting of functions which return template strings
  templates: {wrapper, tag, dropdownItem},

  // if the pattern setting does not meet your needs, use this function, which recieves tag data object as an argument and should return true if validaiton passed or false/string of not
  // a string may be returned as the reason of the validation failure.
  validate: function(){},

  // take a tag input as argument and returns a transformed value
  transformTag: function(){},

  // if true, do not remove tags which did not pass validation
  keepInvalidTags: false,

  // skip invald tags
  skipInvalid: false,

  // if false, do not create invalid tags from invalid user input
  createInvalidTags: true,

  // true - remove last tag; edit - edit last tag
  backspace: true,

  // if you wish your original input/textarea value property format to other than the default (which I recommend keeping) you may use this and make sure it returns a string.
  originalInputValueFormat: function(){},

  // node or string to add after a tag added
  mixMode: {
    insertAfterTag: '\u00A0',
  },

  // allows tags to get focus, and also to be deleted via Backspace
  a11y: {
    focusableTags: false,
  }

  // default classnames
  classNames: {
    namespace            : 'tagify',
    mixMode              : 'tagify--mix',
    selectMode           : 'tagify--select',
    input                : 'tagify__input',
    focus                : 'tagify--focus',
    tagNoAnimation       : 'tagify--noAnim',
    tagInvalid           : 'tagify--invalid',
    tagNotAllowed        : 'tagify--notAllowed',
    scopeLoading         : 'tagify--loading',
    hasMaxTags           : 'tagify--hasMaxTags',
    hasNoTags            : 'tagify--noTags',
    empty                : 'tagify--empty',
    inputInvalid         : 'tagify__input--invalid',
    dropdown             : 'tagify__dropdown',
    dropdownWrapper      : 'tagify__dropdown__wrapper',
    dropdownHeader       : 'tagify__dropdown__header',
    dropdownFooter       : 'tagify__dropdown__footer',
    dropdownItem         : 'tagify__dropdown__item',
    dropdownItemActive   : 'tagify__dropdown__item--active',
    dropdownItemHidden   : 'tagify__dropdown__item--hidden',
    dropdownItemSelected : 'tagify__dropdown__item--selected',
    dropdownInital       : 'tagify__dropdown--initial',
    tag                  : 'tagify__tag',
    tagText              : 'tagify__tag-text',
    tagX                 : 'tagify__tag__removeBtn',
    tagLoading           : 'tagify__tag--loading',
    tagEditing           : 'tagify__tag--editable',
    tagFlash             : 'tagify__tag--flash',
    tagHide              : 'tagify__tag--hide',
  },

  dropdown: {
    classname: '',
    enabled: 2,      // minimum input characters to be typed for the suggestions dropdown to show
    maxItems: 10,
    searchKeys: ["value", "searchBy"],
    fuzzySearch: true,
    caseSensitive: false,
    accentedSearch: true,
    sortby: 'startsWith',  // If set as startsWith string, the suggestions list will be sorted with matched items which starts with the query shown first, and exact matches shown before all. If this setting is defined as a function, it recieves two arguments: the array of filtered items and the query and it must return an Array.
    includeSelectedTags: false,
    escapeHTML: true,
    highlightFirst: false,  // highlights first-matched item in the list
    closeOnSelect: true,   // closes the dropdown after selecting an item, if `enabled:0` (which means always show dropdown)
    clearOnSelect: true,   // after selecting a suggetion, should the typed text input remain or be cleared
    position: 'all',  // 'manual' / 'text' / 'all' / 'input'
    mapValueTo: // If whitelist is an Array of Objects: Ex. [{value:'foo', email:'[email protected]'},...]) this setting controlls which data key will be printed in the dropdown. Ex.1: mapValueTo: data => "To:" + data.email Ex.2: mapValueTo: "email"
    appendTarget: null,   // defaults to document.body one DOM has been loaded
    placeAbove: null, // If defined, will force the placement of the dropdown in respect to the Boolean value: true will always show the suggestions dropdown above the input field and false will always show it below. By default this setting it not defined and the placement of the dropdown is automatically decided according to the space availble, where opening it below the input is preferred.
  },

  hooks:{
    beforeRemoveTag: () => Promise.resolve(),
    beforePaste: () => Promise.resolve(),
    suggestionClick: () => Promise.resolve()
    beforeKeyDown: () => Promise.resolve()
  },

});

8. API methods.

var myInput = new Tagify(input);

// adds new tag
// String (word, single or multiple with a delimiter), an Array of Objects, or Strings
// e.g. addTags(["banana", "orange", "apple"])
// or addTags([{value:"banana", color:"yellow"}, {value:"apple", color:"red"}, {value:"watermelon", color:"green"}])
// clearInputAfterAdding: true or false
// skipAddingInvalids: true or false
myInput.addTags(tags, clearInputAfterAdding, skipAddingInvalids);

// Bypasses the normalization process in addTags, forcefully adding tags at the last caret location or at the end, if there's no last caret location saved
// tags: Array/String
myInput.addMixTags(tags);

// create an empty tag (optionally with pre-defined data) and enters "edit" mode directly
// tagData: Object
myInput.addEmptyTag(tagData);

// removes a specific tag
// Array/HTMLElement/String tag(s) to remove
// silent: does not update the component's value
// tranDuration: transition duration in ms
myInput.removeTags(tags, silent, tranDuration);

// removes all tags
myInput.removeAllTags();

// destroy the plugin
myInput.destroy();

// converts the input's value into tags. This method gets called automatically when instansiating Tagify. Also works for mixed-tags
myInput.loadOriginalValues(String/Array);

// returns an Array of found matching items (case-insensitive)
myInput.getWhitelistItemsByValue(Object);

// returns the index of a specific tag, by value
myInput.getTagIndexByValue();

// returns the first matched tag node, if found
myInput.getTagElmByValue();

// returns how many tags already exists with that value
myInput.isTagDuplicate();

// converts a String argument ([[foo]] and [[bar]] are..) into HTML with mixed tags & texts
myInput.parseMixTags();

// returns a DOM nodes list of all the tags
myInput.getTagElms();    

// returns a specific tag DOM node by value
myInput.getTagElmByValue();

// set/get tag data on a tag element
myInput.getSetTagData(HTMLElement, Object);

// goes to edit-mode in a specific tag
myInput.editTag(HTMLElement); 

// get the node which has the actual tag's content
myInput.getTagTextNode(HTMLElement); 

// set the text of a tag (DOM only, does not affect actual data)
myInput.setTagTextNode(HTMLElement); 

// exit a tag's edit-mode. if "tagData" exists, replace the tag element with new data and update Tagify value
myInput.replaceTag(tagElm, Object (tagData));

// toogle loading state on/off (Ex. AJAX whitelist pulling)
myInput.loading();

// same as above but for a specific tag element
myInput.tagLoading(HTMLElement, Boolean);

// returns a tag element from the supplied tag data
myInput.createTagElem(Object (tagData));

// injects text or HTML node at last caret position. range parameter is optional
myInput.injectAtCaret(HTMLElement (injectedNode), Object (range)); 

// places the caret after a given node
myInput.placeCaretAfterNode(HTMLElement);

// places the caret at the start or the end of a node
myInput.setRangeAtStartEnd(Boolean, HTMLElement);

// whatever to insert after
myInput.insertAfterTag(HTMLElement (tag element), HTMLElement/String);

// toggles class on the main tagify container
myInput.toggleClass(true/false);

// adds all whitelist items as tags and close the suggestion dropdown
myInput.dropdown.selectAll();

// shows the sugegstions list dropdown
// the string paramater allows filtering the results
myInput.dropdown.show(string);

// hides the suggestions list dropdown
myInput.dropdown.hide(true/false);

// Toggles dropdown show/hide
myInput.dropdown.toggle(true/false);

// iterates tag DOM nodes and re-build the tagify.value array (call this if tags get sorted manually)
myInput.updateValueByDOMTags(); 

// converts a template string (by selecting one from the settings.templates by name or supplying a template function which returns a String) into a DOM node
myInput.parseTemplate(String/Function (template name or function), Array (data));

// set readonly mode
myInput.setReadonly(true/false);

// set disabled mode
myInput.setDisabled(true/false);

// get data for the specific instance by parameter
myInput.getPersistedData(string);

// set data for the specific instance. Must supply a second parameter which will be the key to save the data in the localstorage (under the tagify namespace)
myInput.setPersistedData(*, String);

// clear data for the specific instance, by parameter. If the parameter is ommited, clears all persisted data related to this instance (by its id which was set in the instance's settings)
myInput.clearPersistedData(string);

// Sets the placeholder's value
myInput.setPlaceholder(string);

9. Events.

var myInput = new Tagify(input);

// e.type, e.detail, ...
myInput
.on('add', function(e){
  // on add
})

.on('remove', function(e){
  // on remove
})

.on('change', function(e){
  // on change
})

.on('invalid', function(e){
  // on invalid
})

.on('input', function(e){
  // on input
})

.on('paste', function(e){
  // on click
})

.on('click', function(e){
  // on click
})

.on('dblclick', function(e){
  // on dblclick
})

.on('keydown', function(e){
  // on keydown
})

.on('focus', function(e){
  // on focus
})

.on('blur', function(e){
  // on blur
})

.on('edit:input', function(e){
  // on input
})

.on('edit:beforeUpdate', function(e){
  // before update
})

.on('edit:updated', function(e){
  // on updated
})

.on('edit:start', function(e){
  // on start
})

.on('edit:keydown', function(e){
  // on keydown
})

.on('dropdown:show', function(e){
  // on show
})

.on('dropdown:hide', function(e){
  // on hide
})

.on('dropdown:select', function(e){
  // on select
})

.on('dropdown:scroll', function(e){
  // tells the percentage scrolled. (event.detail.percentage)
})

.on('dropdown:noMatch', function(e){
  // when no whitelist suggestion item matched for the the typed input
})

.on('dropdown:updated', function(e){
  // when the dropdown list is re-filtered while suggestions list is visible and a tag was removed so it was re-added as a suggestion
})

Changelog:

v4.32.2 (2024-12-08)

  • Enhance keyboard navigation for suggestions dropdown by adding support for PageUp, PageDown, Home, and End keys. This allows users to navigate through suggestions more efficiently without using the mouse.
  • bugfix: in select-mode, the x (remove tag) button should not be visible if the suggestions' dropdown is visible (open)
  • ran npx update-browserslist-db@latest 0ea0f30
  • bugfix: Dropdowns does not close when interacting with tags of other instances
  • added an FAQ item
  • this.state.dropdown.suggestions should point to the sorted list and not pre-sorted one
  • call the custom sortby (if defined) also when there's no search query
  • Fix scroll behavior

v4.32.1 (2024-11-23)

  • in normal mode, if there is a single tag and while the dropdown is open the tag's x button is clicked, then the component should be re-focused
  • removed e.preventDefault for tab keydown event

v4.32.0 (2024-11-12)

  • bugfixes

v4.31.6 (2024-10-29)

  • bugfixes
  • should tab-autocomplete a tag from the whitelist and with all its data, instead of only the suggetion's text, which is incorrect in case of a whitelist collection

v4.31.4/5 (2024-10-25)

  • bugfixes

v4.31.3 (2024-08-31)

  • bugfixes

v4.31.2 (2024-08-29)

  • add event should fire ASAP without any delay. Also should include invalid added tags

v4.31.1 (2024-08-26)

  • Bugfixed

v4.31.0 (2024-08-24)

  • Updated

v4.27.0 (2024-06-23)

  • added a div wrapper to prevent bug
  • bugfix - clicking the × (clear selected tag) button in select-mode, the component should not get focused
  • added tagify-dd-text-color to Knobs in the examples html page
  • minor refactor
  • added class name this.settings.classNames.dropdownItemSelected (tagify__dropdown__item--selected) for selected dropdown items
  • added new CSS variable --tagify-dd-text-color
  • added CSS for suggestion items which are currently already selected (as tags)

v4.26.6 (2024-06-12)

  • chore: added a updatePlaceholderByTagsCount funciton to the advance-options demo to showcase the tagify.setPlaceholder method
  • chore: added 2 methods to the table of available tagify methods in the README: setRangeAtStartEnd & setPlaceholder
  • bugfixes

v4.26.5 (2024-05-14)

  • bugfixes
  • small CSS change regarding tags' appeared line-height

v4.26.4 (2024-05-11)

  • bugfixes

v4.26.3 (2024-05-09)

  • clicking anywhere within an instance's dropdown should not hide it
  • add a custom property to the dropdown node so it be linked to which tagify instance it belongs to
  • bugfixes

v4.26.2 (2024-05-07)

  • should discard tags added as objects with an empty text-prop value
  • refactored the "bindOriginaInputListener" interval so it will be restarted every time Tagify gets updated so the comparison of the original value will only happen after Tagify was updated for certain
  • When the trim setting is true, tags added as objects should be trimmed as well
  • normalizeTags() method should eliminate empty array items
  • bugfixes

v4.26.1 (2024-05-02)

  • Bugfixes

v4.26.0 (2024-04-29)

  • Bugfixes

v4.25.1 (2024-04-25)

  • Refactored wrapper HTML template by extracting the input into its own template function

v4.25.0 (2024-04-25)

  • Refactored wrapper HTML template by extracting the input into its own template function
  • Added keyboard ENTER support for deleting selected tag using TAB navigation when in select-mode
  • Fixed bugs

2024-04-15

  • Updated doc
  • Updated demos

v4.23.0 (2024-04-09)

  • Minor CSS change to tag's max width
  • Added a new setting - focusable
  • Simplified the condition because dropdown.enabled is changed to 0 automatically if userInput is set to false by the applySettings method
  • cursor: text CSS property should only be applied if Tagify has an editable node within
  • Added a this.removeAllCustomListeners as a cleanup stage inside the destroy method
  • Added ability to remove all the events listeners for a specific type of an event, without specifying the callbacks as they are saves internally - Added ability to remove all the events assigned on the instance
  • Bugfixes

v4.22.2 (2024-03-19)

  • bugfixes

v4.22.0 (2024-03-17)

  • minor code adjustment for select mode
  • changed the focus and blur events for the input element to global focusin & focusout events because they can be propagated, and more flexible to work with because it doesn't resrict working only with the input element
  • dropdown.show() method should do nothing if this.state.dropdown.visible is true
  • select mode should not auto-complete when pressing the TAB button because the autocomplete method cannot currently work for select mode since it only works for the input element which is hidden in select mode 10078f1
  • added new helper method isWithinNodeTag to test if a certain node is nested inside a tag element
  • fixed bugs

v4.21.2 (2024-03-08)

  • bugfixes

v4.21.1 (2024-02-13)

  • dropdownItemNoMatch content should not have empty spaces as it will show up in the HTML when injected.
  • refactored logic for post-processing a tag node which was just added to the DOM.

v4.21.0 (2024-02-13)

  • prepareNewTagNode method should return the modified tagData which includes the __isValid property
  • [refactor] moved suggestions-related methods outside of dropdown.js into a new file: suggestions.js for seperation between the dropdown which is just a container and the actual suggestions and their logic code
  • fixed banner issues
  • added a README section for the bundle's output files
  • refactored similar user-input-to-tag preparation logic into a new method prepareNewTagNode which is called by addTags, addMixedTags & prefixedTextToTag
  • decided it's better to have the dropdown.highlightFirst setting set to true by default
  • selectOption dropdown method should not return on mix-mode when this.DOM.input.parentNode does not exists
  • [Chore] Added javascript sourcemaps support which required replacing rollup-plugin-banner with rollup-plugin-banner2 which does supports sourcemaps. Also fixed the banner comment which seems to have not been correct for a long time

v4.20.0 (2024-02-11)

  • Fixed numbers-only whilelist not showing with userInput:false setting
  • Added paste event listener
  • The global onClickAnywhere event should be of type capture to guarantee it will fire before any other event so not to mess state.hasFocus)
  • Fixes - Tagify within a label element can't get focused as the focus it shifted to the hidden original field
  • select-mode can only have one tag, so replaced block margin (up/down) with padding so the tag will occuy the whole space of the container and have a larger clicking area 
  • Prevented dblclick event from being listened to in select mode, since there is no need for it.
  • In `select mode, clicking on the icon which toggles the dropdown should toggle it when it is already open. refactored that part. 
  • Remove console.log call

v4.19.1 (2024-01-30)

  • bugfixes

v4.19.0 (2024-01-28)

  • improved the users list demo in the main demos page
  • moved last commented change this.state.hasFocus to a better location in the code
  • improved README with a better "basic example" section
  • re-made how "select" mode works so instead of the input being editable, the actual tag is now visible and goes into edit-mode and the input is hidden
  • removed a console.log
  • when calling addEmptyTag method, the Tagify field should be focused
  • in case the suggestions DropDown is placed inside the tagify.DOM.scope node, it should not inherit its line-height style
  • dropdown.appendTarget setting can now be a function as well, which should return a DOM node
  • fix - calling addEmptyTag() with dropdown.enabled: 0 setting should create an empty tag with a dropdown of suggestions 

v4.18.3 (2024-01-18)

  • Bugfixed
  • Don't hide dropdown during whitelist fetch
  • re-expose placeCaretAfterNode which was left out after past refactoing. devs should have access to this method
  • Stop logging input keystrokes

v4.18.2 (2024-01-12)

  • Bugfixed

v4.18.1 (2024-01-08)

  • Bugfixed

v4.18.0 (2024-01-05)

  • Added escapeHTML dropdown setting which optionally allows HTML to be rendered inside the value of each suggestion item
  • The positioning code now takes into considerations the RTL dropdown setting which rendered the suggestions dropdown as if it sticks to the right side of the Tagify.
  • Added conditional class name tagify__dropdown--RTL to the dropdown wrapper
  • added cx helper function for working with complex class names
  • Added --tagify-dd-item-pad global CSS description
  • Replaced margins at several places with logical margins, for RTL support
  • Added --tagify-dd-max-height as global variable for an easier control over it - Added RTL support for the suggestions dropdown, but it only makes sense if the max-width of the dropdown is set to none or any other value greater than the Tagify width
  • Re-instated minification for the jQuery-wrapper output file
  • Random minor CSS refactor

v4.17.9 (2023-08-20)

  • lots of bugs fixed

v4.17.8 (2023-04-13)

  • lots of bugs fixed

v4.17.7 (2023-01-17)

  • lots of bugs fixed

v4.17.5 (2022-12-04)

  • changes React file from js to jsx
  • mix-mode is better initialized by default with dropdown.position as text
  • bugfixes

v4.17.4 (2022-11-20)

  • Bugfix

v4.17.3 (2022-11-18)

  • Bugfix

v4.17.2 (2022-11-16)

  • Bugfix

v4.17.1 (2022-11-16)

  • removed exports from package.json as it seemed to have caused problems with importing the package due to misconfiguration. Will work on that more. 
  • moved tagData from the prototype to the "helpers" file, and renamed it getSetTagData

v4.17.0 (2022-11-13)

  • Bugfixed

v4.16.4 (2022-09-04)

  • Bugfixed

v4.16.3 (2022-09-01)

  • Bugfixed

v4.16.2 (2022-08-20)

  • Bugfixed

v4.16.0 (2022-08-15)

  • Bugfixed

v4.15.4 (2022-08-14)

  • Bugfixed
  • Renamed originalEvent to event in multiple events - removed cloneEvent in EventDispatcher.js since it was already defined apparently in tagify.js

v4.15.3 (2022-08-06)

  • Fixed bugs

v4.15.2 (2022-07-31)

  • Fixed bugs

v4.15.1 (2022-07-31)

  • Fixed bugs

v4.15.0 (2022-07-30)

  • added support for sending the original event to the "trigger" events method
  • added support for transitioning-out the selected suggestion item
  • when removing all tags, the dropdown should re-filter, because that action might have been triggered from inside the dropdown, and it might still be open
  • added dropdown variables to knobs in the examples page
  • refactored users-list CSS example to use --tagify-dd-item-pad variable instead of hard-coded property setter
  • minor improvements to the horizontal tags hidden transition
  • attach a custom property __tagify`` reference to the Tagify instance on the original input and is now returning that instance if the same original input is re-tagified (for some reason)
  • chore - added README info for some new CSS variables + ones which were not mentioned before regarding the suggestions dropdown
  • fixes - underlying Tagify shoud not get focused when selecting a suggestion from a Tagify sugegstion dropdown which is rendered over it.
  • fixes - do not create tags from invalid input. Added the new createInvalidTags setting
  • fixes - add an easy was to set tags border-radius using CSS variables

v4.14.1 (2022-07-26)

  • Fixed bugs

v4.14.0 (2022-07-21)

  • improved the explenation for the Tags with properties section in the examples page
  • fixed bugs

v4.13.3 (2022-07-14)

  • Bugfixes

v4.13.2 (2022-07-12)

  • Fixed wrong duplicate tag with capital letter

v4.13.1 (2022-07-10)

  • added the this instance scope as the second parameter to the tag template react

v4.13.0 (2022-07-10)

  • Filter only the dropdown-item elements (not header/footer/custom ones) when moving with up/down arrows
  • Refactored and fixed the escape scenario when editing tags, so the original tag is now being replaced back correctly
  • Changed "__originalHTML" to point to a cloned element instead of innerHTML, so when pressing escape, it will be replaced back to that, as-is
  • Fixes - Selected tag disappears after the input loses focus when in select mode. 
  • Update templates.js 
  • Update tagify.test.js
  • Improved users-list demo
  • Added function comment
  • Added some new methods
  • Refactored editTag method and added 3 new methods: editTagChangeDetected, getTagTextNode & setTagTextNode
  • Fixes - add missing css color variable to the suggested text
  • Mentioned more templates recently added 
  • Fixes - Tag doesn't get added on selecting value from custom template dropdownItemNoMatch
  • Fixed typo
  • Fixed some typos and added async validation example
  • Fixes - clicking an uneditable tag when the editTags settings is set to clicks: 1 gives focus to the Tagify field which cannot be unfocused by clicking outside
  • Removed data-editable attribute for tags done in previous commit. better its added by the developer and not automatically by Tagify
  • Refactored. removed all CSS variables fallbacks to SCSS variables because they already have fallbacks...
  • Added "data-editable" for tags (default is undefined which means "true") 
  • Removed unneeded left-trim because the the returned value is already trimmed 
  • Updated eslintrc file
  • Removed unused package gulp-eslint
  • Updated eslintrc file
  • Fixes - support originalInputValueFormat setting in mix-mode
  • Fixed some mix-mode issues with new line before/after tags in FF/Chrome. Still a bug for new line before a tag in FF causes double BRs
  • Fixed placeCaretAfterNode after last change in the function
  • Fixes - Editing a tag, allows you to have duplicated tags (case insenstitve)
  • Removed the fix done for #653 as it seems fixed in Chrome
  • Fixes - injecting a tag node using injectAtCaret without prior focus results in an error
  • Fix Changed order of if clauses in iterateChildren function
  • Fixing typo

v4.12.0 (2022-04-26)

  • editing existing valid tag by adding spaces before or after, should not affect validation, unless the trim setting is false
  • fixed - transformTag setting can make a tag invalid when editing
  • exposed the helpers for outside usage
  • added a comment 381ee1d
  • fixed - dropdownFooter shows "Refine your search" when maxItems = 0 (which shows all items)

v4.11.0 (2022-04-11)

  • improved the example for the users-list. it now uses the new dropdown header template instead of the hacky way it used to work 
  • stop adding a tag when blured in select-mode - when typing a tag and blurring, if the typed text is not included in the whitelist, it will be cleared
  • do not render the dropdown header template if there's nothing in it
  • added 2 new templates for dropdown header & footer
  • fixes - keyboard shortcut for bold and italic interfere with mix-mode output
  • for "select" mode - if text value is not in the whitelist, clear it once the input is blured
  • fixes - Tagify can change a tag value to its tagTextProp under mysterious circumstances
  • fixes - destroy() method throws DOM not defined exception

v4.10.0 (2022-04-06)

  • now same styles as applied for "readonly" will also apply to "disabled", mainly so the X button will not be rendered
  • bugfixes

v4.9.8 (2022-02-18)

  • removed unneeded line after recent change which moved this to another onEditDone
  • fixed lots of bugs

v4.9.7 (2022-02-14)

  • fixed: "strim" setting has no affect on "loadOriginalValues" when in mix-mode

v4.9.6 (2022-02-07)

  • minor syntax and comments changes
  • added "help with something" issue templates
  • fixes - Unable to edit tags when they reached to maxTags
  • fixes - make the striped background on readonly an opt-out feature
  • re-ordered classNames
  • added "readonly" to be able to be configured from the settings and not only as an attribute on the original input
  • fixes - dropdown.enabled:false has no effect
  • Fix typo

v4.9.5 (2022-01-25)

  • Fixed bugs

v4.9.2 (2021-11-28)

  • add callback moved to be triggered after DOM has been modified
  • tag is set as readonly even though tagData has key readonly:false

v4.9.1 (2021-11-20)

  • fixed: readonly tag may be deleted in *mix-mode *

v4.9.0 (2021-11-14)

  • React: switched to using the unminified Tagify for easier debugging 
  • fixes - [feat] added ther ability to persist data on localstorage automatically using a unique id per-instance
  • no need to place loadOriginalValues within a setTimeout because it's automatically fired from "observeOriginalInputValue"
  • fixes- Distribute non-minified code on NPM
  • fixes - Dropdown selection in edited tag with emptied value fails
  • fixes - move transformTag callback to be called before valitation happens
  • fixes - Input is enabled in disabled mode
  • minor fix for some random console error
  • fixes - Placeholder text only shows when the page first loads

v4.8.1 (2021-09-25)

  • Fixed bugs

v4.8.0 (2021-09-22)

  • Fixes various bugs regarding mix-mode backspace & ENTER both in Chrome & FF.

v4.7.2 (2021-08-23)

  • Bugfix: Extra newlines added on double Enter

v4.7.1 (2021-08-22)

  • Added dropdown.toggle method
  • Fixes an issue with "userInput" setting - when a tag is selected the dropdown is closed bu the component still has focus so clicking it again will not re-open then dropdown. Must force enabled to 0 to solve this.

v4.7.0 (2021-08-21)

  • fixed: mix-mode with tags, when caret at the end and pessing Delete a few times, tags should not be removed
  • fixed: mix-mode with simple whitelist & "dropdown.enabled = 0" setting could not select suggestions after only typing the pattern
  • fixed: added "userInput" setting ("true" by default) which allows typing/pasting/editing tags
  • updated Codepen CSS for toggling original input visibility
  • fixed: removed IE support
  • fixed: when allowing duplicates, duplicates are not matched with the filtered whitelist
  • fixed: allows Select mode to not be editable if "enforceWhitelist" setting is set, and also allows backspace to remove selected tag
  • select-mode with "enforceWhitelist" setting should not be editable
  • improved "advanced options" example so a single click will change to a random tag color

v4.6.0 (2021-07-29)

  • Add mechanism to unbind all global event listeners of an instance
  • Refactored "texts" for easier customization from "settings"
  • Fixed bugs.

v4.5.0 (2021-07-14)

  • Briefly show knobs before closing it
  • Improved the "easy to customize" section in the demo page with link to CSS variables
  • fixed missing parts in code examples syntax highlighter in the demo page
  • R efactored code for better supporting React components as templates

v4.4.0 (2021-07-04)

  • Fixed bugs

v4.3.1 (2021-06-16)

  • Minor bugfix for invalid edited tags' title tooltip

v4.3.0 (2021-06-13)

  • fixed: backspace in 'mix' mode with multiple lines Previous lines are being hidden and removed from the text area
  • [chore] refactored dropdown methods so they wouldn't need binding with "bind" or "call"
  • [feature] added "whitelist" getter and setter directly on the instance
  • fixed tags validation when edited/removed
  • improved "isSameDeep" to not stringify if already is a string
  • refactored "defaultValue" logic related to "value" changes
  • small general refactor for all events binding

v4.2.0 (2021-06-07)

  • Bugs fixed.

v4.1.4 (2021-05-31)

  • restored missing header comment in minified files
  • suggestions dropdown list now has scrollbar shown by default and no only on hover, for touch screen issues where "hover" cannot be applied
  • fixed: revalidate max tags after tags are removed

v4.1.3 (2021-05-24)

  • fixes - onInput event is fired too early, before a tag was added, so "tagify.value" is not up-to-date
  • fixes - Re-validation on edit/delete tags

v4.1.2 (2021-05-16)

  • fixed: retain invalid tags (including from page load) but color them red

v4.1.1 (2021-04-25)

  • [feat] when "a11y.focusableTags" setting is true, allows editing tags by pressing "enter" key

v4.1.0 (2021-04-25)

  • Bugs fixed

v4.0.5 (2021-04-16)

  • fixed: mix mode now support loading animation
  • improved "mix mode" section with settings example
  • cleaned unwanted props also in mix-mode when updating original field's value

v4.0.4 (2021-04-11)

  • fixed: apparently without the setTimeout, if another Tagify was "under" the selected suggestion, it will gain focus 46ad4e5
  • fixed: added __tagId property to each data item on the this.value and also on the tag elements themselves, so they could be matched to the correct item in the this.value

v4.0.3 (2021-04-06)

  • added dropdown:updated support in the React Wrapper

v4.0.2 (2021-04-05)

  • fixed: changed the propTypes for "children" in the React Wrapper
  • fixed: added all missing custom event listeners to the React wrapper
  • fixed: React wrapper now exports MixedTags correctly

v4.0.1 (2021-04-03)

  • fixesed: updated addTags to use DOM fragment for better performance when adding tons of tags at-once (copy=paste)
  • improved filtering suggestions for "select" mode: if a tag was chosen, do not filter by value until the tag is erased or was edited. if tag is edited so all characters removed, then the field blured - the tag is now removed. Also when editing the text and bluring, the tag is updated.
  • improved demo for "select" mode
  • makes more sense to use "auto" since the X button should be to the right (in LTR)
  • fixesed: Can't make tagTextProp work when mode select is set

v4.0 (2021-03-30)

  • improved controlled-component ability by better comparing between current value and new value
  • changed how the original input is un-hidden
  • fixed: Browser shows console error when submitting a form with a "required" tagified input element which is empty

v3.25.0 (2021-03-30)

  • improved controlled-component ability by better comparing between current value and new value
  • changed how the original input is un-hidden
  • fixes: Browser shows console error when submitting a form with a "required" tagified input element which is empty

v3.25.0 (2021-03-29)

  • fixed: Previous tag is deleted when quickly pressing backspace and typing new text
  • fixed: added "suggestionClick" hook to the "enter" key down event, while sending the tag's data to the hook's function
  • fixed: added deep compare to the React wrapper when the "value" changes (AKA "controlled")
  • fixed: in "select" mode, when selecting an option, the dropdown will no longer show any of the other options

v3.23.1 (2021-03-08)

  • fixed: line-height clipped certain fonts glyphs
  • fixed: Method removeAllTags ignores the passed option withoutChangeEvent
  • fixed:  tag somewhere in the middle of textarea and then put cursor to the end and press "DEL" then tag will be deleted
  • fixed: Caret stretch to full parent height in contenteditable inline with inline first child element

v3.22.3 (2021-02-26)

  • fixes when typing and bluring the text is not becoming red and then deletced after a while (if whilist is objects and enforceWhitelist is true)
  • [FEAT] force dropdown to always open (be placed) above or below the input
  • removed Angular port from repo and linked to a dedicated repo made by another developer
  • fixes "navigator" not available in SSR
  • [CHORE] updated dependencies

v3.22.3 (2021-02-14)

  • fixed: when editing a tag, the "edit:beforeUpdate" should not deep-clone the data, so the developer could modify it at the event callback if it is wished to remove/add other properties to the edited tag before the tag is replaced, therefore added a third option to the "trigger" event method
  • fixed: when editing a tag which has other properties than "value" they should be persisted after editing
  • Added a missing custom event
  • fixed: Cannot read property 'withoutChangeEvent' of undefined
  • fixed: typo 

v3.22.2 (2021-02-14)

  • when filtering dropdown items, in case whitelist items do not contain any of the custom "mapValueTo" array strings, then use value instead 
  • fix for whitelist of numbers a(not strings)
  • fixes When using objects with "mapValueTo", typing tab to insert tag inserts value
  • fixes Unable to insert tag containing "<x>" with tab key
  • fixes dropdown border bottom in chrome
  • fixes Clicking on The Drop-Down Scroll Closes the Dropdown 
  • support for multiple class names in settings.classNames properties
  • fixes loadOriginalValues triggers multiple change event
  • fixes last element stays in dropdown (when dropdown.position is "manual") 

v3.22.1 (2021-01-18)

  • [FEAT] add select & mix namespace classnames to the settings.classNames object
  • [BUGFIX] TAB key does nothing in single-value mode with text entered
  • [BUGFIX] Cannot read property 'insertBefore' of null
  • [BUGFIX] when using "tagTextProp" setting, and typing a tag, without a whitelist, "value" property is set to "undefined"

v3.22.0 (2020-12-27)

  • [FEAT] Programmatically adding tags in mix-mode
  • In Mix mode, newly created tags are deleted when pressing backspace at the start of textbox
  • [CHORE] added an item to the FAQ list after somebody asked a question
  • [BUGFIX] autofocus React Component
  • [BUGFIX] [React - Mixed mode] remove tag after starting in read-only
  • [BUGFIX] Setting non-default mixTagsInterpolator fails to parse out tags
  • [BUGFIX] Programmatically adding tags in mix-mode throws an error
  • [BUGFIX] Check native support for promises in polyfill
  • add "np" package to streamline publishing 0d1a8cd
  • demo page minor changes to head tag children
  • [BUGFIX] if "dropdownItemNoMatch" template is used, and the item is clicked, the dropdown won't close even if clicked outside afterwards
  • Replaced demo settings with Knobs - changed H2 titles color to match the logo color
  • [BUGFIX] regarding mix-mode custom whitelist text prop (not "value")
  • [BUGFIX] mix-mode fixes for complex whiteilst where values are ids and another property is used as the text of the tags/suggestions
  • [BUGFIX] - minor fix related to "sameStr" helper function
  • [BUGFIX] [Chrome Android] cannot delete mix-mode tags using the keyboard "backspace" key
  • [BUGFIX] If tag value ends with space whitelist not working
  • added new "validate" function to settings, for more complex validations which pattern cannot solve
  • [BUGFIX] When using dropdown.mapValueTo option the original whitelist data structure changes

v3.21.3 (2020-11-23)

  • [BUGFIX] if "dropdownItemNoMatch" template is used, and the item is clicked, the dropdown won't close even if clicked outside afterwards

v3.21.3 (2020-11-11)

  • made "this.trim" error-proof for "undefined" values

v3.21.0 (2020-11-06)

  • when editing, on blur, add an extra parameter to "transformTag" with the preivous data object

v3.20.3 (2020-10-25)

  • fixed cannot create mix-text tags

v3.20.2 (2020-10-25)

  • fixed mix-mode readonly did not hide tags (x) button

v3.20.1 (2020-10-24)

  • fixed a TON of mix-mode delete/backspace issues, many with readonly-tags
  • removed empty textnodes inside tag template, which affected caret placement at some situations
  • added "removeTextChildNodes" & "getfirstTextNode" helpers
  • fixed an issue with restoring multiple readonly tags which were deleted by the browser (range-selection)

v3.20.0 (2020-10-08)

  • Minor changes.

v3.19.7 (2020-10-06)

  • Fixed edited tag with custom template to be able to revert back

v3.19.5 (2020-10-05)

  • pasting text in non-empty input should use all text and not just the pasted part

v3.19.4 (2020-10-01)

  • "onEditTagBlur" should keep any pre-defined properties of the tag's data

v3.19.2 (2020-09-28)

  • fixed: whitelist items with commas should't be splitted to seperate tags

v3.19.1 (2020-09-26)

  • fixed: Mixed mode - Backspace issue

v3.19.0 (2020-09-22)

  • added "integrated" mode which skips the creation of the wrapper

v3.18.1 (2020-09-06)

  • Fixed JS error when entering special characters
  • Fixed: Make the tag search work with keywords, rather than a continuous string

v3.17.10 (2020-09-06)

  • fuzzy-search refactored using Regex

v3.17.10 (2020-08-29)

  • Fixed: when the dropdown is visible, with no item selected, and "tab" key is pressed & whitelist has objects, the first one is added.

v3.17.9 (2020-08-28)

  • minor version bump

v3.17.3 (2020-08-11)

  • Fixed: Editing tags with dropdown enabled is not saving the new value

v3.17.2 (2020-08-09)

  • Bugfixed

v3.17.1 (2020-08-06)

  • Bugfixed

v3.16.3 (2020-07-29)

  • Fixed: Every tag entered adds &nbsp;

v3.16.2 (2020-07-28)

  • update

v3.15.4 (2020-07-20)

  • dropdown position is now an attribute by itself and not a part of the class name
  • dropdown position defaults to "all" if the viewport width is less, or equal, to 480px

v3.15.3 (2020-07-15)

  • Fixed Tagify suggests undefined

v3.15.1 (2020-07-14)

  • changed "dropdownItemNoMatch" template prop to be an Object instead of a String

v3.14.3 (2020-07-09)

  • Fixed: Automatically close dropdown is not working

v3.14.2 (2020-07-07)

  • Update

v3.13.0 (2020-07-03)

  • Update

v3.12.0 (2020-06-28)

  • Allow whitelist items to have a `value` type `Number` 

v3.11.3 (2020-06-22)

  • Bugfix

v3.11.2 (2020-06-21)

  • Fixed onChange is not called when clearing the last tag

v3.11.0 (2020-06-13)

  • Add action button in suggestions dropdown items

v3.10.2 (2020-06-02)

  • Allowed placing action-buttons inside the "dropdownItem" template so anything with a class "tagify__dropdown__item__action" will be ignored when clicking, and will not select that suggestion (but will trigger a "blur" event which will close the suggestions dropdown)

v3.9.2 (2020-05-19)

  • Fixed: Mix text & tags - error when add a tag after deleted another one - IndexSizeError

v3.9.1 (2020-05-17)

  • bug fix

v3.8.0 (2020-05-09)

  • Fixed wrong value when paste the text in to input (Mix-mode)

v3.7.3 (2020-05-02)

  • Bug fix

v3.7.2 (2020-04-28)

  • Fixed Mixed Mode - Tags are in wrong order

v3.7.1 (2020-04-26)

  • removed ARIA attributes from component wrapper element

v3.6.10 (2020-04-06)

  • Bugs fixed

v3.6.6 (2020-04-04)

  • Bugs fixed

v3.6.3 (2020-03-18)

  • Bugs fixed

v3.6.1 (2020-03-05)

  • Bugs fixed

v3.5.1 (2020-02-26)

  • Bugs fixed

v3.4.1 (2020-02-08)

  • Bugs fixed

v3.3.1 (2020-02-05)

  • Bugs fixed

v3.3.0 (2020-01-26)

  • Bugs fixed

v3.2.6 (2020-01-07)

  • Bugs fixed

v3.2.3 (2019-12-23)

  • Wrong value after edit/update a tag

v3.2.2 (2019-12-21)

  • minor changes

v3.2.0 (2019-12-19)

  • minor changes

v3.0.0 (2019-12-13)

  • minor changes

v2.31.6 (2019-11-21)

  • Bugfix

v2.31.4 (2019-11-16)

  • Fixed Callback when removing a tag with backspace

v2.31.3 (2019-11-04)

  • Fixed Callback when removing a tag with backspace

v2.31.2 (2019-10-14)

  • Minor update

v2.31.1 (2019-10-14)

  • Mix Mode Cursor Position on trying to delete a Tag using Backspace key.

v2.29.1 (2019-10-07)

  • Do not normalize input value in "mixed" mode, to allow full control over the textarea to the developer, if anyone wishes their users to be able to do anything within the textarea or to control it outside of tagify.

v2.29.0 (2019-09-24)

  • minor CSS bugfix.

v2.28.2 (2019-09-14)

  • CSS bugfix.

v2.28.0 (2019-09-12)

  • CSS bugfix.

v2.26.3 (2019-09-02)

  • Fixed: Empty tag (via editing) *is* invalid, but remains, even with `keepInvalidTags: false`

v2.26.2 (2019-08-31)

  • Fixed: Safari (11.1.2): Can't edit tags (includes proposed fix)

v2.26.1 (2019-08-31)

  • Cleanup annoying "[addTags] no tags to add: Array []" console warning

v2.26.0 (2019-08-29)

  • Fixed Syntax error in React wrapper compilation

v2.25.3 (2019-08-28)

  • bugfix: when clicking anywhere on the screen there was an error in the console

v2.25.2 (2019-08-24)

  • Fixed: conflict "RENDER SUGGESTIONS LIST MANUALLY" Property with "TEXTAREA"
  • Fixed: Pasted text separated with new line symbol doesn't process correct

v2.24.0 (2019-08-18)

  • Remove "hasMaxTags" class when limit is not reached anymore

v2.23.1 (2019-07-30)

  • Remove "hasMaxTags" class when limit is not reached anymore

v2.22.3 (2019-06-19)

  • Fixed Pressing Enter while Suggestion List is open

v2.22.2 (2019-06-16)

  • Fixed Loading CSS Error

v2.22.1 (2019-06-06)

  • "removeTag" without an argument now removes last tag automatically
  • fixed Input value sent changed 

v2.21.0 (2019-05-29)

  • More bugs fixed

v2.19.0 (2019-05-15)

  • More bugs fixed.

v2.19.0 (2019-05-15)

  • More bugs fixed.

v2.18.2 (2019-05-02)

  • fixed demo IE11 issues

v2.18.1 (2019-04-27)

  • minor insignificant changes in code

v2.17.0 (2019-04-14)

  • fixed a minor bug from previous commit

v2.16.0 (2019-04-11)

  • Fixed: Incorrect interaction between enabled and maxItems for dropdown

v2.15.2 (2019-04-06)

  • Fix exception when input initial value is an empty json list

v2.15.1 (2019-03-26)

  • fixes dropdown mouse click to scroll
  • fixes whitelist of strings suggestions list HTML
  • fixes focus after clicking a suggestion item with the mouse
  • added "searchBy" property support for whitelist alias filtering

v2.15.0 (2019-03-27)

  • Bugfix

v2.14.0 (2019-02-27)

  • fixed removeTag is not working.

v2.13.0 (2019-02-26)

  • Deleting (backspacing) current tag input to the end, makes subsequent input change into tag immediately

v2.12.6 (2019-02-24)

  • Bugfix

v2.12.1 (2019-02-15)

  • Add duplicates in mix mode if duplicates setting false.

v2.11.1 (2019-01-27)

  • Add duplicates in mix mode if duplicates setting false.
  • Fixed placeholder does not update when changing dropdown active item using down arrow

v2.10.1 (2019-01-03)

  • Make blacklist works case-insensitive

v2.9.7 (2018-12-30)

  • Fixed Error when clicking outside of dropdown 

v2.9.1 (2018-12-17)

  • Changed the "input" event parameter to be a string (value) instead of an Object {value:value}

v2.9.0 (2018-12-16)

  • added custom "click" event

v2.8.6 (2018-12-14)

  • Bugfix

v2.8.5 (2018-12-10)

  • minor fix for editable tags blur event not working property

v2.8.4 (2018-12-09)

  • fixed: edit tag not running tag validation

v2.8.2 (2018-11-18)

  • Fixed an issue while pre-populating an unique numeric tag

v2.7.6 (2018-11-18)

  • Bugfix

v2.6.5 (2018-11-03)

  • Fixed: Duplicates tag in Internet Explorer if tag has "@" symbol and delimiter is space bar.

v2.6.3 (2018-10-27)

  • "input" event wasn't triggered in the optimal place. should be triggered after this.input.set
  • "filterListItems" method should not strip whitespaces

v2.6.0 (2018-10-12)

  • Bugfixes

v2.5.1 (2018-10-06)

  • Bugfixes

v2.2.10 (2018-09-24)

  • Bugfixes

v2.1.9 (2018-09-08)

  • Fixed Trigger dropdown

v2.1.4 (2018-08-18)

  • Tiny bug fix in "normalizeTags" where Tagify instances with complex whitelist didn't allow entering any other tags except the whitelist's ones

v2.1.1 (2018-08-12)

  • You can add Tags in the readonly mode

v2.1.0 (2018-07-08)

  • general refactoring

2018-06-24

  • Fixed for key/value tags

2018-03-28


This awesome jQuery plugin is developed by yairEO. For more Advanced Usages, please check the demo page or visit the official website.