List.js is a convention-based, flexible system for rendering an array of objects as html. While defaults are provided, the HTML used to render the list is largely left up to you. The power of lists comes in a set of actions that can be performed on the list, triggered via data-apis, allowing you to display dynamic lists by writing minimal JavaScript.
Templates can be overridden using either strings with the data-api or a compiled template function using the JavaScript API.
Most other overridable logic occurs in the private .getCurrentItems
method. This method is called to generate a sorted, fitered and paginated list of items to render using the default or your custom template.
It calls the following functions in order if they are turned on, each of which has a default implementation and can be overridden by setting your own function: .getFilteredItems
, .getSortedItems
, .getPaginatedItems
. You can also override .getCurrentItems
entirely to set your own logic while retaining the build-in rendering logic.
A list rendered by specifying the content as serialized JSON in a data attribute. This uses the default template to render each row, which renders a table row for each item with the data for each field specified in data-fields
.
ID | Name |
---|
ID | Name |
---|
The default template will work for simple displays, but you can always override what gets rendered for each item. The only requirement is that the template is wrapped in a single outer element, which is what events and data is bound to.
Note that the template doesn't use a specific rendering engine's syntax for including dynamic attributes in the element. Any element with a data-field
attribute will be populated with the corresponding value using jQuery's .html()
method.
You can also specify the template inline inside the container element using normal HTML. If no template
fields
attributes are specified, then the value of the container's .html()
method will be used as the template.
If you do require a more advanced templating engine, you can specify the source template as a string, and set a second configuration option, templateEngine
, to your template compilation function. Because you are passing a JavaScript function, this must be done using the JavaScript API.
The only requirement of the templateEngine
function is that it accept the raw template as a string, and return a compiled template function that accepts an item to be rendered.
When using existing templating libraries, you can wrap their compilation functions to pass custom settings:
{% highlight js %} $('#myList').list({templateEngine: function(t) { return _.template(t, { ... }) }}); {% endhighlight %}For example, you can set the { variable: "item" }
option when using _.template
to move each item's attributes into a namespace for your template:
Index.js also provides a convention around filtering the list of items before it is rendered, and lets you trigger those filters without JavaScript by using the data-api. Configure the filter using the data-filter
and data-pattern
attributes, which specify the comma-separated field and the value to match against. If any given field matches the value (the default sort function treats the value as case-insensitive regular expression), then the item will be included.
Additionally, you can set your own filtering function by calling .setFilter()
on the element. Your filter function should return true to include the item, false to reject it.
$("#myList").list('setFilter', 'myFilterID', function(item) { ... })
This may be necessary if you want more control over the filtering than the default regular expression match provides.
By attaching a data-filter
trigger to an input element, you can filter based on dynamic user input. Input elements use their .val()
value instead of their data-pattern
value.
Filters are stored internally as a hash keyed by the value of data-filter
. For simplicity, all filters are always applied on top of one another - an item must match every filter to be included.
If you want more complex filtering logic, specify your own filtering function with .list('setFilter, ...')
below.
The table at right shows the active filters at any given moment. The button filters have data-filter="id"
, and the search box has data-filter="id, name"
; they're different, so two filters will be created.
By default, filters are applied when a user clicks on a static trigger, or the value of a user input changes. But you can change the event that Index.js listens for on the given element with a data-trigger
attribute. This lets us update the list more or less frequently, or based on different types of user input (e.g., applying a filter when a form is submitted, versus every time a key is pressed). Not all events are listened to for performance reasons; view the allowed events in List.TRIGGER_EVENTS
.
<input type="text" ... data-trigger="keyup">
Any element can become a trigger for sorting your list of items. Each requires a data-sort
and a data-target
. Include the sort-control
class to render feedback about which sort state is active.
The sort's status is kept track of by the trigger cycling through the sort-ascending
and sort-descending
classes. Include either one to initialize the sort. Only one sort for an Index can be active at a time.
ID (click me) | Name (click me) |
---|
ID (click me) | Name (click me) |
---|
When you click on a trigger element, Index.js creates a sort function based on the field specified with data-source
and the direction you are sorting in, and saves it as the sort function. To provide some sensible defaults, sorting is case-insensitive.
You can also set your own sort function by calling .setSort()
on the element:
$("#myList").list('setSort', function(a, b) { ... })
sort
option when initializing a list in code or through the List's top-level data attributes. As with the toggles above, default sort functions will be created. You can pass multiple fields, separated by commas, and you can choose the sort order by appending either .ascending
(default) or .descending
to the field name. For example: .list({sort: 'name, age.descending'})
.
When your list of items gets too long, you'll want to start paginating your data.
Use the input field to change the current page, and the items displayed at the left should update.
It's up to you to render any sort of pagination controls you want to navigate over your list. Use the paginated.ac.list
event described below to retrieve information on page count / current page / etc, and then use the page
instance method to update the current page.
Many lists have some concept of selecting one or more items. Index.js handles these cases by giving each item in the list a boolean state of true or false. If you render a data-toggle="select"
into a list element, it will serve as a toggle between those two states. Reflect the status by setting a data-selected-class
to apply to 'active' element.
Events are triggered when any element is selected or unselected.
The list plugin centers around an element that has a single array of items attached to it, and knows how to render out that list at any time. You can control the content of the list, and the template it renders with.
Render a list without writing JavaScript. Set data-control="list"
on your list container element to trigger it automatically, along with a data-items
attribute containing a serialized array of items.
Render a list by calling .list()
on a container element.
Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-
, as in data-items=""
.
Name | type | default | description |
---|---|---|---|
items | native or serialized array | Describes the complete set of items that should be rendered. | |
fields | string | Comma-separated list of fields to render as cells in a table row when using the default template | |
template | string, function | table row, use with fields |
Compiled or uncompiled template function used to render each item in the list. Use in conjunction with template-engine if using special syntax. |
template-engine | function | If you want to use a custom templating library. Function that takes a template as a string and returns a function to render that template for a given item. For example, _.template . |
|
filtering | on or off | on | Turn filtering on. Uses $('#list').data('ac.list').getFilteredItems , which can be overridden. |
sorting | on or off | on | Turn sorting on. Uses $('#list').data('ac.list').getSortedItems , which can be overridden. |
pagination | on or off | off | Turn pagination on. Uses $('#list').data('ac.list').getPaginatedItems , which can be overridden. If off, then every visible item will be rendered. |
page-size | integer | 20 | How many pages to display at once when pagination is turned on. |
current-page | integer | 1 | What page to start on when pagination is turned on. |
selected-class | string | Class to apply to 'active' items in the list. | |
states | array of booleans | Default an item's state to on by passing true at its index in the items array. |
|
show | boolean | true | Renders the Index after initialization. |
remote | path | false | If a remote URL is provided, content will be loaded one time via jQuery's .getJSON method and stored as the Index's items . If show is true , list will not be rendered until after content is loaded. You can thus use the original contents of the container element as a loading indicator. |
Name | type | default | description |
---|---|---|---|
filter | string | Comma-separated list of field names against which the filter will be applied. If the filter matches the value of any field, the item will be displayed. | |
pattern | string | Value to be compared to the item's attributes. When using the default filter function, this value will be treated as a case-insensitive regular expression. Note that if you need reserved regex characters to be treated normally, you'll either have to escape them here, or set a custom filter function instead. | |
trigger | string | click, change | Event that will trigger the filter. Defaults to click for static elements, change for input elements. |
Name | type | default | description |
---|---|---|---|
sort | string | Field to sort by. | |
states | string | ascending,descending | Comma-separated list of which states to cycle through when toggling the sort. Can specify any combination of ascending , descending , and / or off . |
Activates your content as a list. Accepts an optional options object
. You may re-initialize the list by calling this method again with an Object, and the new options will be merged into the existing options.
Removes the list and all associated data. Call this before re-instantiating if you wish to start fresh.
{% highlight js %}$('#myList').list('destroy'){% endhighlight %}Calculates the list of visible items and renders them into it's container element.
{% highlight js %}$('#myList').list('show'){% endhighlight %}Changes the state of the items represented by the selector, or at the specified index, to true
. You can also pass an array of indices. Triggers the toggle
events.
Changes the state of the items represented by the selector, or at the specified index, to false
. You can also pass an array of indices. Triggers the toggle
events.
Reverses the state of the items represented by the selector, or at the specified index. You can also pass an array of indices. Triggers the toggle
events.
Adds the passed Object as an item to the list. If you also pass an optional index
, the item will be inserted at that index in the list.
Updates an item in the list, and rerenders that element in the container element. You can specify the item to update by passing either the item's index
, current DOM element
, or the underlying data Object
.
Deletes the item at index index
or represented by the element
.
Deletes an item in the list, and removes that element from the container element. You can specify the item to delete by passing either the item's index
, current DOM element
, or the underlying data Object
.
Manually sets a filter function to be applied. Can be used multiple times with different keys, or in bulk. Pass undefined
as a filter's value to remove an existing filter. Pass a function or a string pattern that will be turned into a standard sort function, based off the key field.
Manually sets a sort function. Only one sort function can exist at a time. Pass undefined
as the function to remove the existing sort function. You may also pass a string, such as "field", which will generate a sort function automatically based on that field. Multiple fields can be separated with commas, and can be reversed by adding a suffix: field.descending
.
Manually sets the current page or page size of the list.
{% highlight js %}$('#myList').list({currentPage: 2}){% endhighlight %}Adcom's list class exposes a few events for hooking into functionality.
Event Type | Description |
---|---|
show.ac.list | This event is fired immediately when the show instance method has been called. |
shown.ac.list | This event is fired when the visible items have been rendered and inserted into the container element. The list of rendered items is available as the items property of the event. |
toggle.ac.list | This event is fired when the status of an item is about to be updated. The item whose state has been updated is available as the item property of the event, along with it's index and updated state . If rendered, the item's element is available as the target property of the event. |
toggled.ac.list | This event is fired when the status of an item has been updated. The item whose state has been updated is available as the item property of the event, along with it's index and updated state . If rendered, the item's element is available as the target property of the event. |
sortChange.ac.list | This event is fired immediately when the setSort instance method has been called. |
sortChanged.ac.list | This event is fired when the sort function for the list has been changed or removed. The new sort function is available as the function property of the event. |
filterChange.ac.list | This event is fired immediately when the setFilter instance method has been called. The key for this filter function is available as the key property of the event. The value of the filter (undefined to delete, string or function) is filter . |
filterChanged.ac.list | This event is fired when one of the filter functions for the list has been changed or removed. The key for this filter function is available as the key property of the event, the value of the filter (undefined to delete, string or function) is filter , and the new filter function is available as function . |
pageChange.ac.list | This event is fired immediately when the setCurrentPage instance method has been called. |
pageChanged.ac.list | This event is fired when the current page has been changed. The new current page is available as the page property of the event. |
paginated.ac.list | This event is fired when the rendered list of items has been paginated in preparation for rendering. Fires before the items have been rendered or inserted into the container element. The current page , number of pages , the count of items, the items , and the start and end positions of the current page are available as properties of the event. |
loaded.ac.list | This event is fired when the list has loaded content using the remote option. |