NOTICE: This project is deprecated and no longer maintained. If you'd like to continue supporting a forked version, please reach out on Twitter (@kidjustino) to have it listed here.
A jQuery plugin that adds delight to selecting multiple values for an input.
The recipients field in an email app is a perfect example. You could just offer a plain text input, requiring the user to manually separate each recipient with a comma. Removing a recipient, however, is a pain: the user has to precisely select just the right amount of text, making sure not to accidentally remove too much or too little. As a discerning developer, you know the user experience should be better. And it can be, with Manifest.
Developed by Justin Stayton while at Monk Development.
- Improved user experience. The user no longer has to fumble through manually separating each value, or selecting precisely the right amount of text to remove a value. With Manifest, values can easily be added, selected, and removed via mouse or keyboard.
- Improved developer experience. Why manually parse each value from a single string when Manifest delivers an array with the values ready to be processed?
- Autocomplete functionality. Marco Polo is built-in to provide autocomplete functionality if needed. And it's from the same developer as Manifest, so you can trust in the quality of the code and integration.
- Arbitrary values. Limit selection strictly to the autocomplete results, or allow arbitrary values not returned through autocomplete. Either way, it's a simple configuration option.
- Complete styling control. With straightforward markup that's explained in detail, you can easily style and modify all of the components to fit your needs and aesthetic.
- Callbacks for all major events. Add your own twist when an item is added, removed, selected, highlighted, and more.
- Maintained. You can very much believe that this plugin will remain bug-free and up-to-date. Any feature requests, bug reports, or feedback you submit will be responded to quickly as well.
- Documented. I believe that code is only as useful as its documentation. This manifests itself not only in clear and thorough developer documentation (below), but also verbose documentation within the code itself.
- WAI-ARIA support. Assistive technology users can fully understand and navigate Manifest.
Chosen is a great plugin for jQuery and Prototype that, while similar to Manifest, is different in a number of ways:
- Chosen works with a
<select>
element; Manifest works with a text<input>
. - Chosen searches the pre-defined
<option>
elements; Manifest has built-in autocomplete functionality that requests results from a URL. - Chosen doesn't allow arbitrary, non-
<option>
values to be selected; Manifest does, with or without autocomplete enabled.
Chosen and Manifest were designed for different cases. If you want to make a
<select>
element with a lot of options more user-friendly, use Chosen. If you
can't reasonably list out every possible option (like all users in a system),
or you need to allow arbitrary values (like new tags), use Manifest.
- jQuery >= 1.5
- jQuery UI Widget >= 1.8.21 (included in minified build)
- Marco Polo 1.7.5 (included in minified build)
- All modern browsers, including IE >= 6
Bower is a package manager for the web. Once installed, Bower can install Manifest with a single command:
bower install jquery-manifest
Include both jQuery and Manifest in your HTML:
<script src="jquery.min.js"></script>
<script src="jquery.manifest.min.js"></script>
In most cases, jquery.manifest.min.js
is the best file to include, as it
contains the required libraries and source code in a single minified package.
If Marco Polo is already being
used separately, build/parts/jquery.manifest.min.js
can be included to prevent
duplicate, unnecessary code.
The build
directory contains a number of other files as well:
jquery.manifest.js
contains the required libraries and source code in a single unmifified package.build/parts
contains each individual library and source file in both minified and unminified varieties.
To start, add a text input, if you haven't already:
<input type="text" id="recipients" name="recipients">
Then attach Manifest to the text input in your JavaScript:
$('#recipients').manifest({
marcoPolo: {
url: '/contacts/search',
formatItem: function (data) {
return '"' + data.name + '" (' + data.email + ')';
}
}
});
Notice the marcoPolo
option object.
Marco Polo powers the
autocomplete functionality within Manifest, and the option object allows any of
Marco Polo's options to be configured through Manifest. Be sure to read through
Marco Polo's documentation for how it works and what's possible, including
details on returning results in JSON format from your data source url
. If you
don't require autocomplete functionality, simply set the marcoPolo
option to
false
.
Once you have autocomplete results working through Marco Polo, select a few of
those results for submission. Manifest stores each item value in an array named
after the text input. In the case of this example, the input's name is
recipients
, so the array of values is named recipients_values
. If you dump
the values of this array in PHP ($_POST['recipients_values']
), the results
will look something like this:
Array
(
[0] => "Lindsay Weir" ([email protected])
[1] => "Bill Haverchuck" ([email protected])
[2] => "Daniel Desario" ([email protected])
)
Loop through the array and process each value as necessary.
You should now have enough understanding of Manifest to start configuring it for your specific needs. And when you're ready, consider reading through some of the more advanced guides:
-
marcoPolo object, false
Options to pass on to Marco Polo for autocomplete functionality. Set to false if such functionality is unnecessary.
Default: false
-
required boolean
Whether to only allow items to be selected from the autocomplete results list when autocomplete is enabled. If false, arbitrary, non-results-list values can be added when the separator key character is pressed or the input is blurred.
Default: false
-
separator string, array
One or more key characters or codes to separate arbitrary, non-results-list values if the required option is false. Pressing one of these keys will add the current input value to the list. Also used to split the initial input value and pasted values.
Default: ,
-
values string, object, array
One or more initial values to add to the list.
Default: null
-
valuesName string, null
Name of the hidden input value fields. Do not include [] at the end, as that will be added. If unset, the default is to add _values[] to the input name.
Default: null
-
formatDisplay (data, $item, $mpItem) function
Format the display of an item. The returned value is added to $item with the class mf_item:
<li class="mf_item"> "Lindsay Weir" ([email protected]) … </li>
Default:
if ($mpItem) { return $mpItem.html(); } else { return data; }
Parameters:
- data string, object Item data.
- $item jQuery object List item that will be used for display.
- $mpItem jQuery object, null Optional Marco Polo selected list item.
this: jQuery object Text input (no need to wrap like $(this)).
Return: string, DOM element, or jQuery object to use as the display. A Deferred object can also be returned if an asynchronous process needs to be run that resolves with one of these types later.
-
formatRemove ($remove, $item) function
Format the display of the remove link included with each item. The returned value is added to $remove with the class mf_remove:
<li class="mf_item"> … <a href="#" class="mf_remove" title="Remove">X</a> … </li>
Default:
return 'X';
Parameters:
- $remove jQuery object Remove link.
- $item jQuery object List item that will be added.
this: jQuery object Text input (no need to wrap like $(this)).
Return: string, DOM element, or jQuery object to use as the display. A Deferred object can also be returned if an asynchronous process needs to be run that resolves with one of these types later.
-
formatValue (data, $value, $item, $mpItem) function
Format the hidden value to be submitted for the item. The returned value is set as the value of $value with the class mf_value:
<li class="mf_item"> … <input type="hidden" class="mf_value" value="[email protected]"> </li>
Default:
if ($mpItem) { return $mpItem.text(); } else { return data; }
Parameters:
- data string, object Item data.
- $value jQuery object Hidden value element that will be added.
- $item jQuery object List item that will be added.
- $mpItem jQuery object, null Optional Marco Polo selected list item.
this: jQuery object Text input (no need to wrap like $(this)).
Return: string value. A Deferred object can also be returned if an asynchronous process needs to be run that resolves with a string value later.
-
onAdd (data, $item, initial) function, null
Called when an item is added to the list. Return false to prevent the item from being added, or a Deferred object if an asynchronous process needs to be run that resolves with a boolean value later. If Marco Polo is in use, returning false in
onSelect
will prevent this event from even being fired.Default: null
Parameters:
- data string, object Item data.
- $item jQuery object List item that will be added.
- initial boolean Whether this is an initial value.
this: jQuery object Text input (no need to wrap like $(this)).
Event: You can also bind to the manifestadd event:
$(selector).on('manifestadd', function (event, data, $item, initial) { … });
-
onChange (type, data, $item) function, null
Called when an item is added or removed from the list. Not fired for initial values.
Default: null
Parameters:
- type string Type of change, either "add" or "remove".
- data string, object Item data.
- $item jQuery object List item that will be added.
this: jQuery object Text input (no need to wrap like $(this)).
Event: You can also bind to the manifestchange event:
$(selector).on('manifestchange', function (event, type, data, $item) { … });
-
onHighlight (data, $item) function, null
Called when an item is highlighted via mouseover.
Default: null
Parameters:
- data string, object Item data.
- $item jQuery object List item that's being highlighted.
this: jQuery object Text input (no need to wrap like $(this)).
Event: You can also bind to the manifesthighlight event:
$(selector).on('manifesthighlight', function (event, data, $item) { … });
-
onHighlightRemove (data, $item) function, null
Called when an item is no longer highlighted via mouseover.
Default: null
Parameters:
- data string, object Item data.
- $item jQuery object List item that's no longer highlighted.
this: jQuery object Text input (no need to wrap like $(this)).
Event: You can also bind to the manifesthighlightremove event:
$(selector).on('manifesthighlightremove', function (event, data, $item) { … });
-
onRemove (data, $item) function, null
Called when an item is removed from the list. Return false to prevent the item from being removed.
Default: null
Parameters:
- data string, object Item data.
- $item jQuery object List item that's being removed.
this: jQuery object Text input (no need to wrap like $(this)).
Event: You can also bind to the manifestremove event:
$(selector).on('manifestremove', function (event, data, $item) { … });
-
onSelect (data, $item) function, null
Called when an item is selected through keyboard navigation or click.
Default: null
Parameters:
- data string, object Item data.
- $item jQuery object List item that's being selected.
this: jQuery object Text input (no need to wrap like $(this)).
Event: You can also bind to the manifestselect event:
$(selector).on('manifestselect', function (event, data, $item) { … });
-
onSelectRemove (data, $item) function, null
Called when an item is no longer selected.
Default: null
Parameters:
- data string, object Item data.
- $item jQuery object List item that's no longer selected.
this: jQuery object Text input (no need to wrap like $(this)).
Event: You can also bind to the manifestselectremove event:
$(selector).on('manifestselectremove', function (event, data, $item) { … });
-
add
Add one or more items to the end of the list.
Example:
$('#recipients').manifest('add', { name: 'Lindsay Weir', email: '[email protected]' });
Parameters:
- data string, object, array Item data.
- $mpItem jQuery object, null Optional Marco Polo selected list item.
-
container
Get the container element.
Example:
$('#recipients').manifest('container');
-
destroy
Remove the elements, events, and functionality of this plugin and return the input to its original state.
Example:
$('#recipients').manifest('destroy');
-
list
Get the list element.
Example:
$('#recipients').manifest('list');
-
option
Get or set one or more options.
Example:
Get a specific option:
$('#recipients').manifest('option', 'separator');
Get the entire options object:
$('#recipients').manifest('option');
Set a specific option:
$('#recipients').manifest('option', 'separator', '/');
Set multiple options:
$('#recipients').manifest('option', { separator: '/', onSelect: function (data, $item) { … } });
Parameters:
- nameOrValue string, object Optional options to get or set.
- value mixed Optional option value to set.
-
remove
Remove one or more list items, specifying either jQuery objects or a selector that matches list children.
Example:
$('#recipients').manifest('remove', ':last');
Parameters:
- selector jQuery object, selector Specific jQuery list item object or any selector accepted by .children().
-
values
Get an array of the current values.
Example:
$('#recipients').manifest('values');
Please open an issue to request a feature or submit a bug report. Or even if you just want to provide some feedback, I'd love to hear. I'm also available on Twitter as @kidjustino.
- Fork it.
- Create your feature branch (
git checkout -b my-new-feature
). - Commit your changes (
git commit -am 'Added some feature'
). - Push to the branch (
git push origin my-new-feature
). - Create a new Pull Request.