Dataviewer Library
... needs description
What it is
DataViewer is a library that helps manage display for search results. This is most often for tables, but it can display lists as well. Essentially the purpose of this library is to give you one method of interacting with and displaying your data, regardless of source.
What it does
- Execute a search using Kinetic Bridges OR take input from other searches OR it can take input from fields on the screen
- Display search results in a consistent format (DataTable and Unordered Lists included.)
- Easy to implement
- Consistent, reusable configuration driven.
- Commonly used behaviors and functionality included in library's core functionality
- The ability for the developer to insert custom behavior, through callbacks, at several points in the data search, display and selection.
- Field values can be set upon user selection of results
How it helps your implementation
DataViewer is a library which provides a reusable and constant way to build search functionality into a form and display the results. Commonly used behavior is included in the functionality (ie: Set field values in a row or list selection), and results can be displayed as a Table or List. Custom Renderers may also be created to display search results in an alternate format. The library is configuration driven, reducing the need to create JS when creating simple tables from search results.
Install Information
NOTE: dataViewer is included in the default bundle provided by Kinetic Data.
Download
The dataViewer.js can be found on GitHub: https://github.com/KineticCommunity/library-dataviewer-ce
Requirements
- dataViewer.js file
- A JSON Schema to define the Data Viewer Configuration (in the item leveraging dataveiwer)
- There may be additional requirements for Renderers that are used. Ex. the DataTables libraries from datatables.net for the table capability.
Include JavaScript and CSS
The recommended practice for including JavaScript and CSS files, such as dataViewer.js, is to add them to the header of layout.jsp or whatever file is rendering your services. Including files here will ensure the are accessible to all Kinetic Request Forms within the Bundle.
Usage Information
Bridged Resources
For the use cases involving searching, Bridged Resource defines the search and data returned from it. One must be added to the Kinetic Request Form, if planning to use the executeSearch function for dataViewer. The Data Viewer configuration will reference the Bridged Resource which was created.
Configuration
The searching and displaying of data is defined and configured, by the form developer, in a JSON Schema. It contains the necessary information to define the Bridge used by the search, how to render the results and the behavior. This configuration will be passed to dataViewer as a parameter to execute the search.
Multiple configurations can be created and included in a Kinetic Request Form.
Data Viewer Configuration Options are detailed below.
Renderers
There are 2 Renderers included with Data Viewer. The Renderers are part of the Configuration and used to determine how the search results will be displayed. There is also the option to use a custom Renderers to meet any unique requirements.
- DataTable Render
- Unordered List Render
- Custom - A custom function can be created and included in the Configuration to handle the search results.
Execution
Data Viewer provides the following functions
Function | Description |
---|---|
DataViewer.ucFirst(str) | Returns the provided string with the first letter uppercased |
DataViewer.executeSearch(destination, configObj) | Executes the bridge search provided in the config object, the formats the search results as provided in the config object, and displays those results using the renderer in the config object in the destination specified. |
DataViewer.renderFieldValues(destination, configObj) | Adds the values from the fields specified in the configuration into the table/object specified. See image below for example. |
DataViewer.renderResults(destination, configObj) | formats the search results that are in the config object as provided in the config object, and displays those results using the renderer in the config object in the destination specified. |
Example of setup that uses renderFieldValues:
Destination (JQuery Object, JQuery Selector, or function).
Destination defines the location of where the search results (Table or List) are to be appended on the page. The Destination may be supplied as a JQuery Object, JQuery Selector, function. If a function is provided, it must return a JQuery Object. (This is not the resultscontainerId specified in the Configuration but is where this element will be placed on the page.)
Configuration Object (JSON Object)
This is the Data Viewer Configuration Options created above in a JSON Object to define the behavior of the Data Viewer.
Examples:
//JQuery Selector
DataViewer.executeSearch('#Requested_For', searchConfig.personSearchBridgeTable);
//JQuery Object
DataViewer.executeSearch($('#Requested_For'), searchConfig.personSearchBridgeTable);
OR
DataViewer.renderFieldValues($(K('section[Results Section]').element()), searchConfig.personSearchBridgeTable);
//Function
DataViewer.executeSearch(function(){ return $(K('section[Requested For]').element());}, searchConfig.personSearchBridgeTable);
Styling
Custom styling may be applied to the results through the use of CSS. See Renderers for more information.
Configuration Option Details
- resource: (nested JSON schema)
- name:(String) Name of Bridge Resource
- parameters: (Not used)
- data: (Array of 1 or more nested JSON schemas) When using DataTabes column options may be passed through to it. More info at https://datatables.net/reference/option/columns
- name: (String) Name matches to data returned in the results
- title: (String)(Optional) Title is used for display purposes to identify the data to the user
- visible: (Boolean)(Optional) whether the item displays in the result or is hidden, defaults to true
- className: (String)(Optional) HTML class of the values DOM element
- setField:(String)(Optional) A field on the Form to receive the selected value upon click.
- defaultContent: (String) (Optional) A text or HTML string that will be the defaulted value in the displayed results. The value here will appear will all results sets. This can be used when the data to be displayed doesn't come from the search results.
- render: (Function ( data, type, record )) (Optional) Used to modify the value of the data before display. The results returned from this function will be displayed in the results.
- Parameters: data - (String) Contains the individual value for the "data"; type - Advanced use for DataTables Renderer only. (https://datatables.net/reference/option/columns.render); record - (Object) Contains all of the result values.
- renderer: (nested JSON schema)
- type: (Function) A function to render the results of the search. "KDSearch.Renderers.DataTables" and "KDSearch.Renderers.UnorderedList" included with the library. A custom function may also be supplied instead.
- options: (Nested JSON schema) Values supplied here are specific to the Renderer and define the behavior of the Renderer.
- before: (Function)(Optional) A function to execute before the search is performed
- success: (Function)(Optional) A function to execute after the search is performed but before processing the data
- successEmpty: (Function)(Optional) A function to execute after the search is performed when no results are returned
- error: (Function)(Optional) A function to execute when an error is returned from the search
- complete: (Function)(Optional) A function to execute after the search is performed and after the results are processed. Executes after success and error.
- clickCallback: (Function) (Optional) A function to execute when the results are clicked. Returns element click (jQuery Obj), selected results (JSON)
- resultsContainerId: (String) Supply an arbitrary value which will be applied to the DataTable element id when it is created. This value is be applied to the id attribute of the DataTable. Example:
resultsContainerId: 'sampleTable'
will result in:<table id="sampleTable" >
- removeOnClick: (Boolean)(Optional defaulted "true") "true" or "false" value to indicate if the search results should removed from display after a result is clicked.
Note that options not directly used by dataViewer will be passed on, unmodified, to the renderer used. This is particularly useful when other libraries, such as dataTables, are being used for the renderer.
Examples
Below is a configuration would be used with the renderResults function, because it has no bridge information and cannot be used with execute search (unless that is passed in dynamically).
searchConfig.addressTable = {
resource: {
name: ""
},
resultsContainer:
'<table cellspacing="0", border="0", class="table table-striped table-bordered table-condensed dataTable">',
data: [
{
name: null,
orderable: false,
className: "select-checkbox",
defaultContent: "",
width: "30px"
},
{
title: "id",
name: "address.id",
visible: false
},
{
title: "Location Name",
name: "address.siteLocationName",
orderable: true
},
{
title: "GEOLOC Code",
name: "geoloc.code",
visible: true
},
{
title: "Address",
name: "address.streetAddress",
visible: true
},
{
title: "City",
name: "address.city",
visible: true
},
{
title: "State",
name: "address.state.abbreviation",
visible: true
},
{
title: "Zip Code",
name: "address.zipCode",
visible: true
},
{
title: "Country",
name: "address.state.countryId",
visible: true
}
],
resultsContainerId: "address-table",
before: function before(configObj) {},
success: function success(configObj) {},
error: function error(configObj) {},
complete: function complete(configObj) {},
removeOnClick: false,
renderer: {
type: DataViewer.Renderers.DataTables, // Passing a function here allows for better customization
options: {
// Options for Reneder
processSingleResult: true,
// DataTable OPTIONS; Passing options here make it clear that they are being passed to data tables
// responsive: OPTIONAL Default for "BridgeDataTable" is true but can be over written.
responsive: false,
dom: "ftip",
order: [[2, "asc"]],
paging: true,
pageLength: 20,
lengthChange: false,
deferRender: true,
scrollCollapse: true,
select: {},
createdRow: function createdRow(row, data, dataIndex) {},
initComplete: function initComplete() {}
}
}
},
This example does have a bridge config and executed as shown below the configuration:
//put existing, formatted info into the search config
searchConfig.addressTable.response = addrArray;
//render this information
DataViewer.renderResults(function() {
return $(K('content[Addr Table]').element());
}, searchConfig.addressTable);
searchConfig.personTable = {
resource: {
name: 'people by Organization Id'
},
resultsContainer: '<table cellspacing="0", border="0", class="table table-striped table-bordered table-condensed dataTable">',
data: [{
title: 'id',
name: 'id',
visible: false,
}, {
title: 'Title',
name: 'title'
}, {
title: 'Name',
name: 'fullName',
render: function render(data, type, row) {
if (type === "display") {
if (row['IsNew'] && row['IsNew'] !== 'true') {
return data + " <i style='color:purple;' class='fa fa-user' aria-hidden='true'></i>";
} else if (bundle.helpers.nonRefDataExcludeUsers.indexOf(row['userId']) < 0) {
return data + " " + bundle.helpers.createNonRefDataTooltip({
"dateCreated": moment(row['dateCreated']).format('YYYY-MM-DD HH:mm:ss.SSS'),
"dataModified": moment(row['dataModified']).format('YYYY-MM-DD HH:mm:ss.SSS'),
"userFullName": row['userId'],
"userOrg": row['userOrg'],
"userRole": row['userRole']
});
} else {
return data;
}
} else {
return data;
}
}
}, {
title: 'Organization',
name: 'Org',
}, {
title: 'Action',
name: null,
render: function render(data, type, row) {
var buttons = "<div class='action-buttons'><button class='action-button action-button-view btn btn-xs'>View</button> <button class='action-button action-button-remove btn btn-xs'>Remove</button></div>";
return buttons;
}
}],
resultsContainerId: 'person-table',
before: function(configObj) {
$('.message').show();
},
error: function(configObj) {},
complete: function(configObj) {
$('.message').hide();
$(K('content[Person Table]').element()).find('.message').hide();
//repopulate Person Summary that holds the JSON data representing the table.
K('field[Person Summary]').value(JSON.stringify(configObj.tableObj.data().toArray()));
K('field[Person Summary]').trigger('change');
// On View Button
configObj.tableObj.on('click', 'button.action-button-view', function() {
var row = $(this).parents('tr'),
data = configObj.tableObj.row(row).data();
bundle.helpers.personReview(data);
});
// On Remove Button
configObj.tableObj.on('click', 'button.action-button-remove', function() {
var row = $(this).parents('tr'),
data = configObj.tableObj.row(row).data();
configObj.tableObj.row(row).remove().draw();
//repopulate Person Summary that holds the JSON data representing the table.
K('field[Person Summary]').value(JSON.stringify(configObj.tableObj.data().toArray()));
K('field[Person Summary]').trigger('change');
});
},
removeOnClick: false,
renderer: {
type: DataViewer.Renderers.DataTables, // Passing a function here allows for better customization
options: {
// Options for Render
processSingleResult: false,
// DataTable OPTIONS; Passing options here make it clear that they are being passed to data tables
// responsive: OPTIONAL Default for "BridgeDataTable" is true but can be over written.
responsive: false,
dom: 'tip',
order: [
[3, 'asc']
],
paging: false,
scrollY: '60vh',
scrollCollapse: true,
select: {
style: 'single',
selector: 'td:first-child'
},
createdRow: function createdRow(row, data, dataIndex) {
$(row).find('a[name="nonRefData"]').popover({
trigger: 'hover',
container: 'body'
});
},
deferRender: true,
}
}
}
};
Example calls for the above configuration:
DataViewer.executeSearch(function () {
return $(K('content[person Table]').element());
}, searchConfig.personTable);
or this way
searchConfig.personTable.response = pocArray;
DataViewer.renderResults(function () {
return $(K('content[person Table]').element());
}, searchConfig.personTable);
Updated over 3 years ago