Updated Feb 24, 2020.
Hi to all,
Here's my gift of the day to the world of Knack users!
Something I wanted for a long time: being able to remove any columns from a table based on my own arbitrary criteria.
The most common use of this would be to remove columns based on the user's roles.
Ex: Remove a column if user roles do not contain 'Admin' or 'Supervisor'.
Or simply hide (but not remove in this case) a column and still benefit from the knack-view-render callback data parameter, where one of the field has some interest in the code but not visually to the user. You should know that if the column is not in the table, you won't get that field from the data parameter.
Here's the code. Just replace the table view and the fields to remove or hide by yours.
Enjoy!
Norm
/////////////////////////////////////////////////////////////////////////////
// Code sample to remove or hide a table's columns based on your own arbitrary criteria
const MY_TABLE_VIEW = 'view_123';
//Need to determine each role by clicking on them in the builder and checking the address bar.
var appRoles = {
'Admin': 'object_16',
'Manager': 'object_17',
'Supervisor': 'object_30',
'Quality Control': 'object_44'
}
//////////////////////////////////////////////////////////////////
$(document).on('knack-view-render.' + MY_TABLE_VIEW, function (event, view, data) {
console.log(data);
var userRolesArray = Knack.getUserAttributes().roles;
console.log('Current User Roles :');
console.log(userRolesArray);
//Only Admin role can see these columns. Hide for all others.
if (!userRolesArray.includes(appRoles['Admin']))
removeTableColumns(view.key, true, ['field_123', 'field_134', 'field_421']);
});
/*//////////////////////////////////////////////////////////////////
Removes or hides any table's columns, including those
with Action, Edit and Delete.
Input parameters:
- view: must be a view.key string, ex: 'view_123'
- remove: true removes elements from DOM, false only hides them. Useful to hide them when you need to access data, but not secure.
- columnsArray: must be an array of 1-based integers, ex: [5, 2, 1] to remove 1st, 2nd and 5th columns. Order MUST be decreasing.
- fieldsArray: must be an array of strings, ex: ['field_456', 'field_789']. Order is not important.
You may use both arrays at same time, but columnsArray has precedence.
*/
//////////////////////////////////////////////////////////////////
function removeTableColumns(view, remove = true, columnsArray = [], fieldsArray = []) {
var header;
var cell;
var column;
if (view === null || view === 'undefined' || ((fieldsArray && fieldsArray.length === 0) && (columnsArray && columnsArray.length === 0))) {
console.log('Called removeTableColumns with invalid parameters.');
return;
}
if (columnsArray && columnsArray.length > 0) {
columnsArray.forEach(function (el) {
//Remove Header
header = $('#' + view + ' > div.kn-table-wrapper > table > thead > tr > th:nth-child(' + el + ')');
if (remove)
header.remove();
else
header.css({ 'display': 'none' });
//Remove each data field
cell = $('#' + view + ' > div.kn-table-wrapper > table > tbody > tr > td:nth-child(' + el + ')');
if (cell.length > 0) {
if (remove)
cell.remove();
else
cell.css({ 'display': 'none' });
}
})
}
if (fieldsArray && fieldsArray.length > 0) {
$("div.kn-table.kn-view." + view + " table.kn-table thead tr th").each(function (index) {
header = $(this)[0].className;
if (fieldsArray.some(function (v) { return header.indexOf(v) >= 0; })) {
if (remove)
$(this).remove(); //Remove header.
else
$(this).css({ 'display': 'none' });
//Remember each columns where cells muse be removed.
column = index + 1;
//Remove each row's data.
$("div.kn-table.kn-view." + view + " table tr:not(.kn-table-group)").each(function () {
cell = $(this).find('td:nth-child(' + column.toString() + ')');
if (cell.length > 0) {
if (remove)
cell.remove(); //Remove cell.
else
cell.css({ 'display': 'none' });
}
})
}
})
}
}