{"id":13992044,"url":"https://github.com/sniperwolf/taggingJS","last_synced_at":"2025-07-22T15:30:59.367Z","repository":{"id":15277679,"uuid":"18007070","full_name":"sniperwolf/taggingJS","owner":"sniperwolf","description":"jQuery plugin to tagging like a charm!","archived":false,"fork":false,"pushed_at":"2017-07-20T18:11:03.000Z","size":637,"stargazers_count":927,"open_issues_count":27,"forks_count":152,"subscribers_count":46,"default_branch":"master","last_synced_at":"2025-06-23T19:07:55.144Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://sniperwolf.github.io/taggingJS/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sniperwolf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-03-22T10:35:49.000Z","updated_at":"2025-06-20T22:06:36.000Z","dependencies_parsed_at":"2022-07-31T02:48:15.541Z","dependency_job_id":null,"html_url":"https://github.com/sniperwolf/taggingJS","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/sniperwolf/taggingJS","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sniperwolf%2FtaggingJS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sniperwolf%2FtaggingJS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sniperwolf%2FtaggingJS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sniperwolf%2FtaggingJS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sniperwolf","download_url":"https://codeload.github.com/sniperwolf/taggingJS/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sniperwolf%2FtaggingJS/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266520605,"owners_count":23942298,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-09T14:01:45.592Z","updated_at":"2025-07-22T15:30:59.035Z","avatar_url":"https://github.com/sniperwolf.png","language":"JavaScript","readme":"# taggingJS #\n\n[![Build Status](https://travis-ci.org/sniperwolf/taggingJS.svg?branch=master)](https://travis-ci.org/sniperwolf/taggingJS)\n\n## jQuery plugin to tagging like a charm! ##\n\n**taggingJS** is a jQuery plugin to create an high customizable front-end tag system.\nIt is like `5 kb` and [support major browsers](#browser-support) in the world!\n\nActual version is [`1.3.3`](https://github.com/sniperwolf/taggingJS/releases/tag/v1.3.3).\n\n![Example Image](example/example_img.png)\n\n## Getting Started ##\n\nYou can find a working example in [Codepen.io](http://codepen.io/sniperwolf/pen/geFxq/)\nor in the project's [GitHub page](http://sniperwolf.github.io/taggingJS/).\n\n### Simplest ###\n\n1. **Download** the `tagging.min.js` file from this repository;\n\n2. **Include** `\u003cscript src=\"path/to/tagging.min.js\"\u003e\u003c/script\u003e` to the bottom of\nyour page;\n\n3. *Optional* - Include the basic CSS tag style\n`\u003clink href=\"tag-basic-style.css\" rel=\"stylesheet\"\u003e` to the `\u003chead\u003e` of\nyour page;\n\n4. **Add** to your page something like\n`\u003cdiv data-tags-input-name=\"tag\" id=\"tagBox\"\u003epreexisting-tag\u003c/div\u003e`;\n\n5. **Add** to your main JavaScript file `$(\"#tagBox\").tagging();`;\n\nThe `data-tags-input-name=\"tag\"` is the `name` attribute used by each input\ninside the `tagBox`.\n\n### Manipulate tags with methods ###\n\nHere there are some **common pattern** to manipulate tags inside the tag box:\n\n**N.B.**: `$tag_box` is the tag box object. To get it:\n\n```js\nvar t, $tag_box;\n\n// We call taggingJS init on all \"#tag\" divs\nt = $( \"#tag\" ).tagging();\n\n// This is the $tag_box object of the first captured div\n$tag_box = t[0];\n```\n\n#### Get all tags (object)\n\n```js\n// To get all tags inside tag box as an array of String\n$tag_box.tagging( \"getTags\" );\n\u003e\u003e\u003e [\"preexisting-tag\", \"another-tag\"]\n\n// To get all tags inside tag box as an array of jQuery Object\n$tag_box.tagging( \"getTagsObj\" );\n\u003e\u003e\u003e [x.fn.x.init[1], x.fn.x.init[1]]\n```\n\n#### Add new tags\n\n```js\n// To add a tag with \"A new tag added via JS\" as text\n$tag_box.tagging( \"add\", \"A new tag added via JS\" );\n\u003e\u003e\u003e true\n\n// To add two tag, one with \"tag 1\" and the other with \"tag 2\" as text\n$tag_box.tagging( \"add\", [\"tag 1\", \"tag 2\"] );\n\u003e\u003e\u003e [\"tag 1\", \"tag 2\"]\n```\n\n#### Remove a tag\n\n```js\n// To remove a tag with text \"A new tag added via JS\" as text\n$tag_box.tagging( \"remove\", \"A new tag added via JS\" );\n\u003e\u003e\u003e $_obj\n\n// To remove two tag, one with \"tag 1\" and the other with \"tag 2\" as text\n$tag_box.tagging( \"remove\", [\"tag 1\", \"tag 2\"] );\n\u003e\u003e\u003e [$_obj]\n\n// Suppose that $tag is the jQuerify object of a tag inside the tag box, you can also do\n$tag_box.tagging( \"remove\", $tag] );\n\u003e\u003e\u003e $_obj\n```\n\n#### Remove all tags\n\n```js\n// To remove all tags\n$tag_box.tagging( \"removeAll\" );\n\n// or\n$tag_box.tagging( \"reset\" );\n```\n\n#### Get Special Keys\n\n```js\n// To get special Keys without distinctions\n$tag_box.tagging( \"getSpecialKeys\" );\n\u003e\u003e\u003e Object {comma: 188, enter: 13, spacebar: 32, del: 46, backspace: 8}\n\n// To get special Keys with distinctions\n$tag_box.tagging( \"getSpecialKeysD\" );\n\u003e\u003e\u003e Object {add: Object, remove: Object}\n```\n\n#### Add or Remove a Special Key\n\n```js\n// To add the \"left arrow\" as a special key to add a new tag\n$tag_box.tagging( \"addSpecialKeys\", [ \"add\", { left_arrow: 37 } ] );\n\n// To add the \"right arrow\" as a special key to remove a tag\n$tag_box.tagging( \"addSpecialKeys\", [ \"remove\", { right_arrow: 39 } ] );\n\n// To remove the \"right arrow\" as a special key\n$tag_box.tagging( \"removeSpecialKeys\", [\"remove\", 39] );\n```\n\n#### Disable taggingJS\n\n```js\n// To disable taggingJS\n$tag_box.tagging( \"destroy\" );\n```\n\n#### Empty the `type_zone`\n\n```js\n// To disable taggingJS\n$tag_box.tagging( \"emptyInput\" );\n```\n\n#### Get or Set the value of `type_zone`\n\n```js\n// To set \"value\" as value of the input\n$tag_box.tagging( \"valInput\", \"value\" );\n\n// To get the value of the input\n$tag_box.tagging( \"valInput\" );\n```\n\n#### Trigger Focus event the `type_zone`\n\n```js\n// To Trigger Focus event the input\n$tag_box.tagging( \"focusInput\" );\n```\n\n#### Detect when a Tag is Added or Removed\n\n```js\n// Execute callback when a tag is added\n$tag_box.on( \"add:after\", function ( el, text, tagging ) {\n  console.log( \"Added tag: \", text );\n});\n\n// Execute callback when a tag is removed\n$tag_box.on( \"remove:after\", function ( el, text, tagging ) {\n  console.log( \"Removed tag: \", text );\n});\n```\n\nPlease, see all [Available Methods](#available-methods).\n\n### Customize ###\n\nThere are **several ways** to customize the default behavior of taggingJS:\n\n1. Use a JavaScript `custom_options` object to customize the global taggingJS behavior\n(see [First Way](#first-way---global-object));\n\n2. Use `data` attributes in the `tagBox` HTML Markup\n(see [Second Way](#second-way---data-attributes));\n\n3. Use a combination of the first two way\n(see [Third Way](#third-way---mixed-way));\n\n**N.B.**: Be careful! `data` attributes have an higher priority than the `custom_options` object,\nbecause each `data` attribute overwrite the global behavior.\nIn other words, the global settings work for all tags box captured, unless in\nthese are specified `data` attributes (*which may change the behavior*).\n\n####  First Way - Global Object ####\n\n1. **Create a custom options** `object`, like this `my_custom_options` (see [Available Options](#available-options)):\n\n\t```js\n\tvar my_custom_options = {\n\t\t\"no-duplicate\": true,\n\t\t\"no-duplicate-callback\": window.alert,\n\t\t\"no-duplicate-text\": \"Duplicate tags\",\n\t\t\"type-zone-class\": \"type-zone\",\n\t\t\"tag-box-class\": \"tagging\",\n\t\t\"forbidden-chars\": [\",\", \".\", \"_\", \"?\"]\n\t};\n\t```\n\n2. **Create a tag box** (or multiple tag box) like this:\n\n\t```html\n\t\u003cdiv id=\"tagBox\"\u003epreexisting-tag\u003c/div\u003e\n\t```\n\n3. **Add** to your main JavaScript file:\n\n\t```js\n\t$(\"#tagBox\").tagging( my_custom_options );\n\t```\n\nIn this way, we customize the **global behavior** of taggingJS for\n**all tag box** caught with selector.\n\n#### Second Way - Data Attributes ####\n\n1. **Create a tag box** with some `data` attributes, like this (see [Available Options](#available-options)):\n\n\t```html\n\t\u003cdiv\n\t\tdata-no-duplicate=\"true\"\n\t\tdata-pre-tags-separator=\"\\n\"\n\t\tdata-no-duplicate-text=\"Duplicate tags\"\n\t\tdata-type-zone-class=\"type-zone\"\n\t\tdata-tag-box-class=\"tagging\"\n\t\tdata-edit-on-delete=\"true\"\n\tid=\"tagBox\"\u003epreexisting-tag\u003c/div\u003e\n\t```\n\n2. **Add** to your main JavaScript file:\n\n\t```js\n\t$(\"#tagBox\").tagging();\n\t```\n\n**N.B.**: Use data method with `no-duplicate-callback` and `forbidden-chars`\ncan cause some problems. Avoid it.\n\n#### Third Way - Mixed Way ####\n\nIn this way, we **mix** data attributes and options object to customize taggingJS behavior for each tag box.\n\n1. **Create a tag box** with some `data` attributes, like this:\n\n\t```html\n\t\u003cdiv class=\"tag-box\"\n\t\tdata-no-duplicate=\"true\"\n\t\tdata-tags-input-name=\"tag\"\n\tid=\"tagBox1\"\u003epreexisting-tag\u003c/div\u003e\n\t```\n\n2. **Create *another* tag box** with no `data` attributes:\n\n\t```html\n\t\u003cdiv id=\"tagBox1\" class=\"tag-box\"\u003epreexisting-tag\u003c/div\u003e\n\t```\n\n3. **Create a custom options** `object`, like this `my_custom_options` (see [Available Options](#available-options)):\n\n\t```js\n\tvar my_custom_options = {\n\t\t\"no-duplicate\": false,\n\t\t\"tags-input-name\": \"taggone\",\n\t\t\"edit-on-delete\": false,\n\t};\n\t```\n\n4. **Add** to your main JavaScript file\n\n\t```js\n\t$(\".tag-box\").tagging( my_custom_options );\n\t```\n\nNow you may see that:\n\n* The `#tagBox1` has a behavior that overwrite some `my_custom_options` options:\n\n\t- Does not accept duplicate tag (*for the respective `data` attribute*);\n\t- For each tag, it has `tag` as input name (*for the respective `data` attribute*);\n\t- On delete, the tag is completely removed (*for the `my_custom_options`*);\n\n* The `#tagBox2` has a behavior dictated only by `my_custom_options`:\n\n\t- Accept duplicate tag (*for the `my_custom_options`*);\n\t- For each tag, it has `tag` as input name (*for the `my_custom_options`*);\n\t- On delete, the tag is completely removed (*for the `my_custom_options`*);\n\n## Available Options ##\n\nBelow there are the **available options to customize taggingJS** with `type`,\na little description and the default value:\n\n| Option | Type | Default | Description |\n| ------ | ---- | ------- | ----------- |\n| **case-sensitive** | `Boolean` | `false` | If `false`, all text is treated like lowercase. |\n| **close-char** | `String` | `\"\u0026times;\"` | Single Tag close character. |\n| **close-class** | `String` | `\"tag-i\"` | Single Tag close class. |\n| **edit-on-delete** | `Boolean` | `true` | `true` to edit tag that has just been removed from tag box. |\n| **forbidden-chars** | `Array` | `[\",\" , \".\", \"_\", \"?\"]` | Array of forbidden characters. |\n| **forbidden-chars-callback** | `Function` | `window.alert` | Function to call when is detected a forbidden character. |\n| **forbidden-chars-text** | `String` | `\"Forbidden character:\"` | Basic text passed to `forbidden-chars-callback`. |\n| **forbidden-words** | `Array` | `[]` | Array of forbidden words. |\n| **forbidden-words-callback** | `Function` | `window.alert` | Function to call when is detected a forbidden words. |\n| **forbidden-words-text** | `String` | `\"Forbidden word:\"` | Basic text passed to `forbidden-words-callback`. |\n| **no-backspace** | `Boolean` | `false` | Backspace key remove last tag by default, `true` to avoid that. |\n| **no-comma** | `Boolean` | `false` | Comma `\",\"` key add a new tag by default, `true` to avoid that. |\n| **no-del** | `Boolean` | `false` | Del key remove last tag by default, `true` to avoid that. |\n| **no-duplicate** | `Boolean` | `true` | If `true`, there will be no duplicate tag's name in the tag box. |\n| **no-duplicate-callback** | `Function` | `window.alert` | Function to call when is detected a duplicate tag. |\n| **no-duplicate-text** | `String` | `\"Duplicate tag:\"` | Basic text passed to `no-duplicate-callback`. |\n| **no-enter** | `Boolean` | `false` | Enter key add a new tag by default, `true` to avoid that. |\n| **no-spacebar** | `Boolean` | `false` | Spacebar key add a new tag by default. `true` to avoid that.|\n| **pre-tags-separator** | `String` | `\", \"` | This is used to `split` the initial text and add `preexistint-tag`. By default, you must put new tags using a comma and a space (`\", \"`). |\n| **tag-box-class** | `String` | `\"tagging\"` | Class of the tag box. |\n| **tag-box-editable-class** | `String` | `\"editable\"` | Class of the tag box when editable, used together with tags-limit option for css targeting. |\n| **tag-char** | `String` | `\"#\"` | Single Tag char. |\n| **tag-class** | `String` | `\"tag\"` | Single Tag class. |\n| **tag-on-blur** | `Boolean` | `true` | If `true`, clicking away from the `$type_zone` will add a new tag. |\n| **tags-input-name** | `String` | `\"tag\"` | Name to use as `name=\"\"` in single tags' input. By default, all tags being passed as array like `tag[]`. |\n| **tags-limit** | `Integer` | `0` | Limit the number of tags that can be added, zero for no limit. |\n| **type-zone-class** | `String` | `\"type-zone\"` | Class of the type-zone. |\n\n## Available Methods ##\n\nBelow there are the **available methods of taggingJS** with a\nlittle description, the argument that it can take and the return `type`:\n\n| Method | Description | Argument | Return |\n| ------ | ----------- | -------- | ------ |\n| **add( `text` or `[text]` )** | Add a new tag. | A `String` (or an `Array` of `String`) to add as tag, if `null` we get the content of tag box `type_zone`. | `Boolean` or `Funtion` |\n| **add:after( `function` )** | Execute the function after add a Tag. | Depends on the `function` used as callback. | `Generic` |\n| **addSpecialKeys( `[ \"type\", obj ]` )** | Add a special keys to add or remove a tag. | `Array` - Where `\"type\"` is `\"add\"` or `\"remove\"`, `obj` is like `{ key_name: key_code }` (it can be also an `Array` of `obj`). | A `String` for error or `Object`  Actually `\"type\"_key` (`add_key` or `remove_key`). |\n| **destroy()** | Remove `type_zone`, all tags and other things. | `void` | `Boolean` |\n| **emptyInput()** | Empty tag box's `type_zone`. | `void` | `$_obj` - The jQuerified `type_zone` itself. |\n| **focusInput()** | Trigger focus on tag box's `type_zone`. | `void` | `$_obj` - The jQuerified `type_zone` itself. |\n| **getDataOptions()** | Get Data attributes custom options. | `void` | `Object` - tag box data attributes custom options. |\n| **getSpecialKeys()** | Return all special keys inside an object (without distinction) | `void` | `Object` - All tags as member of strings. |\n| **getSpecialKeysD()** | Return all special keys inside an object (with distinction) | `void` | An `Object` with an `add` and `remove` properties. |\n| **getTagsObj()** | Return all tags as object | `void` | `Array` - All tags as member of objects. |\n| **init()** | Init method to bootstrap all things | `void` | `$_obj` - The jQuerify tag box. |\n| **refresh( `text` )** | Remove and insert all tag | A `String` with all tags separated by `pre-tags-separator` option value (if `null`, we call `getTags` method) | `Boolean` |\n| **remove( `text` or `$_obj` )** | Remove last tag or the specified ones in tag box's `type_zone`. | A `String` or `$_obj` (or an `Array` of them) of the tag to remove. | A `String` with error message  or `$_obj` of the removed tag. |\n| **remove:after( `function` )** | Execute the function after remove a Tag. | Depends on the `function` used as callback. | `Generic` |\n| **removeAll()** | Alias of reset | `void` | `Array` - All removed tags. |\n| **removeSpecialKeys( `[ \"type\", obj ]` )** | Remove a special key . | `Array` - Where `\"type\"` is `\"add\"` or `\"remove\"`, `obj` is like `{ key_name: key_code }` (it can be also an `Array` of `obj`). | `Object` -  Actually `\"type\"_key` (`add_key` or `remove_key`). |\n| **reset()** | Remove all tags from tag box's `type_zone` | `void` | `Array` - All removed tags. |\n| **valInput( `text` )** | Get or set the tag box `type_zone`'s value | A `String` to put as tag box `type_zone`'s value. | The value `String` or `$_obj` of tag box's `type_zone`. |\n\nYou can find example [here](#manipulate-tags).\n\n## Contribute ##\n\n### Set Up nodeJS and Grunt ###\n\n1. Fork the repository;\n\n2. Open a shell in project's directory;\n\n3. Type `npm install` (make sure you have installed [nodeJS](http://nodejs.org));\n\n4. Type `grunt` to execute the default script (without minification),\n`grunt dist` to also minify the script (make sure you have installed [Grunt](http://gruntjs.com)).\n\n### JavaScript Style Guide ###\n\nI follow the [jQuery's JavaScript style guide](https://contribute.jquery.org/style-guide/js/),\nplease follow it you too :D\n\nAlso take a look to [IdiomaticJS](https://github.com/rwaldron/idiomatic.js/)\n(**Principles of Writing Consistent, Idiomatic JavaScript**).\n\n## Requirements ##\n\n- **jQuery** (`1.5.X` or more, also `2.X` works);\n\n## Browser Support ##\n\nSupports all major browsers in the world (`IE 6+`, `Mozilla Firefox 1+`,\n`Google Chrome 1+`, `Safari 5.1+`).\n\n## License ##\n\n(C) Fabrizio Fallico 2014, released under the [MIT license](LICENSE.md).\n\n## Changelog (v1.3.X) ##\n\n### 1.3.3 - [Oct 24, 2014]\n\n* Now you can add tags clicking away from the `$type_zone` (see [Available Options](#available-options)).\n* Fix [#22](https://github.com/sniperwolf/taggingJS/issues/22), Fix [#24](https://github.com/sniperwolf/taggingJS/issues/24), Fix [#26](https://github.com/sniperwolf/taggingJS/issues/26), Fix [#28](https://github.com/sniperwolf/taggingJS/issues/28) issues.\n\n### 1.3.1 - [Apr 28, 2014]\n\n* Radically changed the architecture of the plugin. Now we are more flexible to changes and pull requests.\n* Added basic methods.\n* Now you can add (and remove) custom special keys to add or remove tags (see [Available Methods](#available-methods)).\n* Fix [#6](https://github.com/sniperwolf/taggingJS/issues/6), [#8](https://github.com/sniperwolf/taggingJS/issues/8), [#16](https://github.com/sniperwolf/taggingJS/issues/16), [#17](https://github.com/sniperwolf/taggingJS/issues/17), [#19](https://github.com/sniperwolf/taggingJS/issues/19) issues.\n","funding_links":[],"categories":["JavaScript","10. 表单处理"],"sub_categories":["10.7 标签插件(Tag) ###","10.8 标签插件(Tag)"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsniperwolf%2FtaggingJS","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsniperwolf%2FtaggingJS","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsniperwolf%2FtaggingJS/lists"}