Lists index.js

Lists are 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.

Override hooks

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.

Examples

Static

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
{% highlight html %}
ID Name
{% endhighlight %}

Custom templates

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.

    {% highlight html %}
      {% endhighlight %}

      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.

      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.

      {% highlight html %} {% endhighlight %}

      Filtering

      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-match attributes, which specify the comma-separated field and the value to match against. If any given field matches the value (using a fairly tolerant, case insensitive match), then the item will be included.

      Static Filters

      {% highlight html %}
      {% endhighlight %}

      Using multiple filters

      Filters are stored internally as a hash keyed by the value of data-filter. This scopes multiple filters on a specific field so that only one is active at any given time. However, you can have filters on multiple fields active at once.

      Setting a custom filter function

      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.

      $("#myIndex").index('setFilter', 'myFilterID', function(item) { ... })

      Dynamic Filters

      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-match value.

      {% highlight html %}
      {% endhighlight %}

      Custom event triggers

      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.

      <input type="text" ... data-trigger="keyup">

      Sorting

      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.

      ID (click me) Name (click me)
      {% highlight html %}
      ID (click me) Name (click me)
      {% endhighlight %}

      Setting a custom sort function

      Internally, when you click on a trigger element, Index.js creates a sort function based on the field specified with data-source and which direction you are sorting in, and saves it as the sort function. You can also set your own sort function by calling .setSort() on the element:

      $("#myIndex").index('setSort', function(a, b) { ... })

      Pagination

      When your list of items gets too long, you'll want to start paginating your data.

      Show first 5 items of a 10 page list:

      {% highlight html %}
      {% endhighlight %}

      Rendering page controls

      It's up to you to render any sort of pagination controls you want to navigate over your list. Use the paginated.adcom.index event described below to retrieve information on page count / current page / etc, and then use the page instance method to update the current page.

      Selection

      Many lists have some concept of selecting one or more items. Index.js handles these cases by giving each item in the index 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.

      {% highlight html %}
      {% endhighlight %}

      Events are triggered when any element is selected or unselected.

      Usage

      The index 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.

      Via data attributes

      Render a list without writing JavaScript. Set data-control="index" on your list container element to trigger it automatically, along with a data-items attribute containing a serialized array of items.

      {% highlight html %}
      {% endhighlight %}

      Via JavaScript

      Render a list by calling .index() on a container element.

      {% highlight js %}$('#myIndex').index(options){% endhighlight %}

      Options

      Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-items="".

      The index container

      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 index. 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 $('#index').data('adcom.index').getFilteredItems, which can be overridden.
      sorting on or off on Turn sorting on. Uses $('#index').data('adcom.index').getSortedItems, which can be overridden.
      pagination on or off off Turn pagination on. Uses $('#index').data('adcom.index').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 active 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.

      Filter triggers

      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.
      match string Value to be compared to the item's attributes. When using the default filter function, this value will be compared using a case-insensitive search, and if it is found anywhere in the item's relevant attributes, it will match.
      trigger string click, change Event that will trigger the filter. Defaults to click for static elements, change for input elements.

      Sort triggers

      Name type default description
      sort string Field to sort by.
      states string ascending,descending,off Comma-separated list of which states to cycle through when toggling the sort. Can specify any combination of ascending, descending, and / or off.

      Methods

      .index(options)

      Activates your content as an index. Accepts an optional options object.

      {% highlight js %} $('#myIndex').index({ pagination: 'off' }) {% endhighlight %}

      .index('show')

      Calculates the list of visible items and renders them into it's container element.

      {% highlight js %}$('#myIndex').index('show'){% endhighlight %}

      .index('page', Integer)

      Manually sets the current page of the list.

      {% highlight js %}$('#myIndex').index('page', 2){% endhighlight %}

      .index('setFilter', key, function)

      Manually sets a filter function to be applied. Can be used multiple times with different keys. Pass undefined as the final argument to remove an existing filter.

      {% highlight js %}$('#myIndex').index('setFilter', function(item) { ... }){% endhighlight %}

      .index('setSort', function)

      Manually sets a sort function. Only one sort function can exist at a time. Pass undefined as the function to remove an existing filter.

      {% highlight js %}$('#myIndex').index('setSort', function(a, b) { ... }){% endhighlight %}

      .index('updateAtIndex', idx, item)

      Replaces the item at index idx with the passed item, and rerenders that element in the container element if it's visible.

      {% highlight js %}$('#myIndex').index('updateAtIndex', 0, {"id": 1}){% endhighlight %}

      Events

      Adcom's index class exposes a few events for hooking into modal functionality.

      Event Type Description
      show.adcom.index This event is fired immediately when the show instance method has been called.
      shown.adcom.index 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.adcom.index This event is fired when the status of an item is about to be updated. The item's rendered element is available as the target property of the event, along with the relevant item and boolean state.
      toggled.adcom.index This event is fired when the status of an item has been updated. The item's rendered element is available as the target property of the event, along with the relevant item and boolean state.
      paginated.adcom.index 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.
      {% highlight js %} $('#myIndex').on('shown.adcom.index', function (e) { // do something... }) {% endhighlight %}