2017-05-07 08:05:36 +02:00
|
|
|
import {Feature} from '../feature';
|
|
|
|
import {
|
|
|
|
ignoreCase, numSortAsc, numSortDesc,
|
|
|
|
dateSortAsc, sortNumberStr, sortDateStr
|
|
|
|
} from '../sort';
|
2017-09-07 06:21:40 +02:00
|
|
|
import {isArray, isObj, isEmpty} from '../types';
|
2017-05-09 12:47:05 +02:00
|
|
|
import {NUMBER, FORMATTED_NUMBER, DATE} from '../const';
|
2017-05-07 08:05:36 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Base class for Dropdown and CheckList UI components
|
|
|
|
* @export
|
|
|
|
* @class BaseDropdown
|
|
|
|
* @extends {Feature}
|
|
|
|
*/
|
|
|
|
export class BaseDropdown extends Feature {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an instance of BaseDropdown
|
|
|
|
* @param {TableFilter} tf
|
|
|
|
*/
|
2019-02-15 11:37:30 +01:00
|
|
|
constructor(tf, cls) {
|
|
|
|
super(tf, cls);
|
2017-05-07 08:05:36 +02:00
|
|
|
|
|
|
|
let f = this.config;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Filter options custom sorter on a column basis
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
|
|
|
this.customSorter = isObj(f.filter_options_sorter) &&
|
|
|
|
isArray(f.filter_options_sorter.col) &&
|
|
|
|
isArray(f.filter_options_sorter.comparer) ?
|
2017-06-28 12:47:32 +02:00
|
|
|
f.filter_options_sorter :
|
|
|
|
null;
|
2017-05-07 08:05:36 +02:00
|
|
|
|
2019-02-09 14:27:55 +01:00
|
|
|
// TODO: move here all properties shared by Dropdown and CheckList
|
2017-05-07 08:05:36 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Has custom options
|
|
|
|
* @type {Boolean}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this.isCustom = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* List of options values
|
|
|
|
* @type {Array}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this.opts = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* List of options texts for custom values
|
|
|
|
* @type {Array}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this.optsTxt = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* List of options to be excluded from the checklist filter
|
|
|
|
* @type {Array}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this.excludedOpts = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sort passed options based on the type of the specified column
|
|
|
|
* @param {Number} colIndex Column index
|
|
|
|
* @param {Array} [options=[]] Collection of values
|
|
|
|
* @return {Array} Sorted values
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
sortOptions(colIndex, options = []) {
|
|
|
|
let tf = this.tf;
|
|
|
|
|
|
|
|
if (tf.isCustomOptions(colIndex) || !tf.sortSlc ||
|
|
|
|
(isArray(tf.sortSlc) && tf.sortSlc.indexOf(colIndex) === -1)) {
|
|
|
|
return options;
|
|
|
|
}
|
|
|
|
|
|
|
|
let { caseSensitive, sortNumDesc } = tf;
|
|
|
|
let compareFn;
|
|
|
|
|
|
|
|
if (this.customSorter &&
|
|
|
|
this.customSorter.col.indexOf(colIndex) !== -1) {
|
|
|
|
var idx = this.customSorter.col.indexOf(colIndex);
|
|
|
|
compareFn = this.customSorter.comparer[idx];
|
|
|
|
}
|
|
|
|
else if (tf.hasType(colIndex, [NUMBER, FORMATTED_NUMBER])) {
|
|
|
|
let decimal = tf.getDecimal(colIndex);
|
|
|
|
let comparer = numSortAsc;
|
|
|
|
if (sortNumDesc === true || sortNumDesc.indexOf(colIndex) !== -1) {
|
|
|
|
comparer = numSortDesc;
|
|
|
|
}
|
|
|
|
compareFn = sortNumberStr(comparer, decimal);
|
|
|
|
}
|
2017-05-09 12:47:05 +02:00
|
|
|
else if (tf.hasType(colIndex, [DATE])) {
|
2017-05-07 08:05:36 +02:00
|
|
|
let locale = tf.feature('dateType').getLocale(colIndex);
|
|
|
|
let comparer = dateSortAsc;
|
|
|
|
compareFn = sortDateStr(comparer, locale);
|
|
|
|
} else { // string
|
|
|
|
compareFn = caseSensitive ? undefined : ignoreCase;
|
|
|
|
}
|
|
|
|
|
|
|
|
return options.sort(compareFn);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Regenerate filters of specified columns and maintain selection if any
|
|
|
|
* @param {Array} colIndexes Collection of column indexes
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
refreshFilters(colIndexes) {
|
|
|
|
colIndexes.forEach((colIdx) => {
|
|
|
|
let values = this.getValues(colIdx);
|
|
|
|
this.build(colIdx, this.tf.linkedFilters);
|
|
|
|
this.selectOptions(colIdx, values);
|
|
|
|
});
|
|
|
|
}
|
2017-09-07 06:21:40 +02:00
|
|
|
|
2017-09-08 10:00:03 +02:00
|
|
|
/**
|
|
|
|
* Check passed row contains a valid linked value
|
|
|
|
* @param {Number} rowIdx Row index
|
|
|
|
* @param {Number} activeFilterIdx Current active filter index
|
|
|
|
* @returns {Boolean}
|
|
|
|
*/
|
2017-09-07 06:21:40 +02:00
|
|
|
isValidLinkedValue(rowIdx, activeFilterIdx) {
|
|
|
|
let tf = this.tf;
|
2017-09-08 10:00:03 +02:00
|
|
|
|
2017-09-07 06:21:40 +02:00
|
|
|
if (tf.disableExcludedOptions) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tf.paging) {
|
|
|
|
if (!isEmpty(activeFilterIdx) && tf.isRowValid(rowIdx)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (tf.isRowDisplayed(rowIdx)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2018-09-17 11:32:16 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Refresh linked filters to offer only selected options
|
|
|
|
*/
|
|
|
|
linkFilters() {
|
|
|
|
let tf = this.tf;
|
|
|
|
if (!tf.linkedFilters || !tf.activeFilterId) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.refreshAll();
|
|
|
|
}
|
2017-05-07 08:05:36 +02:00
|
|
|
}
|