jAutochecklist is a jQuery plugin that help you to create an user-friendly HTML list which can be used to replace the old tradition select
list
Copyright ©2013 Thanh Trung NGUYEN <flyingangel1987@gmail.com>
Released under MIT License
Not just limited to a simple list like select
, you can make a powerful list out of it
Include this plugin after jQuery. Two following methods are equivalent :
<ul data-name="aList" id="list"> <li data-value="1">Item 1</li> <li data-value="2" data-selected="1">Item 2</li> <li class="group">A group</li> <li class="child">A child</li> <li>Not any child</li> </ul> |
= |
<select name="aList" id="list" multiple> <option value="1">Item 1</option> <option value="2" selected>Item 2</option> <optgroup label="A group"> <option>A child</option> </optgroup> <option>Not any child</option> </select> |
And then with javascript
$('#list').jAutochecklist(); |
It's recommend to use the list ul
method because select
will not support html for its content
Have a cool idea ? See a missing feature ? You can request for its implementation or report an issue here
Default configuration. List multiple by default
<ul id="list"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> $('#list').jAutochecklist();
Size control
$('#list').jAutochecklist({ width: 300, listWidth: 400, listMaxHeight: 100 });
Control popup visibility
$('#ex3').jAutochecklist({ popup: false });
Maximum number of item in popup
$('#ex4').jAutochecklist({ firstItemSelectAll: true, popupMaxItem: 20 });
Control the size of the popup. The popup width will be add (or minus) by this value
$('#ex5').jAutochecklist({ popupSizeDelta: 0 });
Show values instead of text. If no value, text will be used instead
$('#ex6').jAutochecklist({ showValue: true });
Text control
The default text when all items are selected is All
. Set to null
will display text item instead
$('#ex7').jAutochecklist({ textAllSelected: 'All items selected', textEmpty: 'Nothing is selected', textNoResult: 'Found nothing', textSearch: 'Search something here', textMoreItem : 'and {0} more...' //{0} will be replaced by a number });
Working with form. Pre-select a value.
<ul class="jAutochecklist" data-name="myList"> <li data-selected="1" data-value="1">Item 1</li> <li data-value="2">Item 2</li> <li data-value="3">Item 2</li> </ul>
Show checkboxes, though not very useful
$('#ex8').jAutochecklist({ checkbox: true });
Set first item as a SelectAll
$('#ex9').jAutochecklist({ firstItemSelectAll: true });
Switch to single select mode. The list will be automatically close on item click and there is no popup.
Note: for a (single) select
list. The first item is selected automatically by the browser. Which is an unexpected behavior.
A fallback with emtpy value is added. You must not use an empty option as the first item
$('#ex10').jAutochecklist({ multiple: false });
Group support. Using group
and child
class selector and level
to determine the depth
<ul id="list" data-json='{"width":400}'> <li>Item 1</li> <li class="group">A GROUP</li> <li class="child">Item 3</li> <li class="group">ANOTHER GROUP</li> <li class="child">Item 5</li> <li class="group level2">Sub group</li> <li class="child level2">Item 7</li> <li class="child">Item 6</li> <li class="group" data-value="somevalue">A group with value. Will be selected if all chilren are selected</li> <li class="child">A child</li> <li class="child">A child</li> <li class="child">A child</li> <li class="group" data-value="v" data-grouptype="1">Will be selected if at least one child is selected</li> <li class="child">A child</li> <li class="child">A child</li> <li class="child">A child</li> <li class="group" data-value="anothervalue" data-grouptype="2">Group exclusive works independantly from the children</li> <li class="child">Will not be selected if parent selected</li> <li class="child">Will not select parent no matter what</li> <li>Not any child</li> </ul>
Keyboard support: TAB
, Shift
+ up/down
and Enter
to select item. If there is word prediction, pressing TAG
will complete that word
Multi-selection support: Hold mouse on an item and drag to (de)select many items
Dynamic positionning (click for details)
The right corner list will be automatically adjusted. By default, the bottom lists aren't adjusted. You need to activate
dynamicPosition: true
depends on your need.
Event onItemClick
, triggered after an item is clicked. Is is equivalent to html onChange
.
If return false
, the list will be reverted back to previous values
$('#ex15').jAutochecklist({ firstItemSelectAll: true, onItemClick: function(val, li, valBefore, valAfter){ alert('Selected:'+val+'. Before:'+valBefore+'. After:'+valAfter); if (valAfter.length>2) return false; } });
Event onClose
, can be compared with html onBlur
.
If return false
, the list will not be closed
$('#ex16').jAutochecklist({ onClose: function(val){ alert('Selected: ' + val); } });
Config can be overriden by passing a valid JSON string to the html data attribute
data-json='{"aKey":"aValue"}'
(single quote)
data-json={"aKey":"aValue"}
(no quote)
In some rare case, htmlentities encode or escape is needed
<ul id="ex17" data-json='{"width":400}'> <li>Item 1</li> <li>Item 2</li> </ul>
Build list item from JSON
var list = $('#ex18').jAutochecklist(); list.jAutochecklist('buildFromJSON', [ { html: 'Item 1', val: 1, selected: true }, { html: 'Item 2', val: 2 } ]);
What is fallback?
This is without fallback
<input type="checkbox" name="toto" value="1" />
If the checkbox isn't checked. When submit form, it won't be sent to the server. Calling for $_POST["toto"] (php) will throw a notice error
This is fallback
<input type="hidden" name="toto" value="0" /> <input type="checkbox" name="toto" value="1" />
With the input hidden as fallback, whether the checkbox is checked or not. $_POST["toto"] (php) will always contain something, either 0 or 1 in this case. It's convenient if you dont want to check for the existence of the variable everytime
You can activate the fallback support through the property fallback: true
Fetch data from remote source. Only JSON format is accepted.
The following example uses a static JSON source, the remote source must filter the result according to the querying text.
$('#ex20').jAutochecklist({ remote: { source: 'data.json', loadMoreOnScroll: true //default is false } });
Fetching data is originally handled by the plugin, but you can also write your own function by implementing fnQuery
.
When using this method, you have to implement results caching by yourself. When scrolling reach the end of the list, new data will be fetch
according to an offset sent to the remote source to indicate the position of the result.
buildFromJSON
is the core method to build the list
<ul id="ex20"></ul> $('#ex20').jAutochecklist({ remote: { loadMoreOnScroll: true, fnQuery: function(obj, text, offset){ //custome function if no source $.getJSON('data.json', { text: text, offset: offset }, function(json){ //build the list from a VALID json obj.jAutochecklist('buildFromJSON', json, true, offset>0); }); } } });
Example: fetch results from Google. Try to type Chrome
$('#ex21').jAutochecklist({ popup: false, width: 500, remote: { minLength: 3, loadMoreOnScroll: true, fnQuery: function(obj, text, offset){ //custom fetch data function //API deprecated, for more parameter detail, see https://developers.google.com/web-search/docs/#fonje //get JSONP data $.getJSON('http://ajax.googleapis.com/ajax/services/search/web?v=1.0&rsz=8&start='+offset+'&q='+text+'&callback=?', function(data){ var results = data.responseData.results; var json = []; for (var i in results){ var d = results[i]; json.push({ html: '<h4><a href="' + d.url + '" target="_blank">' + d.title + '</a></h4>' + d.content }); } obj.jAutochecklist('buildFromJSON', json, true); }); }, fnPredict: function(val, input){ //custom function for suggestion /* google suggest do not return JSONP data, we must use a proxy In this case, we'll use a php script for example echo file_get_contents($_GET['url']); */ $.getJSON('proxy.php', { url: 'http://google.com/complete/search?output=firefox&q=' + escape(val) }, function(json) { var result; var suggest = json[1]; suggest.sort(); for (var i in suggest){ var text = suggest[i].toLowerCase(); var index = text.indexOf(val); index += val.length; //find the index of the following space character var sp_index = text.indexOf(' ', index); //if reaching the end without space, get all text from starting index result = val + (sp_index===-1 ? text.substr(index) : text.substring(index, sp_index)); if (result !== val){ input.val(result); return; } } }); } } });
width : 200, //width of the wrapper listWidth : null, //width of the list listMaxHeight : null, //max height of the list checkbox : false, //show or hide checkbox dynamicPosition : false, //support dynamic position for list at the bottom of page fallback : false, //fallback support firstItemSelectAll : false, //enable checkall on first item multiple : true, //checkbox or radio showValue : false, //show value instead of text popup : true, //show or hide popup popupLogoAsValue : false, //show logo instead of item value/text popupMaxItem : 10, //maximum number of item on popup popupSizeDelta : 100, //this will add to the popup width textAllSelected : 'All', //text when all selected textEmpty : 'Please select...', //the default text textMoreItem : 'and {0} more...', //text on popup when there are more items, {0} will be replaced by a number textNoResult : 'No result found...', //text no result textSearch : 'Type something...', //the default text selectorGroup : 'group', //the class selector of a group selectorChild : 'child', //the class selector of a child groupType : 0, //global setting of the type of a group //0 => default. The parent item will be selected if all of the children items are selected //1 => The parent item will be selected if at least one child item is selected //2 => The parent item acts independantly from the children items (exclusive) remote : { //fetch data from remote source cache : true, //whether to cache found data (should be disable when loadMoreOnScroll is enable) loadMoreOnScroll: false, //when scroll down, next data will be loaded (will conflict with cache) source : null, //source of data to fetch if fnQuery isn't defined minLength : 1, //the minimum length of the text fnPredict : null, //func(text) custom function that handle suggestion //text = the typing search text fnQuery : null //func(obj, text) custom function that handle query //obj = the current jQuery list object //text = the typing search text }
onClose : function(values) //values=list of selected values onItemClick : function(value, li, valBefore, valAfter) //value = the selected value //li = the selected list item object //valBefore = list of values before selection //valAfter = list of values after selection
//destroy the list and revert back to the original list $('.list').jAutochecklist('destroy'); //select all items $('.list').jAutochecklist('selectAll'); //deselect all items $('.list').jAutochecklist('deselectAll'); //open the list $('.list').jAutochecklist('open'); //close the list $('.list').jAutochecklist('close'); //update the result box basing on the selected element $('.list').jAutochecklist('update'); //count selected item, can only count one instance $('.list').jAutochecklist('count'); //get selected values, can only get value of one instance //return Array $('.list').jAutochecklist('get'); //get all values (including not selected items) //return Array $('.list').jAutochecklist('getAll'); //select a set of values //values: Array of values to set //clearAll: Boolean whether to empty the list before set or not $('.list').jAutochecklist('set', values, clearAll=false); //deselect a set of values //values: Array of values to unset $('.list').jAutochecklist('unset', values); //disable the list $('.list').jAutochecklist('disable'); //enable the list $('.list').jAutochecklist('enable'); //change the current settings with an JSON //some settings can't be changed (for the moment) $('.list').jAutochecklist('settings', json); //build the list items from JSON //json: Array of JSON object in the following format //showNoResult: Boolean whether to show text "No result found" if nothing found //isAdd: Boolean if true, data will be add to the end of the list instead of replacing the current list { html: string //the html content of this item val: sring | int //the value of this item selected: boolean //whether to select the item or not exclusive: boolean, //if exclusive, the group will not be selected when the children are selected isGroup: boolean, //whether this item is a group isChild: boolean, //whether this item is a child of a group level: null | int //the level of group, use when you want to have a subgroup } $('.list').jAutochecklist('buildFromJSON', json, showNoResult=false, isAdd=false);
Check script.js for source
Styling can be done through overwriting the given CSS (do not modify it directly). There are some CSS class that help you to easily create logos. Note that you still have the freedom to style the content as you like
<ul class="jAutochecklist"> <li> <img src="..." class="logo"> Google </li> <li> <img src="..." class="logo"> Yahoo </li> <li> <img src="..." class="logo"> Bing </li> </ul>
If property popupLogoAsValue
is activated, images with class logo
will be shown on popup as values
<ul class="jAutochecklist"> <li> <img src="" class="logo medium"> ... <div class="clear"></div> </li> <li> <img src="" class="logo medium"> ... <div class="clear"></div> </li> <li> <img src="" class="logo medium"> ... <div class="clear"></div> </li> </ul>
With a medium line-height. Text will be vertically centered if there's only one line of text
<ul class="jAutochecklist"> <li class="line-medium"> <img src="" class="logo medium"> Google <div class="clear"></div> </li> <li class="line-medium"> <img src="" class="logo medium"> Yahoo <div class="clear"></div> </li> <li class="line-medium"> <img src="" class="logo medium"> Bing <div class="clear"></div> </li> </ul>
Use class line-large
if there's only one line of text
<ul class="jAutochecklist"> <li> <img src="" class="logo large"> ... <div class="clear"></div> </li> <li> <img src="" class="logo large"> ... <div class="clear"></div> </li> <li> <img src="" class="logo large"> ... <div class="clear"></div> </li> </ul>
Text and logo in seperated columns
<ul class="jAutochecklist"> <li> <div class="float-left"><img src="" class="logo large"></div> <div class="overflow">text...</div> <div class="clear"></div> </li> <li> <div class="float-left"><img src="" class="logo large"></div> <div class="overflow">text...</div> <div class="clear"></div> </li> <li> <div class="float-left"><img src="" class="logo large"></div> <div class="overflow">text...</div> <div class="clear"></div> </li> </ul>