GithubHelp home page GithubHelp logo

yaireo / tagify Goto Github PK

View Code? Open in Web Editor NEW
3.3K 20.0 425.0 6.56 MB

๐Ÿ”– lightweight, efficient Tags input component in Vanilla JS / React / Angular / Vue

Home Page: https://yaireo.github.io/tagify/

License: Other

JavaScript 46.21% HTML 49.40% SCSS 4.39%
tagging html input tags tagify javascript react reactjs react-component angular-component

tagify's Introduction



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

Installation

Option 1 - import from CDN:

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

<script src="https://cdn.jsdelivr.net/npm/@yaireo/tagify"></script>
<script src="https://cdn.jsdelivr.net/npm/@yaireo/tagify/dist/tagify.polyfills.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/@yaireo/tagify/dist/tagify.css" rel="stylesheet" type="text/css" />

Tagify will then be available globally. To load specific version use @ - for example: unpkg.com/@yaireo/[email protected]

option 2 - import as a Node module:

npm i @yaireo/tagify --save

Basic Usage Examples

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 whic a must-have property of value:

whitelist: [{value: 'foo', id: '123', email: '[email protected]'}, ...]

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

Debugging

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:

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 <select>)
  • Supports whitelist/blacklist
  • Customizable HTML templates for the different areas of the component (wrapper, tags, dropdown, dropdown item, dropdown header, dropdown footer)
  • Shows suggestions list (flexiable settings & styling) at full (component) width or next to the typed texted (caret)
  • Allows setting suggestions' aliases for easier fuzzy-searching
  • Auto-suggest input as-you-type with the ability to auto-complete
  • Can paste in multiple values: tag 1, tag 2, tag 3 or even newline-separated tags
  • Tags can be created by Regex delimiter or by pressing the "Enter" key / focusing of the input
  • Validate tags by Regex pattern or by function
  • Tags may be editable (double-click)
  • ARIA accessibility support(Component too generic for any meaningful ARIA)
  • Supports read-only mode to the whole component or per-tag
  • Each tag can have any properties desired (class, data-whatever, readonly...)
  • Automatically disallow duplicate tags (vis "settings" object)
  • Has built-in CSS loader, if needed (Ex. AJAX whitelist pulling)
  • Tags can be trimmed via hellip by giving max-width to the tag element in your CSS
  • Easily change direction to RTL (via the SCSS file)
  • Internet Explorer - A polyfill script should be used: tagify.polyfills.min.js (in /dist) (IE support has been dropped)
  • Many useful custom events
  • Original input/textarea element values kept in sync with Tagify

Building the project

Simply run gulp in your terminal, from the project's path (Gulp should be installed first).

Source files are this path: /src/

Output files, which are automatically generated using Gulp, are in: /dist/

Output files:

Filename Info
tagify.esm.js ESM version. see jsbin demo
tagify.js unminified UMD version, including its souremaps
tagify.min.js minified UMD version, including its souremaps. This is the main file the package exports.
tagify.polyfills.min.js Used for old Internet Explorer browser support
react.tagify.js Wrapper-only for React. Read more (Deprecaded as of APR 24', import the file from /src instead)
jQuery.tagify.min.js jQuery wrapper - same as tagify.min.js. Might be removed in the future. (Deprecaded as of APR 24')
tagify.css

Adding tags dynamically

var tagify = new Tagify(...);

tagify.addTags(["banana", "orange", "apple"])

// or add tags with pre-defined properties

tagify.addTags([{value:"banana", color:"yellow"}, {value:"apple", color:"red"}, {value:"watermelon", color:"green"}])

Output value

There are two possible ways to get the value of the tags:

  1. Access the tagify's instance's value prop: tagify.value (Array of tags)
  2. Access the original input's value: inputElm.value (Stringified Array of tags)

The most common way is to simply listen to the change event on the original input

var inputElm = document.querySelector,
    tagify = new Tagify (inputElm);

inputElm.addEventListener('change', onChange)

function onChange(e){
  // outputs a String
  console.log(e.target.value)
}

Default format is a JSON string:
'[{"value":"cat"}, {"value":"dog"}]'

I recommend keeping this because some situations might have values such as addresses (tags contain commas):
'[{"value":"Apt. 2A, Jacksonville, FL 39404"}, {"value":"Forrest Ray, 191-103 Integer Rd., Corona New Mexico"}]'

Another example for complex tags state might be disabled tags, or ones with custom identifier class:
(tags can be clicked, so delevopers can choose to use this to disable/enable tags)
'[{"value":"cat", "disabled":true}, {"value":"dog"}, {"value":"bird", "class":"color-green"}]'

To change the format, assuming your tags have no commas and are fairly simple:

var tagify = new Tagify(inputElm, {
  originalInputValueFormat: valuesArr => valuesArr.map(item => item.value).join(',')
})

Output:
"cat,dog"

Ajax whitelist

Dynamically-loaded suggestions list (whitelist) from the server (as the user types) is a frequent need to many.

Tagify comes with its own loading animation, which is a very lightweight CSS-only code, and the loading state is controlled by the method tagify.loading which accepts true or false as arguments.

Below is a basic example using the fetch API. I advise aborting the last request on any input before starting a new request.

Example:
var input = document.querySelector('input'),
    tagify = new Tagify(input, {whitelist:[]}),
    controller; // for aborting the call

// listen to any keystrokes which modify tagify's input
tagify.on('input', onInput)

function onInput( e ){
  var value = e.detail.value
  tagify.whitelist = null // reset the whitelist

  // https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort
  controller && controller.abort()
  controller = new AbortController()

  // show loading animation.
  tagify.loading(true)

  fetch('http://get_suggestions.com?value=' + value, {signal:controller.signal})
    .then(RES => RES.json())
    .then(function(newWhitelist){
      tagify.whitelist = newWhitelist // update whitelist Array in-place
      tagify.loading(false).dropdown.show(value) // render the suggestions dropdown
    })
}

Persisted data

Sometimes the whitelist might be loaded asynchronously, and so any pre-filled value in the original input field will be removed if the enforceWhitelist is set to true.

Tagify can automatically restore the last used whitelist by setting a unique id to the Tagify instance, by using the localstorage to persist the whitelist & value data:

var input = document.querySelector('input'),
    tagify = new Tagify(input, {
      id: 'test1',  // must be unique (per-tagify instance)
      enforceWhitelist: true,
    }),

Edit tags

Tags that aren't read-only can be edited by double-clicking them (by default) or by changing the editTags setting to 1, making tags editable by single-clicking them.

The value is saved on blur or by pressing enter key. Pressing Escape will revert the change trigger blur. ctrlz will revert the change if an edited tag was marked as not valid (perhaps duplicate or blacklisted)

To prevent all tags from being allowed to be editable, set the editTags setting to false (or null).
To do the same but for specific tag(s), set those tags' data with editable property set to false:

<input value='[{"value":"foo", "editable":false}, {"value":"bar"}]'>

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 recieves a tag data object as an argument and should return true if validaiton 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:

{
  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:

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

Or by directly manipulating the Tagify function prototype:

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.

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, 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:

// ...more tagify settings...
templates: {
  dropdownItemNoMatch: data =>
    `<div class='${tagify.settings.classNames.dropdownItem}' value="noMatch" tabindex="0" role="option">
        No suggestion found for: <strong>${data.value}</strong>
    </div>`
}

View templates

Example of overriding the tag template:

Each template function is automatically binded 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.

new Tagify(inputElem, {
  templates: {
    tag(tagData, tagify){
      return `<tag title="${(tagData.title || tagData.value)}"
              contenteditable='false'
              spellcheck='false'
              tabIndex="${this.settings.a11y.focusableTags ? 0 : -1}"
              class="${this.settings.classNames.tag} ${tagData.class ? tagData.class : ""}"
              ${this.getAttributes(tagData)}>
      <x title='' class="${this.settings.classNames.tagX}" role='button' aria-label='remove tag'></x>
      <div>
          <span class="${this.settings.classNames.tagText}">${tagData[this.settings.tagTextProp] || tagData.value}</span>
      </div>
    </tag>`,

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

      return hasMore > 0
        ? `<footer data-selector='tagify-suggestions-footer' class="${this.settings.classNames.dropdownFooter}">
            ${hasMore} more items. Refine your search.
          </footer>`
        : '';
    }
  }
})

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 <body> 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
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

<div class="tagify__dropdown tagify__dropdown--text" style="left:993.5px; top:106.375px; width:616px;">
    <div class="tagify__dropdown__wrapper">
      <div class="tagify__dropdown__item tagify__dropdown__item--active" value="aaab">aaab</div>
      <div class="tagify__dropdown__item" value="aaabb">aaabb</div>
      <div class="tagify__dropdown__item" value="aaabc">aaabc</div>
      <div class="tagify__dropdown__item" value="aaabd">aaabd</div>
      <div class="tagify__dropdown__item" value="aaabe">aaabe</div>
    </div>
</div>

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.

Example for a suggestion item alias

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

Example whitelist:

[
  {
    value    : 123456,
    nickname : "foo",
    email    : "[email protected]"
  },
  {
    value    : 987654,
    nickname : "bar",
    email    : "[email protected]"
  },
  ...more..
]

Modified searchKeys setting to also search in other keys:

{
  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:

{
  //  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 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 <Select> element, but allows typing text as value.

React

See live demo for React integration examples. โš ๏ธ Tagify is not a controlled component.

A Tagify React component is exported from react.tagify.jsx:


Update regarding onChange prop:

I have changed how the onChange works internally within the Wrapper of Tagify so as of March 30, 2021 the e argument will include a detail parameter with the value as string. There is no more e.target, and to access the original DOM input element, do this: e.detail.tagify.DOM.originalInput.


Note: You will need to import Tagify's CSS also, either by JavaScript or by SCSS @import (which is preferable) Also note that you will need to use dart-sass and not node-sass in order to compile the file.

import { useCallback, useRef } from 'react'
import Tags from "@yaireo/tagify/src/react.tagify" // React-wrapper file
import "@yaireo/tagify/dist/tagify.css" // Tagify CSS

const App = () => {
    // on tag add/edit/remove
    const onChange = useCallback((e) => {
        console.log("CHANGED:"
            , e.detail.tagify.value // Array where each tag includes tagify's (needed) extra properties
            , e.detail.tagify.getCleanValue() // Same as above, without the extra properties
            , e.detail.value // a string representing the tags
        )
    }, [])

    return (
        <Tags
            whitelist={['item 1', 'another item', 'item 3']}
            placeholder='Add some tags'
            settings={{
                blacklist: ["xxx"],
                maxTags: 4,
                dropdown: {
                    enabled: 0 // always show suggestions dropdown
                }
            }}
            defaultValue="a,b,c" // initial value
            onChange={onChange}
        />
    )
}

To gain full access to Tagify's (instance) inner methods, A custom ref can be used:

import Tags, {MixedTags} from "@yaireo/tagify/src/react.tagify";

...
const tagifyRef = useRef()
...
<Tags tagifyRef={tagifyRef} ... />

// or mix-mode
<MixedTags
  settings={...}
  onChange={...}
  defaultValue={`This is a textarea which mixes text with [[{"value":"tags"}]].`}
/>

<MixedTags> component is a shorthand for <Tags InputMode="textarea">

Updating the component's state

The settings prop is only used once in the initialization process, please do not update it afterwards.


๐Ÿ“– List of (React) props for the <Tags/> component
Prop Type Updatable Info
settings Object See settings section
name String โœ” <input>'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 <textarea> (hidden) element instead of the default <input> and automatically make Tagify act as "mix mode"
autoFocus Boolean Should the component have focus on mount. Must be unique, per-page.
children String/Array value/defaultValue props are prefered
onChange Function See events section
onInput Function See events section
onAdd Function See events section
onRemove Function See events section
onInvalid Function See events section
onClick Function See events section
onKeydown Function See events section
onFocus Function See events section
onBlur Function See events section
onEditInput Function See events section
onEditBeforeUpdate Function See events section
onEditUpdated Function See events section
onEditStart Function See events section
onEditKeydown Function See events section
onDropdownShow Function See events section
onDropdownHide Function See events section
onDropdownSelect Function See events section
onDropdownScroll Function See events section
onDropdownNoMatch Function See events section
onDropdownUpdated Function See events section

jQuery version

This variant of Tagify code has been deprecated because it doesn't really add much in terms of ease-of-use. I only made it so it would be possible to use jQuery selectors & chaining but the (jQuery) port really isn't needed when implementing Tagify within a jQuery code.

Below is the documentation for previous Tagify packages versions which included support:

jQuery.tagify.js

A jQuery wrapper version is also available, but I advise not using it because it's basically the exact same as the "normal" script (non-jqueryfied) and all the jQuery's wrapper does is allowing to chain the event listeners for ('add', 'remove', 'invalid')

$('[name=tags]')
    .tagify()
    .on('add', function(e, tagData){
        console.log('added', ...tagData)  // data, index, and DOM node
    });

Accessing methods can be done via the .data('tagify'):

$('[name=tags]').tagify();
// get tags from the server (ajax) and add them:
$('[name=tags]').data('tagify').addTags('aaa, bbb, ccc')

HTML input & textarea attributes

The below list of attributes affect Tagify.
These can also be set by Tagify settings Object manually, and not declerativly (via attributes).

Attribute Example Info
pattern
<input pattern='^[A-Za-z_โœฒ ]{1,15}$'>
Tag Regex pattern which tag input is validated by.
placeholder
<input placeholder='please type your tags'>
This attribute's value will be used as a constant placeholder, which is visible unless something is being typed.
readOnly
<input readOnly>
No user-interaction (add/remove/edit) allowed.
autofocus
<input autofocus>
Automatically focus the the Tagify component when the component is loaded
required
<input required>
Adds a required attribute to the Tagify wrapper element. Does nothing more.

Caveats

  • <input> wrapped in a <label> doesn't work - #1219 and so Tagify internally sets the label's for attribute to an empty string, so clicking the Tagify component will not blur it and re-focus on the hidden input/textarea element Tagify is "connected" to

FAQ

List of questions & scenarios which might come up during development with Tagify:

Dynamic whitelist The whitelist initial value is set like so:
const tagify = new Tagify(tagNode, {
  whitelist: ["a", "b", "c"]
})

If changes to the whitelist are needed, they should be done like so:

Incorrect:

tagify.settings.whitelist = ["foo", "bar"]

Correct:

// set the whitelist directly on the instance and not on the "settings" property
tagify.whitelist = ["foo", "bar"]

tags/whitelist data structure

Tagify does not accept just any kind of data structure.
If a tag data is represented as an Object, it must contain a unique property value which Tagify uses to check if a tag already exists, among other things, so make sure it is present.

Incorrect:

[{ "id":1, "name":"foo bar" }]

Correct:

[{ "id":1, "value": 1, "name":"foo bar" }]
[{ "value":1, "name":"foo bar" }]
[{ "value":"foo bar" }]
// ad a simple array of Strings
["foo bar"]

Save changes (Ex. to a server)

In framework-less projects, the developer should save the state of the Tagify component (somewhere), and the question is:
when should the state be saved? On every change made to Tagify's internal state (tagify.value via the update() method).

var tagify = new Tagify(...)

// listen to "change" events on the "original" input/textarea element
tagify.DOM.originalInput.addEventListener('change', onTagsChange)

// This example uses async/await but you can use Promises, of course, if you prefer.
async function onTagsChange(e){
  const {name, value} = e.target
  // "imaginary" async function "saveToServer" should get the field's name & value
  await saveToServer(name, value)
}

If you are using React/Vue/Angular or any "modern" framework, then you already know how to attach "onChange" event listeners to your <input>/<textarea> elements, so the above is irrelevant.


Render tags in one single line

Stopping tags from wrapping to new lines, add this to your .tagify selector CSS Rule:

flex-wrap: nowrap;

Submit on `Enter` key

Tagify internally has state property, per Tagify instance and this may be useful for a variety of things when implementing a specific scenario.

var tagify = new Tagify(...)
var formElm = document.forms[0]; // just an example

tagify.on('keydown', onTagifyKeyDown)

function onTagifyKeyDown(e){
  if( e.key == 'Enter' &&         // "enter" key pressed
      !tagify.state.inputText &&  // assuming user is not in the middle or adding a tag
      !tagify.state.editing       // user not editing a tag
    ){
    setTimeout(() => formElm.submit())  // put some buffer to make sure tagify has done with whatever, to be on the safe-side
  }

}

CSS Variables

Learn more about CSS Variables) (custom properties)

Tagify's utilizes CSS variables which allow easy customization without the need to manually write CSS. If you do wish to heavily style your Tagify components, then you can (and should) use the below variables within your modified styles as much as you can.

For a live example, see the demos page.

Name Info
--tags-disabled-bg Tag background color when disabled
--tags-border-color The outer border color which surrounds tagify
--tags-hover-border-color hover state
--tags-focus-border-color focus state
--tag-border-radius Tag border radius
--tag-bg Tag background color
--tag-hover Tag background color on hover (mouse)
--tag-text-color Tag text color
--tag-text-color--edit Tag text color when a Tag is being edited
--tag-pad Tag padding, from all sides. Ex. .3em .5em
--tag--min-width Minimum Tag width
--tag--max-width Maximum tag width, which gets trimmed with hellip after
--tag-inset-shadow-size This is the inner shadow size, which dictates the color of the Tags.
It's important the size fits exactly to the tag.
Change this if you change the --tag-pad or fontsize.
--tag-invalid-color For border color of edited tags with invalid value being typed into them
--tag-invalid-bg Background color for invalid Tags.
--tag-remove-bg Tag background color when hovering the ร— button.
--tag-remove-btn-color Remove (ร—) button text color
--tag-remove-btn-bg Remove (ร—) button background color
--tag-remove-btn-bg--hover Remove (ร—) button hover background color
--input-color Input text color
--tag-hide-transition Controls the transition property when a tag is removed. default is '.3s'
--placeholder-color Placeholder text color
--placeholder-color-focus Placeholder text color when Tagify has focus and no input was typed
--loader-size Loading animation size. 1em is pretty big, default is a bit less.
--readonly-striped Either a value 1 or 0 can be used to toggle the striped diagonal background in readonly

Suggestions Dropdown CSS variables

should be appiled on the :root {...} selector

Name Info
--tagify-dd-color-primary The suggestion's dropdown background color
--tagify-dd-bg-color Sugegstion's background color on hover
--tagify-dd-item--hidden-duration When selecting a suggestion, this is the duration for it to become hidden (shrink)
--tagify-dd-item-pad Suggestion item padding
--tagify-dd-max-height Maximum height of the suggestions dropdown (300px by default)

Full list of Tagify's SCSS variables

Methods

Tagify is prototype based and There are many methods, but I've chosen to list the most relevant ones:

Name Parameters Info
destroy Reverts the input element back as it was before Tagify was applied
removeAllTags Removes all tags and resets the original input tag's value property
addTags
  1. Array/String/Object tag(s) to add
  2. Boolean clear input after adding
  3. Boolean - skip adding invalids
    Accepts a String (word, single or multiple with a delimiter), an Array of Objects (see above) or Strings.
    addMixTags Array/String 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 (at tagify.state.selection)
    removeTags
    1. Array/HTMLElement/String tag(s) to remove
    2. silent does not update the component's value
    3. tranDuration Transition duration (in ms)
    (#502) Remove single/multiple Tags. When nothing passed, removes last tag.
    • silent - A flag, which when turned on, does not remove any value and does not update the original input value but simply removes the tag from tagify
    • tranDuration - delay for animation, after which the tag will be removed from the DOM
    addEmptyTag Object (tagData) Create an empty tag (optionally with pre-defined data) and enters "edit" mode directly. See demo
    loadOriginalValues String/Array Converts the input's value into tags. This method gets called automatically when instansiating Tagify. Also works for mixed-tags
    getWhitelistItemsByValue Object {value} - return an Array of found matching items (case-insensitive)
    getTagIndexByValue String Returns the index of a specific tag, by value
    getTagElmByValue String Returns the first matched tag node, if found
    isTagDuplicate String Returns how many tags already exists with that value
    parseMixTags String Converts a String argument ([[foo]]โ  and [[bar]]โ  are..) into HTML with mixed tags & texts
    getTagElms Returns a DOM nodes list of all the tags
    getTagElmByValue String Returns a specific tag DOM node by value
    getSetTagData HTMLElement, Object set/get tag data on a tag element (has.tagify__tag class by default)
    editTag HTMLElement Goes to edit-mode in a specific tag
    getTagTextNode HTMLElement Get the node which has the actual tag's content
    setTagTextNode HTMLElement, String Sets the text of a tag (DOM only, does not affect actual data)
    replaceTag tagElm, Object (tagData) Exit a tag's edit-mode. if "tagData" exists, replace the tag element with new data and update Tagify value
    loading Boolean toggle loading state on/off (Ex. AJAX whitelist pulling)
    tagLoading HTMLElement, Boolean same as above but for a specific tag element
    createTagElem Object (tagData) Returns a tag element from the supplied tag data
    injectAtCaret HTMLElement (injectedNode), Object (range) Injects text or HTML node at last caret position. range parameter is optional
    placeCaretAfterNode HTMLElement Places the caret after a given node
    insertAfterTag HTMLElement (tag element), HTMLElement/String (whatever to insert after)
    toggleClass Boolean Toggles class on the main tagify container (scope)
    dropdown.selectAll Add all whitelist items as tags and close the suggestion dropdown
    dropdown.show String Shows the sugegstions list dropdown. A string paramater allows filtering the results
    dropdown.hide Boolean Hides the suggestions list dropdown (if it's not managed manually by the developer)
    dropdown.toggle Boolean Toggles dropdown show/hide. the boolean parameter will force-show
    updateValueByDOMTags Iterate tag DOM nodes and re-build the tagify.value array (call this if tags get sorted manually)
    parseTemplate String/Function (template name or function), Array (data) 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
    setReadonly Boolean Toggles "readonly" mode on/off
    setDisabled Boolean Toggles "disabled" mode on/off
    getPersistedData String Get data for the specific instance by parameter
    setPersistedData *, 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)
    clearPersistedData String Clears 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)

    Events

    To listen to tagify events use the .on(EVENT_NAME, EVENT_CALLBACK_REFERENCE) mehotd and stop listening use the .off(EVENT_NAME, EVENT_CALLBACK_REFERENCE)

    All triggered events return the instance's scope (tagify).
    See e.detail for custom event additional data.

    Example 1
    var tagify = new Tagify(...)
    
    // events can be chainable, and multiple events may be binded for the same callback
    tagify
      .on('input', onInput)
      .on('edit:input edit:updated edit:start edit:keydown', e => console.log(e.type, e.detail))
    
    function onInput(e) {
      console.log(e.detail)
    }
    
    // later in the code you might do to unsubscribe the event listener with a specific callback
    tagify.off('input', onInput)
    Example 2
    var tagify = new Tagify(inputNode, {
      callbacks: {
        "change": (e) => console.log(e.detail),
        "dropdown:show": (e) => console.log(e.detail)
      }
    })
    Name Info
    change Any change to the value has occurred. e.detail.value callback listener argument is a String
    add A tag has been added
    remove A tag has been removed (use removeTag instead with jQuery)
    invalid A tag has been added but did not pass validation. See event detail
    input Input event, when a tag is being typed/edited. e.detail exposes value, inputElm & isValid
    paste Text pasted (not while editing a tag). The pasted text might or might not have been converted into tags, depneding if pasteAsTags setting is set to false
    click Clicking a tag. Exposes the tag element, its index & data
    dblclick Double-clicking a tag
    keydown When Tagify input has focus and a key was pressed
    focus The component currently has focus
    blur The component lost focus
    edit:input Typing inside an edited tag
    edit:beforeUpdate Just before a tag has been updated, while still in "edit" mode
    edit:updated A tag as been updated (changed view editing or by directly calling the replaceTag() method)
    edit:start A tag is now in "edit mode"
    edit:keydown keydown event while an edited tag is in focus
    dropdown:show Suggestions dropdown is to be rendered. The dropdown DOM node is passed in the callback, see demo.
    dropdown:hide Suggestions dropdown has been removed from the DOM
    dropdown:select Suggestions dropdown item selected (by mouse/keyboard/touch)
    dropdown:scroll Tells the percentage scrolled. (event.detail.percentage)
    dropdown:noMatch No whitelist suggestion item matched for the typed input. At this point it is possible to manually set tagify.suggestedListItems to any possible custom value, for example: [{ value:"default" }]
    dropdown:updated Fired 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

    Hooks

    Promise-based hooks for async program flow scenarios.

    Allows to "hook" (intervene) at certain points of the program, which were selected as a suitable place to pause the program flow and wait for further instructions on how/if to proceed.

    For example, if a developer wishes to add a (native) confirmation popup before a tag is removed (by a user action):
    var input = document.querySelector('input')
    var tagify = new Tagify(input,{
        hooks: {
            /**
             * Removes a tag
             * @param  {Array}  tags [Array of Objects [{node:..., data:...}, {...}, ...]]
             */
            beforeRemoveTag : function( tags ){
                return new Promise((resolve, reject) => {
                    confirm("Remove " + tags[0].data.value + "?")
                        ? resolve()
                        : reject()
                })
            }
        }
    })
    Name Parameters Info
    beforeRemoveTag Array (of Objects) Example
    suggestionClick Object (click event data) Example
    beforePaste tagify, pastedText, clipboardData Before pasted text was added to Tagify. Resolve with new paste value if needed
    beforeKeyDown On any browser keydown event, but called after keydown Tagify event
    Name Type Default Info
    id String See Persisted data
    tagTextProp String "value" Tag data Object property which will be displayed as the tag's text. Remember to keep "value" property unique. See Also: dropdown.mapValueTo, dropdown.searchKeys
    placeholder String Placeholder text. If this attribute is set on an input/textarea element it will override this setting
    delimiters String "," [RegEx string] split tags by any of these delimiters. Example delimeters: ",|.| " (comma, dot or whitespace)
    pattern String/RegEx null Validate input by RegEx pattern (can also be applied on the input itself as an attribute) Ex: /[1-9]/
    mode String null Use select for single-value dropdown-like select box. See mix as value to allow mixed-content. The 'pattern' setting must be set to some character.
    mixTagsInterpolator Array ['[[', ']]'] Interpolation for mix mode. Everything between these will become a tag
    mixTagsAllowedAfter RegEx /,|\.|\:|\s/ Define conditions in which typed mix-tags content is allowing a tag to be created after.
    duplicates Boolean false Should duplicate tags be allowed or not
    trim Boolean true If true trim the tag's value (remove before/after whitespaces)
    enforceWhitelist Boolean false Should ONLY use tags allowed in whitelist.
    In mix-mode, setting it to false will not allow creating new tags.
    userInput Boolean true Disable manually typing/pasting/editing tags (tags may only be added from the whitelist). Can also use the disabled attribute on the original input element. To update this after initialization use the setter tagify.userInput
    focusable Boolean true Allow the component as a whole to recieve focus. Implementations of Tagify without an external border should not allow 'focusability' which causes unwanted behaviour. (use-case example)
    autoComplete.enabled Boolean true Tries to suggest the input's value while typing (match from whitelist) by adding the rest of term as grayed-out text
    autoComplete.rightKey Boolean 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"
    autoComplete.tabKey Boolean 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).
    whitelist Array [] An array of allowed tags (Strings or Objects). When using Objects in the whitelist array a value property is a must & should be unique.
    Also, the *whitelist used for auto-completion when autoCompletion.enabled is true
    blacklist Array [] An array of tags which aren't allowed
    addTagOnBlur Boolean true Automatically adds the text which was inputed as a tag when blur event happens
    addTagOn Array ['blur', 'tab', 'enter'] 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
    onChangeAfterBlur Boolean true By default, the native way of inputs' onChange events is kept, and it only fires when the field is blured.
    pasteAsTags Boolean true Automatically converts pasted text into tags
    callbacks Object {} Exposed callbacks object to be triggered on events: 'add' / 'remove' tags
    maxTags Number Infinity Maximum number of allowed tags. when reached, adds a class "tagify--hasMaxTags" to <Tags>
    editTags Object/Number {} false or null will disallow editing
    editTags.clicks Number 2 Number of clicks to enter "edit-mode": 1 for single click. Any other value is considered as double-click
    editTags.keepInvalid Boolean true keeps invalid edits as-is until esc is pressed while in focus
    templates Object wrapper, tag, dropdownItem Object consisting of functions which return template strings
    validate Function If the pattern setting does not meet your needs, use this function, which receives tag data object as an argument and should return true if validation passed or false/string if not. A string may be returned as the reason for the validation failure.
    transformTag Function Takes a tag data as argument and allows mutating it before a tag is created or edited and also before validation.
    Should not return anything, only mutate the argument.
    keepInvalidTags Boolean false If true, do not remove tags which did not pass validation
    createInvalidTags Boolean true If true, create invalid-tags. Otherwise, keep the editable input and do not create tags from it
    skipInvalid Boolean false If true, do not add invalid, temporary, tags before automatically removing them
    backspace * true On pressing backspace key:
    true - remove last tag
    edit - edit last tag
    false - do nothing (useful for outside style)
    originalInputValueFormat Function 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.
    mixMode.insertAfterTag Node/String \u00A0 node or string to add after a tag added
    a11y.focusableTags Boolean false allows tags to get focus, and also to be deleted via Backspace
    dropdown.enabled Number 2 Minimum characters input for showing a suggestions list. false will not render a suggestions list.
    dropdown.caseSensitive Boolean false if true, match exact item when a suggestion is selected (from the dropdown) and also more strict matching for dulpicate items. Ensure fuzzySearch is false for this to work.
    dropdown.maxItems Number 10 Maximum items to show in the suggestions list
    dropdown.classname String "" Custom classname for the dropdown suggestions list
    dropdown.fuzzySearch Boolean true Enables filtering dropdown items values' by string containing and not only beginning
    dropdown.sortby String/Function 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.

    (default sorting order is same as the whitelist's)
    dropdown.accentedSearch Boolean true Enable searching for accented items in the whitelist without typing exact match (#491)
    dropdown.includeSelectedTags Boolean false Should the suggestions list Include already-selected tags (after filtering)
    dropdown.escapeHTML Boolean true Escapes HTML entities in the suggestions' rendered text
    dropdown.position String "all"
    • manual - will not render the dropdown, and you would need to do it yourself. See demo
    • text - places the dropdown next to the caret
    • input - places the dropdown next to the input (useful in rare situations)
    • all - normal, full-width design
    dropdown.RTL Boolean false Dictates the dropdown's horizontal starting position. By default it would be aligned with the left side of the Tagify component.
    dropdown.highlightFirst Boolean false When a suggestions list is shown, highlight the first item, and also suggest it in the input (The suggestion can be accepted with โ†’ key)
    dropdown.closeOnSelect Boolean true close the dropdown after selecting an item, if enabled:0 is set (which means always show dropdown on focus)
    dropdown.clearOnSelect Boolean true Keep typed text after selecting a suggestion
    dropdown.mapValueTo Function/String 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"
    dropdown.searchKeys Array ["value", "searchBy"] When a user types something and trying to match the whitelist items for suggestions, this setting allows matching other keys of a whitelist objects
    dropdown.appendTarget HTMLNode/Function document.body Target-Node which the suggestions dropdown is appended to (only when rendered). If used as a function, should return a DOM node.
    dropdown.placeAbove Boolean 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.

    tagify's People

    Contributors

    d-weber avatar danleyb2 avatar dependabot[bot] avatar eqqe avatar gencer avatar haseebeqx avatar jzohrab avatar keksa avatar kerolloz avatar lironhazan avatar matheuspolicamilo avatar mdashti avatar mecit avatar mikkoatgrynos avatar mohammad-matini avatar mshaaban0 avatar nazin avatar omcsesz avatar philetaylor avatar raymondsalim avatar scra3 avatar seb3s avatar shunichi avatar spazard1 avatar svensven avatar taaqif avatar wdietz avatar yaireo avatar yamiodymel avatar zaburt avatar

    Stargazers

     avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

    Watchers

     avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

    tagify's Issues

    Safari issue

    I am trying to use tagify in one of the pages to implement tags and auto-suggestions.
    The problem I am facing in safari is that the suggestion dropdown comes with a plain html dropdown menu and also selecting a keyword from the list of suggestions does not create a tag. Not sure if this has been reported before, but I do not see it in the list of issues here.

    Add on remove/add tag event possibility to check if it passed whitelist or not

    Right now, if you pass tag what isn't whitelisted, it still gets activated and then immediately removed. This basically means right now I have to do double work

    1. Add whitelist
    2. Check in function again if it is in whitelist.

    If you function details, there could be a parameter: "Passed whitelist" related, would be cool and make life easier.

    Whitelist support id and value!

    This might be harder (and not sure if possible), but if you could add into a white list of arrays ($id => $label) or something similar would be cool.

    That means: In tag lists, it will add and show a label, but when saved, the input will save/use the actual set id.

    This is a necessary feature if this project is used in larger databases OR there are the possibility of two same name strings.

    Extra space after comma

    Hi,

    Great Plugin ! Only drawback is that it adds an extra space after every comma, so the output list will look something like : test, test1.
    Could it be possible to add an option so it would be : test,test1 ?

    Thanks in advance for your help,
    Julien

    Always show suggestions list, or way to trigger showing the suggestion list

    First of all, great job on the library. I love the design.

    I have a short list of suggestions that I'd like to always show to the user. I set suggestionsMinChars to 0, but it seems the suggestion list is only triggered inside callbacks.onInput. It would be nice to have this as a custom event or method so we can manually trigger the suggestion list.

    Alternatively, you could also add the functionality that if suggestionsMinChars is 0, the suggestion list is shown as soon as the input gets focus.

    Max Suggestion to be displayed from whitelist && some unexpected behaviours!

    Can you please implement a new setting parameter that allows us to set how many suggestion the whitelist should display?
    if not that, a callback on the event "on change" would be good too to actually manually handle the whitelist and displaying a maximum number of results. basically something like this :

    function(request, response) {
            var results = element.filter(myarray, request.term,maxSuggestions);
            response(results.slice(0, maxSuggestions));
        }
    

    Also please release a pre-compiled version of this to be implemented on vanilla html without needing pre-processors.

    Also to correctly display the input like it's supposed to be displayed in the demo i had to manually hide the element i "tagified", i think it should be integrated in the tagify() function itself to actually hide the element that will only hold the value.

    Great job btw!

    Programmatically reset input

    Hello guy!

    First of all, congratulations for you lib. In my opinion, it's simple and easy to use as all lib should be!

    What I am trying to do and I am not being able is to reset the input after form to be successfully sent. I have a single page application, so my page will not reload after form submit. Looking your code, I have tried the following solution:

    // In my angular directive I store all tags in an array called "tags"
    scope.reset = function(){
      for (var i = 0; i < tags.length; i++)
        tagify.removeTag(i); // tagify is the instance of your component
    };

    So, I run this code after form submit. However, just some tags got removed. Other ones are still there and I couldn't understand why... ๐Ÿค”

    Could you help me?

    UPDATE
    As workaround, I have solved it destroying and intantiating the component again. Working fine.

    Make sure field is not empty

    Hi,

    How can I make sure the field is not empty ?
    Html tag 'required' is not working anymore using tagify.

    Thanks in advance,
    Julien

    Object doesn't support property or method 'findIndex'

    Hello,

    I have the following error on IE11
    "Object doesn't support property or method 'findIndex'"

    In the following line in jquery.tagify.min.js
    function(t){var e=this.value.findIndex(function(e){return t.toLowerCase()===e.toLowerCase()}

    It's seem that IE11 doesn't support findIndex
    https://stackoverflow.com/questions/41938036/object-doesnt-support-property-or-method-findindex-ie11-javascript-issue

    Maybe you do not support IE11?

    Thx in advance

    Event not triggering (?)

    Hello, I have this piece of code

    $('.tagify').each(function () {
    
                var $toTagify = $(this);
    
                $toTagify.tagify({
    
                    duplicates : false
    
                });
                
                $toTagify.on('add', function (e) {
                    console.log(e);
                    console.log("test");
                });
    
            });
    

    but the events are not triggering. Am I wrong or there's something that doesn't work properly?

    Is there a way to add a tag by code?

    Hello,

    I don't see in demos if it is possible to add a tag by calling a method in javascript.
    I tried this without success. Is there a way?

    var elm= $('#myInput').tagify();
    elm.addTag('myTag');
    

    Autocomplete related issues/fixes

    Currently, I have an issue where I have around 330 whitelisted items. Issue what it has is when it loads all together at once when I started typing, the browser becomes laggy. I don't have that shit computer, so I assume the most user would have the same issue. So, there is 2 recommendation, to add to autocomplete (or at least add a setting option for possibly support it!)

    1. Reduce the length of displaying all options and add a search bar to it. The search bar part should be an option not recommended, as if there aren't that many searchable options, it might become more pain, but having that option when whitelist is bigger, will help a lot! Below is example picture what another datatable plugin is using (Not tag support tho, ;))
      image
    2. Add option from when it will start autocompleting. Usually, it is the third character. This should be also an option, as if there are few characters, having it from first adds to the user experience. If you have however 330 whitelisted options, loading on the first character can be discouraging.

    Also side note: That arrow what you disappeared actually destroyed a bit friendliness. I usually try to think that all clients are actual dumb-users and if they see box, but no way to open the option list, it can be confusing to them. It is not that huge of an issue to me, as I simply reversed the CSS file commit, but just a small thought I had.

    Also, is it possible to donate for this project? I feel like you have done quite a lot, especially recently.

    tagify.min.js is not synch with tagify.js

    Hi, me again :)! I hope I am not getting annoying, as I truly think this is one of the best tagify libs out there. So I am suggesting things what makes sense, what are kinda needed in my current project and so on.

    The first bug: Took me a while, when I didn't see that any updated weren't synching. Apparently, min.js is not same as just js. For an example that auto-add tag doesn't work there. Else, awesome job!

    Wrong Brackets in readme page

    The closing bracket at the whitelist row must go to end

    tagify = new Tagify( input, {
        duplicates: true,
        whitelist: ['foo', 'bar']},
        callbacks: {
            add : onAddTag // calls an imaginary "onAddTag" function when a tag is added
        }
    );
    

    Using keyboard to select whitelisted item in Firefox fails

    Firefox 55.0.0.2 on Ubuntu

    Using the most recent commit from the GitHub repo and the demo index.html.

    1. Type, "A#" to display two whitelisted suggestions
    2. Use the down arrow on the keyboard to select one of the suggestions
    3. Rather than the selected suggestion being added to the field, the typed letters ("A#") are added

    The behaviour is as expected in Chromium 60 on Ubuntu. The behaviour is expected in both browsers if the mouse is used instead of the keyboard to select one of the suggestions.

    I will look at this myself now but any suggestions welcome.

    Destroy method causes TypeError

    Thanks for making Tagify!

    I'm trying to basically 'reset' tagify fairly often based upon new information grabbed from a database. When I do that, I want to essentially remove all the old tags and start from scratch OR add tags retrieved from the database.

    I saw the new 'destroy' method, which I'm attempting to use like this:

    tagify.destroy();
    When I try that, I get the following error:

    Error in event handler for (unknown): TypeError: Cannot read property 'destroy' of undefined

    However, tagify is definitely defined as I can run the tagify.on('foo') event handlers and it's working very well in all other respects. I imagine I am using the destroy method incorrectly, but I'm not sure how. If someone could please provide an example with real code that would also be very helpful.

    Thanks!

    Jake

    Allow pull request

    Please allow pull request, I added a little feature and want to share it!
    Thanks!

    Only numbers input?

    Hi, I have a question about this ...
    the plugin has option input only numbers?

    how to add other delimiter, because my project need use "," and " " (comma and spacebar) ????

    sincerily
    MMR

    Add limit of tags

    Another (hopefully small) feature what I thought would be nice (for me needed, lol):

    Add possibility to limit the amount of tags.

    So, basically, once you hit a certain amount (for example 4), it won't allow you to add any more tags.

    I hope I am not becoming annoying here :)!

    When you autocomplete from whitelisted list, possibility to add it straight as tag

    Right now when you search from lsit, you have to do double enter to add it into list. It is bad design, when I use whitelist only method and once person chooses from autocomplete list, they cannot change it anyway (will be denied straight away). So it would be good to add setting/option where selection from autocomplete will go straight into the tag list as approved tag.

    Sidenote: Thank you for this up to date tagify. I like it a lot and if those last 2 quality updates will be added, would be cool! Right now there are million of tagify libraries, but this seemed easiest and best one by far.

    Autocomplete/Whitelist behavior on select

    Hi,

    When using autocomplete & whitelist options, if you select an option from the list, it does not add it as a tag. You need to press enter.

    Select
    capture d ecran 2018-02-02 a 18 30 34
    Result
    capture d ecran 2018-02-02 a 18 30 40

    Normal ?

    Any reason why it's not using normal HTML markup?

    I found this from the StackOverflow question, and I think it really is the best plugin for tagging out of the list.

    But why is it not using normal HTML elements? I think that would make this plugin perfect.

    tags color

    Tags color not working when we set background color for parent div or container.

    For example:

    <div style="background-color: black">
        <input type=text id="tg">
    </div>
    
    <script>
        var tag = document.getElementById("tg"),
            tagify1 = new Tagify(tag);
    </script>
    

    Auto release to npm on new git tag

    I have installed tagify from npm and I relaized there is an old version on npm.

    Maybe it would be a good idea to autorelease new git tags into npm

    Feature request: List of matching tags

    May I suggest a new feature: A list of matching tags showing in a list while you type in a tag.

    For example, you type in #j and the list shows 5 available tags containing a "j". Typing #jq and the list is limited to tags containing "jq". User may select one of the matching tags from the list.

    Anway, nice work you did with tagify ๐Ÿ‘

    duplicates option not working !

    hi . i'm try to set duplicates option to false but Still typing duplicates values is enable.
    can you fix this issue please ?

    Ajax

    Please can I use ajax auto complete with this?

    Add destructor

    I don't see a destroy method in this library. Do you have a recommended way of destroying ta tagify-ed element. Or at least removing the tags from it?

    Updated Bower version?

    Would it be possible to tag a new version so that the latest code can be used with Bower? I see that Bower config is on v1.0.5 while NPM is v1.1.0. Looks like the latest version has some improvements we'd like to use.

    Vue usage?

    Can I use this with Vue JS or do I need to use as a Vue component?

    Adding tag programmatically

    Hi

    I know I can add tags when rendering the tagify component, like so:

    <input name='user-tag' value='apple, orange, banana'>

    But in my case, I have a service which returns tags to show, but unfortunately this returns after the tagify component has been rendered. So I would need to add the tags later programmatically, like

    $('[name=user-tag]').Tagify.addTag('kiwi');

    But this is currently not possible. Can this feature of adding tags programmatically be implemented?

    Thanks ๐Ÿ‘

    ID => Value tags

    Hi,

    Can the plugin support an array of key => value as tag ?
    I mean something like that : <tag data-id="1">...</tag>

    I use the plugin with an user system and filtering users with name is not that good.

    Thanks :)

    Bootstrap 4 Support

    How can i use this Plugin / Javscript with Bootstrap 4?
    If i use the Bootstrap 4 Form-Controls i see the input twice. Have a look here

    My HTML-Code looks this:

    <fieldset class="form-group">
    <label for="tags">Tags (Limit 5)</label>
    <input name='tags' placeholder='write some tags' value='foo, bar, buzz' class="form-control">               
    </fieldset>
    

    But when i look into the generated code i see that the input will be transformed to a Element. So there comes the problem that i see the input twice i think.
    How can i use it correctly with bootstrap 4? Can you help me? Or someone else?

    When I remove a tag the input element is deleted

    Hi and thank you for the nice js lib.
    I have run onto a problem;
    When i remove a tag the hidden input element is removed from DOM.
    The bug also happens at your live demo page.
    Please see the following screenshots.
    At the first screenshot I highlight the hidden input before taking any action and at the second screenshot I delete a tag, as you can see the input element is removed.
    before removing tag
    after removing tag

    CSS issues

    Not sure if it's related by bootstrap (since the demo works fine for me) but anyways, here is how the fresh setup looks like:

    image

    background doesn't work at all for tags. Probably caused by the opacity and z-index in the tags tag > div::before.

    When I remove the z-index from it:

    image

    Then in the tags tag > div > span change the opacity to .9 to make it work:

    image

    If you set the opacity to 1 it will not work.

    This is known behaviour when using animations + z-indexing.

    Using latest Opera browser. Doesn't work in Chrome neither.

    Remote content

    Just need to know if the tags can be fetched via ajax

    duplicate setting and event not working

    I am using following code to prevent from getting duplicate values but neither console log is working nor duplicate true setting.

    jQuery(document).ready(function($) {
    		$("#tags").tagify({
    			delimiters: ",",
    			enforeWhitelist: true,
    			autocomplete: true,
    			whitelist: ["foo", "bar", "foo bar"],
    			suggestionsMinChars: 1,
    			duplicates: true,
    		}).on("duplicate", function(e, tagName) {
    			console.log("duplicate" + e + " " + tagName);
    		});
    });
    

    Recommend Projects

    • React photo React

      A declarative, efficient, and flexible JavaScript library for building user interfaces.

    • Vue.js photo Vue.js

      ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

    • Typescript photo Typescript

      TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

    • TensorFlow photo TensorFlow

      An Open Source Machine Learning Framework for Everyone

    • Django photo Django

      The Web framework for perfectionists with deadlines.

    • D3 photo D3

      Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

    Recommend Topics

    • javascript

      JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

    • web

      Some thing interesting about web. New door for the world.

    • server

      A server is a program made to process requests and deliver data to clients.

    • Machine learning

      Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

    • Game

      Some thing interesting about game, make everyone happy.

    Recommend Org

    • Facebook photo Facebook

      We are working to build community through open source technology. NB: members must have two-factor auth.

    • Microsoft photo Microsoft

      Open source projects and samples from Microsoft.

    • Google photo Google

      Google โค๏ธ Open Source for everyone.

    • D3 photo D3

      Data-Driven Documents codes.