The traditional participant view in a LabKey study shows a stacked set of grids for available datasets. In this topic, you will find examples to help you create custom participant views, including a more intuitive tabbed view, presenting data by dataset, sorted by category.
Custom HTML/JavaScript Participant Views
You can override the default participant details view by providing an alternative page either:
Using the User Interface
You can paste new content for the participant details view directly into the server UI using
Customize View on the view page itself. Learn more in this topic:
The
tabbed participant view example below illustrates how to use this method.
Include in a File-based Module
To add the participant details page through a file-based module, place a file named "participant.html" in the views/ directory:
MODULE_NAME
resources
views
participant.html
This option lets you default all studies using that module to use your new view without having to edit the UI in each one. Learn more about file-based modules in this webinar:
For example, this example grabs the ParticipantID from the URL, queries the database for the details about that participant, and builds a custom HTML view/summary of the data with a different appearance than the default. Download this file, rename it "participant.html" and include it in a module to try it out.
Tabbed Participant View Example
Following the
steps below, you can customize the participant view to provide an intuitive tabbed interface for users to browse data.
- The top row of tabs in the view (shown above "Assay/Instrument" and "Clinical") represent the categories of dataset in the study.
- Click a tab to see individual clickable "pills" for each dataset in that category (shown above, "Demographics", "MedicalHistory", and "PhysicalExam" in the "Clinical" category).
- For demographic datasets, where there is a single row per participant, you will see the detailed view of the data for that participant.
- For datasets with multiple rows per participant, you will see the grid filtered to show all rows for the selected participant.
- If a user has permission to add new data, they can also click to Insert New Record in the filtered grid view.
Set Up the Demo
1. To begin, create a new study folder and install the example research study as described in this topic:
2. You can either copy and paste from the
code description of this topic or download this file containing the HTML/JavaScript for the view and be ready to paste the contents into the browser:
3. Install the custom view code:
- Click the Participants tab, then any participant ID.
- Above the existing participant information, click Customize View.
- Select Use customized participant view.
- In place of the default content, paste the contents of the ptidViewer.txt file you downloaded.
- Below the customization area, the current participant view is previewed. Click Save to refresh the preview. Use this to test and refine the participant view using the data for the participant you selected.
- Click Save and Finish when you are happy with the view.
The new participant view now applies to all the participants in the study. When you are viewing data in an ordered list or grid, you will be able to step through them in the new view using 'previous' and 'next' links.
Example Code
The example code contains comments indicating the function of each section, as well as common modifications you might want to make.
<div id="Participant-viewer-ptid-dataset-tab-panel"></div>
<script type="text/javascript" nonce="<%=scriptNonce%>">
// Load required JS dependencies
LABKEY.requiresScript(['Ext4ClientApi'], function() {
var DATASET_PANEL_DIV_ID = 'Participant-viewer-ptid-dataset-tab-panel';
var QWP_COUNTER = 0;
var DEFAULT_DATASET = 'Demographics'; // Change this if there is a different dataset
// you want to start on for a page load.
var selectedDatasetTab;
var categories = [];
var ptidSelection = LABKEY.ActionURL.getParameter('participantId');
var datasetSelection = LABKEY.ActionURL.getParameter('datasetId');
// On page load, query for the set of study datasets and their metadata.
LABKEY.Query.selectRows({
schemaName: 'study',
queryName: 'DataSets',
columns: 'DataSetId,Name,Label,CategoryId,CategoryId/Label,DemographicData',
sort: 'CategoryId/Label,Label', // Sort by category label and then
// dataset label within a category
success: datasetResponse
});
// Callback function for processing the dataset query and intializing the page.
function datasetResponse(data) {
// Keep track of the datasets by their categories so that we can render
// the two level tab panel
var categoryMap = {};
for (var i = 0; i < data.rows.length; i++) {
var row = data.rows[i];
var label = row["CategoryId/Label"];
if (categoryMap[label] === undefined) {
categories.push({label:label, datasets:[]});
categoryMap[label] = categories.length - 1;
}
categories[categoryMap[label]].datasets.push({
id: row.DataSetId,
name: row.Name,
label: row.Label,
isDemographic: row.DemographicData
});
// If there is a datasetId in the URL params, use that for the
// initial tab selection.
if (datasetSelection !== undefined && datasetSelection === row.DataSetId.toString()) {
selectedDatasetTab = row.Name;
}
}
initDatasetTabPanel();
}
// Initializes the outer dataset category tab panel, this will be called once
// on page load.
function initDatasetTabPanel() {
var items = [];
for (var i = 0; i < categories.length; i++) {
var label = categories[i].label || 'Uncategorized';
items.push(getCategoryTabContent(label, categories[i].datasets));
}
// If there is exactly one category (or all datasets are uncategorized),
// don't show the two level tabs but just show that one level of datasets.
if (categories.length === 1) {
items = items[0].items[0].items;
}
Ext4.create('LABKEY.ext4.BootstrapTabPanel', {
renderTo: DATASET_PANEL_DIV_ID,
items: items
});
}
// Generate the per-category tab information and components for each dataset
// in this category.
function getCategoryTabContent(categoryLabel, datasets) {
var items = [];
var active = false;
for (var i = 0; i < datasets.length; i++) {
items.push(getDatasetTabContent(datasets[i]));
active = active || isDatasetActiveTab(datasets[i]);
}
return {
title: categoryLabel,
active: active,
items: [
Ext4.create('LABKEY.ext4.BootstrapTabPanel', {
usePills: true,
items: items,
changeHandler: function(tab) {
selectedDatasetTab = tab.title;
}
})
]
};
}
function isDatasetActiveTab(dataset) {
var active = false;
if (selectedDatasetTab !== undefined) {
if (selectedDatasetTab.toLowerCase() === dataset.name.toLowerCase()) {
active = true;
}
}
else if (DEFAULT_DATASET.toLowerCase() === dataset.name.toLowerCase()) {
active = true;
}
return active;
}
// Generate the per-dataset tab information and components, including the check
// for whether a dataset is marked as isDemographic.
// If so, use the DetailsPanel view instead of the QueryWebPart grid.
function getDatasetTabContent(dataset) {
var divId = 'dataset-qwp-' + QWP_COUNTER++;
var ptidFilterArray = [LABKEY.Filter.create('ParticipantId', ptidSelection)];
return {
title: dataset.label,
active: isDatasetActiveTab(dataset),
items: [{
xtype: 'box',
padding: '20px 0 0 0',
html: '<div id="' + divId + '"></div>',
listeners: {
boxready: function() {
if (ptidSelection && dataset.isDemographic) {
Ext4.create('LABKEY.ext.DetailsPanel', {
renderTo: divId,
border: true,
showTitle: false,
store: {
schemaName: 'study',
queryName: dataset.name,
filterArray: ptidFilterArray
},
showBackBtn: false
});
}
else {
new LABKEY.QueryWebPart({
renderTo: divId,
title: dataset.label,
frame: 'none',
schemaName: 'study',
queryName: dataset.name,
filters: ptidFilterArray,
showInsertNewButton: false,
showImportDataButton: false,
// Add a custom button bar item for an "Insert New Record" button that includes the
// current participant id in the URL as a default value for the dataset insert form.
buttonBar: {
includeStandardButtons: true,
items:[
{
text: 'Insert New Record',
url: LABKEY.ActionURL.buildURL('dataset', 'insert', undefined, {
datasetId: dataset.id,
"default.ParticipantId": ptidSelection,
returnUrl: LABKEY.ActionURL.buildURL('study', 'participant', undefined, {
datasetId: dataset.id,
participantId: ptidSelection
})
})}
]
}
});
}
}
}
}]
};
}
});
</script>
Related Topics