Audienti's DataTables are built on top of the DataTables.js the Table library for Javascript, with three primary extensions installed: select (so that a selected is added to the row), buttons (to enable buttons on the tables), and checkboxes (enables the multi-select, storing across pages, and remembering on a page refresh).
The base class for an AudientiDataTable is in the javascripts/app/datatables.coffee class. This sets the default actions. Then, on your JS file for your view, you instantiate this with options passed to it to setup the specific dataTable.
Backing a datatable is a class that handles creating the data in the requested format. This should be placed in the app/datatables folder. Note that this is a cyild class of ApplicationDatatable that does the majority of the work. Please review the KeywordsDatatable for an example of this code.
class KeywordDatatable < ApplicationDatatable
# The base on which all queries (for counts and records) are made. Scoping
# should occur here to limit things to just the data you actually want. Most
# of the time, this will be to your current_project.
def root_query
current_project.keywords
end
# This is expected to return an array with hashes that have the fields
# we are tracking in them. You can do your queries dynamically, and add
# additional other attributes here, and as long as the query isn't too
# bad it should be OK.. as we'll be at most dealing with only 100 records.
#
# The DT_RowId will be passed as the id of the tr.
# The DT_RowData, in theory, should be adding a data attribute on the
# tr generated from this data.
def data
records.map do |record|
{
'checkbox' => record.id,
'name' => record.name,
'created_at' => record.created_at,
'DT_RowId' => "keyword_#{record.id}",
'DT_RowData' => { 'id' => record.id }
}
end
end
# Columns listed here will not be searched. Any DateTime should not
# be included in this, as it will cause the saerch function to error with
# a request for its timezone.
def skip_search_columns
%w(checkbox created_at)
end
# THe columns that are used in the app. These will be iterated over
# for the search functions to generate the search string.
def columns
%w(checkbox name created_at)
end
end
The controller takes this information, and if it's from a JS it calls this. The format.json will call to_json on the class, and this is how it gets rendered.
class KeywordsController < SecuredApplicationController
def index
datatable = KeywordDatatable.new(view_context, current_user: current_user,
current_project: current_project)
@total = datatable.count
respond_to do |format|
format.html
format.json { render json: datatable }
end
end
def create
factory = KeywordFactory.new(params: params, project: current_project)
factory.call
flash[:notice] = 'Keywords were updated.'
redirect_to request.referrer || project_keywords_path(current_project)
end
end
Configuring the DataTable in Javascript is very straightforward.
Note that this uses the page-specific JS model that the application uses. Please review this if you have questions about the base @KeywordsIndex class.
In the constructor which is called on the page, load, we instantiate the datatable, using teh selector defined for the page (#keywords-table). in addition, the AudientiTable expects a hash of options. At a minimum, this must contain the columns definition. It should match the names in your KeywordsDatatable. In addition, it can include things such as the buttons that will be on the top of the table and perform actions. This is passed to DataTables natively, so anything that you want that is a datatabels capability can be passed in through this hash.
Once you have what you want, you return it as a hash/object. The table. makes it so that the table is available in Javascript at App.page.items.table.
Special Circumstances
Handling HTML content. Sometimes, you'll need to have complex data in a table. Not a problem. The DataTable class can handle this and will render the content for you.
Modify the column defintion to HTML, then in the data dlement that you return, reutrn the HTML.