
js.jquery.molgenis.table.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of molgenis-core-ui Show documentation
Show all versions of molgenis-core-ui Show documentation
Spaghetti module containing core plugins and legacy UI components.
/**
* @deprecated Use /molgenis-core-ui/src/main/resources/js/component/Table.js instead
*
* @param $
* @param molgenis
*/
(function($, molgenis) {
"use strict";
var restApi = new molgenis.RestClient();
/**
* @memberOf molgenis.table
*/
function createTable(settings) {
// create elements
var items = [];
items.push('');
items.push('');
items.push(''); /* workaround for IE9 bug https://github.com/molgenis/molgenis/issues/2755 */
if(settings.rowClickable){
items.push('
');
}else{
items.push('
');
}
items.push('');
items.push('');
items.push('');
items.push('');
items.push('');
items.push('');
items.push('');
items.push('');
settings.container.html(items.join(''));
// add data to elements
getTableMetaData(settings, function(attributes, refEntitiesMeta) {
var visibleAttributes = [];
for (var i = 0; i < attributes.length; ++i) {
if(attributes[i].visible) {
visibleAttributes.push(attributes[i]);
}
}
settings.colAttributes = visibleAttributes;
settings.refEntitiesMeta = refEntitiesMeta;
getTableData(settings, function(data) {
createTableHeader(settings);
createTableBody(data, settings);
createTablePager(data, settings);
createTableFooter(data, settings);
});
});
}
/**
* @memberOf molgenis.table
*/
function getTableMetaData(settings, callback) {
if(settings.attributes && settings.attributes.length > 0) {
var colAttributes = molgenis.getAtomicAttributes(settings.attributes, restApi);
// get meta data for referenced entities
var refEntitiesMeta = {};
$.each(colAttributes, function(i, attribute) {
if(attribute.fieldType === 'XREF' || attribute.fieldType === 'MREF' || attribute.fieldType === 'CATEGORICAL' || attribute.fieldType === 'CATEGORICAL_MREF') {
refEntitiesMeta[attribute.refEntity.href] = null;
}
});
var dfds = [];
$.each(refEntitiesMeta, function(entityHref) {
dfds.push($.Deferred(function(dfd) {
restApi.getAsync(entityHref, {'expand' : [ 'attributes' ]}, function(entityMeta) {
refEntitiesMeta[entityHref] = entityMeta;
dfd.resolve();
});
}).promise());
});
// build table after all meta data for referenced entities was loaded
$.when.apply($, dfds).done(function() {
// inject referenced entities meta data in attributes
$.each(colAttributes, function(i, attribute) {
if(attribute.fieldType === 'XREF' || attribute.fieldType === 'MREF' || attribute.fieldType === 'CATEGORICAL' || attribute.fieldType === 'CATEGORICAL_MREF') {
attribute.refEntity = refEntitiesMeta[attribute.refEntity.href];
}
});
callback(colAttributes, refEntitiesMeta);
});
} else {
callback([], {});
}
}
/**
* @memberOf molgenis.table
*/
function getTableData(settings, callback) {
var attributeNames = $.map(settings.colAttributes, function(attribute) {
if(attribute.visible){
return attribute.name;
}
});
var expandAttributeNames = $.map(settings.colAttributes, function(attribute) {
if(attribute.expression){
if(attribute.visible){
return attribute.name;
}
}
if(attribute.fieldType === 'XREF' || attribute.fieldType === 'CATEGORICAL' ||attribute.fieldType === 'MREF' || attribute.fieldType === 'CATEGORICAL_MREF') {
// partially expand reference entities (only request label attribute)
var refEntity = settings.refEntitiesMeta[attribute.refEntity.href];
if(attribute.visible){
return attribute.name;// + '[' + refEntity.labelAttribute + ']';
}
}
return null;
});
// TODO do not construct uri from other uri
var entityCollectionUri = settings.entityMetaData.href.replace("/meta", "");
if(settings.query) {
var q = $.extend({}, settings.query, {'start': settings.start, 'num': settings.maxRows, 'sort': settings.sort});
restApi.getAsync(entityCollectionUri, {'attributes' : attributeNames, 'expand' : expandAttributeNames, 'q' : q}, function(data) {
settings.data = data;
callback(data);
});
} else {
// don't query but use the predefined value
settings.data = settings.value;
callback(settings.value);
}
}
/**
* @memberOf molgenis.table
*/
function calculateNrHeaderRows(attributes) {
var level = 1;
if(attributes) {
var key;
for(key in attributes) {
if (!attributes.hasOwnProperty(key)) continue;
if(typeof attributes[key] === 'object'){
var depth = calculateNrHeaderRows(attributes[key]) + 1;
level = Math.max(depth, level);
}
}
}
return level;
}
/**
* @memberOf molgenis.table
*/
function createTableHeader(settings) {
var container = $('.molgenis-table thead', settings.container);
var items = [];
if (settings.editenabled) {
items.push($('')); // edit row
items.push($(' ')); // delete row
}
// calculate number of header rows
var nrHeaderRows = calculateNrHeaderRows(settings.expandAttributes);
$.each(settings.colAttributes, function(i, attribute) {
if(attribute.visible) {
var expandCollapseControl;
if(attribute.refEntity) {
if(settings.expandAttributes && settings.expandAttributes[attribute.name] !== undefined) {
expandCollapseControl = '';
} else {
expandCollapseControl = '';
}
} else {
expandCollapseControl = '';
}
function createAttributeHeader(attribute, headerClass) {
var header;
if (settings.sort && settings.sort.orders[0].property === attribute.name) {
if (settings.sort.orders[0].direction === 'ASC') {
header = $(' ' + attribute.label + '' + expandCollapseControl + ' ');
} else {
header = $('' + attribute.label + '' + expandCollapseControl + ' ');
}
} else {
header = $('' + attribute.label + '' + expandCollapseControl + ' ');
}
header.data('attr', attribute);
items.push(header);
}
if(settings.expandAttributes && settings.expandAttributes[attribute.name] !== undefined) {
$.each(attribute.refEntity.attributes, function(i, refAttribute) {
createAttributeHeader(refAttribute, 'ref-attr');
});
} else {
createAttributeHeader(attribute);
}
}
});
container.html(items);
}
/**
* @memberOf molgenis.table
*/
function createTableBody(data, settings) {
var container = $('.molgenis-table tbody', settings.container);
var items = [];
var tabindex = 1;
for (var i = 0; i < data.items.length; ++i) {
var entity = data.items[i];
var row = $('').data('entity', entity).data('id', entity.href);
if (settings.editenabled) {
// edit row button
var cell = $('');
$('').appendTo(cell);
row.append(cell);
// delete row button
var cell = $(' ');
$('').appendTo(cell);
row.append(cell);
}
$.each(settings.colAttributes, function(i, attribute) {
function renderAttribute(entity, attribute) {
var cell = $(' ').data('id', entity.href + '/' + encodeURIComponent(attribute.name));
renderCell(cell, entity, attribute, settings);
if(settings.editenabled) {
cell.attr('tabindex', tabindex++);
}
row.append(cell);
}
if(settings.expandAttributes && settings.expandAttributes[attribute.name] !== undefined) {
$.each(attribute.refEntity.attributes, function(i, refAttribute) {
var refEntity = entity[attribute.name];
if(refEntity) {
renderAttribute(entity[attribute.name], refAttribute);
} else {
row.append($(' '));
}
});
} else {
renderAttribute(entity, attribute);
}
});
items.push(row);
}
container.html(items);
$('.show-popover').popover({trigger:'hover', placement: 'bottom', container: 'body'});
}
/**
* @memberOf molgenis.table.cell
*/
function renderCell(cell, entity, attribute, settings) {
if(settings.editenabled && !attribute.readOnly) {
renderEditCell(cell, entity, attribute, settings);
}
else {
renderViewCell(cell, entity, attribute, settings);
}
}
/**
* @memberOf molgenis.table.cell
*/
function renderEditCell(cell, entity, attribute, settings) {
cell.empty();
var value = entity[attribute.name];
switch(attribute.fieldType) {
case 'BOOL':
var items = [];
items.push('');
items.push('');
items.push('');
if(attribute.nillable) {
items.push('');
}
items.push('');
cell.html(items.join(''));
break;
case 'CATEGORICAL':
var refEntityMeta = settings.refEntitiesMeta[attribute.refEntity.href];
// TODO do not construct uri from other uri
var refEntityCollectionUri = attribute.refEntity.href.replace("/meta", "");
var format = function(item) {
if (item) {
return item[refEntityMeta.labelAttribute];
}
};
var opts = {
id: 'href',
allowClear : attribute.nillable ? true : false,
placeholder : ' ', // cannot be an empty string
initSelection: function(element, callback) {
callback(value);
},
query: function (query) {
var num = 25;
var q = {
q : {
start : (query.page - 1) * num,
num : num
}
};
restApi.getAsync(refEntityCollectionUri, q, function(data) {
query.callback({results: data.items, more: data.nextHref ? true : false});
});
},
formatResult: format,
formatSelection: format,
minimumResultsForSearch: -1, // permanently hide the search field
width: '100%'
};
var container = $('');
cell.html(container); // first append container, then create select2
container.select2(opts).select2('val', []); // create select2 and trigger initSelection
break;
case 'DATE':
var datepicker = createInput(attribute, {'style': 'min-width: 100px'}, entity[attribute.name]);
cell.html(datepicker);
break;
case 'DATE_TIME':
var datepicker = createInput(attribute, {'style': 'min-width: 210px'}, entity[attribute.name]);
cell.html(datepicker);
break;
case 'DECIMAL':
case 'INT':
case 'LONG':
var input = createInput(attribute, null, entity[attribute.name]);
input.addClass('number-input');
cell.html(input);
break;
case 'CATEGORICAL_MREF': // TODO render like CATEGORICAL is rendered for XREF
case 'MREF':
var refEntityMeta = settings.refEntitiesMeta[attribute.refEntity.href];
// TODO do not construct uri from other uri
var refEntityCollectionUri = attribute.refEntity.href.replace("/meta", "");
var format = function(item) {
return item[refEntityMeta.labelAttribute];
};
// note: allowClear not possible in combination with multiple select
var opts = {
id: 'href',
multiple: true,
initSelection: function(element, callback) {
callback(value.items);
},
query: function (query) {
var num = 100;
var q = {
q : {
start : (query.page - 1) * num,
num : num,
q : [ {
field : refEntityMeta.labelAttribute,
operator : 'SEARCH',
value : query.term
} ]
}
};
restApi.getAsync(refEntityCollectionUri, q, function(data) {
query.callback({results: data.items, more: data.nextHref ? true : false});
});
},
formatResult: format,
formatSelection: format,
width: '400px' // preserve row height changes by limiting y overflow
};
var container = $('');
cell.html(container); // first append container, then create select2
container.select2(opts).select2('val', []); // create select2 and trigger initSelection
break;
case 'XREF':
var refEntityMeta = settings.refEntitiesMeta[attribute.refEntity.href];
// TODO do not construct uri from other uri
var refEntityCollectionUri = attribute.refEntity.href.replace("/meta", "");
var format = function(item) {
if(item) {
return item[refEntityMeta.labelAttribute];
}
};
var opts = {
id: 'href',
allowClear : attribute.nillable ? true : false,
placeholder : ' ', // cannot be an empty string
initSelection: function(element, callback) {
callback(value);
},
query: function (query) {
var num = 100;
var q = {
q : {
start : (query.page - 1) * num,
num : num,
q : [ {
field : refEntityMeta.labelAttribute,
operator : 'SEARCH',
value : query.term
} ]
}
};
restApi.getAsync(refEntityCollectionUri, q, function(data) {
query.callback({results: data.items, more: data.nextHref ? true : false});
});
},
formatResult: format,
formatSelection: format,
width: '100%'
};
var container = $('');
cell.html(container); // first append container, then create select2
container.select2(opts).select2('val', []); // create select2 and trigger initSelection
break;
default:
var value = entity[attribute.name];
cell.text(value).attr('contenteditable', 'true');
break;
}
}
/**
* @memberOf molgenis.table.cell
*/
function renderViewCell(cell, entity, attribute, settings) {
cell.empty();
var rawValue = entity[attribute.name];
switch(attribute.fieldType) {
case 'XREF':
case 'MREF':
case 'CATEGORICAL':
case 'CATEGORICAL_MREF':
if (undefined === rawValue) {
cell.append(formatTableCellValue(undefined, undefined));
} else {
var refEntity = settings.refEntitiesMeta[attribute.refEntity.href];
var refAttribute = refEntity.labelAttribute;
var refValue = refEntity.attributes[refAttribute];
if (refValue) {
var refAttributeType = refValue.fieldType;
if (refAttributeType === 'XREF' || refAttributeType === 'MREF' || refAttributeType === 'CATEGORICAL' || refAttributeType === 'CATEGORICAL_MREF' || refAttributeType === 'COMPOUND') {
throw 'unsupported field type ' + refAttributeType;
}
switch(attribute.fieldType) {
case 'CATEGORICAL':
case 'XREF':
var $cellValue = $('').append(formatTableCellValue(rawValue[refAttribute], refAttributeType));
$cellValue.click(function(event) {
openRefAttributeModal(attribute, refEntity, refAttribute, rawValue);
event.stopPropagation();
});
cell.append($cellValue);
break;
case 'CATEGORICAL_MREF':
case 'MREF':
if(!rawValue.items.length){
cell.append(formatTableCellValue(undefined, refAttributeType));
}else{
$.each(rawValue.items, function(i, rawValue) {
var $cellValuePart = $('').append(formatTableCellValue(rawValue[refAttribute], refAttributeType));
$cellValuePart.click(function(event) {
openRefAttributeModal(attribute, refEntity, refAttribute, rawValue);
event.stopPropagation();
});
if (i > 0) {cell.append(',');}
cell.append($cellValuePart);
});
}
break;
default:
throw 'unexpected field type ' + attribute.fieldType;
}
}
}
break;
case 'BOOL':
cell.append(formatTableCellValue(rawValue, attribute.fieldType, undefined, attribute.nillable));
break;
default :
cell.append(formatTableCellValue(rawValue, attribute.fieldType));
break;
}
}
/**
* @memberOf molgenis.table
*/
function openRefAttributeModal(attribute, refEntity, refAttribute, refValue) {
// create modal structure
var modal = $('#table-ref-modal');
if(!modal.length) {
var items = [];
items.push('