Little (hopefully) well designed pieces of code I want to share with you.
Tags Manager (a jQuery plugin)
I built this simple plugin while working on an online personal finance tool, I wanted a simple solution to manage tags for each expense users were entering, like in stackoverflow and many other sites.
Best way to understand what it does is to try it, so jump to the demo below:
HTML markup
<input type="text" name="tags" placeholder="Tags" class="tagManager"/>
Javascript
jQuery(".tagManager").tagsManager();
Just play with it.
Tags manager does try to be very humble, if you place an input field in a form, and turn it into a tag manger with the code above, a hidden input field will be added to the form and filled with a comma separated list of the tags the user entered.
When processing the user input on form submit, server side, all you have to do is manage an additional hidden field with name="hiddenTagList".
If you have firebug installed or if you check the source code above in chrome developer tool or explorer developer tool you will see <input type="hidden" value="Pisa,Rome" name="hiddenTagList">
Type some tags in the input field, separate them with comma (or tab).
The code below show how to use an ajax source, and an ajax destination for any added tag:
jQuery(".tagManager").tagsManager({
typeahead: true,
typeaheadAjaxSource: '/ajax/countries',
typeaheadAjaxPolling: true,
AjaxPush: '/ajax/countries/push',
});
Type some tags in the input field, separate them with comma (or tab).
The code below show how to use an ajax source, and an ajax destination for any added tag:
jQuery(".tagManager").tagsManager({
preventSubmitOnEnter: true,
typeahead: true,
typeaheadSource: your_function_here(),
blinkBGColor_1: '#FFFF9C',
blinkBGColor_2: '#CDE69C',
});
The code below show all the configurable options available (so far):
jQuery(".tagManager").tagsManager({
prefilled: ["Pisa", "Rome"],
CapitalizeFirstLetter: true,
preventSubmitOnEnter: true,
typeahead: true,
typeaheadAjaxSource: null,
typeaheadSource: ["Pisa", "Rome", "Milan", "Florence", "New York", "Paris", "Berlin", "London", "Madrid"],
delimeters: [44, 188, 13],
backspace: [8]
blinkBGColor_1: '#FFFF9C',
blinkBGColor_2: '#CDE69C',
hiddenTagListName: 'hiddenTagListA'
});
| prefilled | Either a string of comma separate values or an array, the plugin will render these values as pre-selected tags. |
| CapitalizeFirstLetter | If true all tags the user enter will be converted to lowercase but displaied capitalized. |
| preventSubmitOnEnter | If true when the user hit enter inside the input field (and the input field is part of a <form>), nothing happen (the form is not submitted to the server). |
| typeahead | If true a bootstrap typeahead is setup, typeahead is a nice plugin for bootstrap, when the user start typing something a popup below the input field show possible values matching the typed text. Currently this features is available only if you also include bootstrap, if you are not using it tags manager typeahead won't work. Should be relatively easy to replace typeahead with jQuery UI autocomplete for the ones not using bootstrap, but I didn't. If anyone is really interested I can consider including that in a next releas that. If you choose to use typeahead please check the typeahead specific paramenters in the bootstrap documentation. And in case you don't want browsers autocomplete to mess with your own autocomplete learn to add autocomplete="off" on every Tags Manager input field. |
| typeaheadAjaxSource | If you are a fan of bootstrap typeahead plugin you may love this, is a JSON AJAX source for the list of possible values to display in the typeahead popup. The JSON returned by your serverside code should look like this: {"tags":[{"tag":"Pisa"},{"tag":"Rome"},{"tag":"Milan"},{"tag":"Florence"},{"tag":"New York"},{"tag":"Paris"},{"tag":"Berlin"},{"tag":"London"},{"tag":"Madrid"}]} |
| typeaheadSource | This is passed to standard Bootstrap typeahead source initialization option, so if you don't need an AJAX dynamically generated list you can provide a static one, or you can pass a function(), see typeahead docs for details. Of course in your very function() you can do ajax or whatever you want. |
| typeaheadAjaxPolling | With Bootstrap v2.0 typeahead can request the list of entries to show to an ajax source everytime the user type something in the input field, provide "true" to this option to activate it. Otherwise the ajax source will be queried only at initialization. |
| AjaxPush | Well, since we pull from an ajax source we can also push, don't we? So provide a url as AjaxPush and the added tag will be POSTed. |
| delimeters | If you are not happy with comma separating your tags you can provide your list of delimeters, must be an array of char codes, the ones returned by javascript keyup/keydow/etc... See this table. |
| backspace | When the input field is empty, and some tags are rendered on the left of the input field, and the user hit the backspace the plugin remove the rightest tag (which is the last the user entered). With this option you can provide an array of char codes (like the delimeters above) you want the system to use in place of the backspace (char code 8), or provide an empty array if you don't want this feature at all. |
| blinkBGColor_1 blinkBGColor_2 |
When a duplicate tag is entered the user is notified with a blinking of the corresponding (duplicate) tag, here you can configure the colors. |
| hiddenTagListName | You can define your own personalized name for the hidden tags list field.
PLEASE NOTE if you have multiple instance of tagmanager in a form you SHOULD give a different name to head hidden tags list field! |
| maxTags | Define the maximum number of tags accepted, default is 0 which mean there's no limit and users can add as many tags as they want. |
| validator | Provide a callback to validate the user input, only input field is the entered tag, the callback must return true or false. |
You can pop the last added tag (the rightmost being show)
.tagsManager('popTag');
You can push a new tag
.tagsManager('pushTag','I_am_a_new_tag');
You can remove all tags
.tagsManager('empty');
Just override the styles defined in the .css file.
PLEASE NOTE, if you are not using bootstrap .css you may find out things doesn't look as nice as expected, that's just because you have to adapt the styles to your stylesheets, change the styles!
Before to develop my own tags manager I spent quite a lot of time investigating what other solutions where available, so I think I can spare you some time listing them here and explaining why I developed my own.
The four above are the best around in my opinion, but... I developed Tags Manager. I wanted it to be very simple, I didn't need a pencil mouse pointer when the user hover it. I didn't need inplace edit of the tag, I think it's confusing for the user. I didn't want the tag manager to generate a lot of html in the form.
And I wanted it to be fully integrated with bootstrap and its typeahead.
If you have choosen to go this way and implement a tags system in one of your application you have probably already thought about a couple of things, like the database structure required to store tags.
But just in case... You can find some thoughts about that here.
Check the Tags Manager repository and download the scripts from github