From 360458f5748101b51acdf6ecf66295eb0312c6d5 Mon Sep 17 00:00:00 2001 From: Peter Pfeufer Date: Tue, 12 Jul 2022 18:22:49 +0200 Subject: [PATCH] Update with latest version --- .../js/filterDropDown/filterDropDown.js | 239 ++++++++++++++++++ .../js/filterDropDown/filterDropDown.min.js | 2 +- 2 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 allianceauth/static/allianceauth/js/filterDropDown/filterDropDown.js diff --git a/allianceauth/static/allianceauth/js/filterDropDown/filterDropDown.js b/allianceauth/static/allianceauth/js/filterDropDown/filterDropDown.js new file mode 100644 index 00000000..c01ca649 --- /dev/null +++ b/allianceauth/static/allianceauth/js/filterDropDown/filterDropDown.js @@ -0,0 +1,239 @@ +/* + * filterDropDown.js + * + * Copyright (C) 2017-18 Erik Kalkoken + * + * Extension for the jQuery plug-in DataTables (developed and tested with v1.10.15) + * + * Version 0.4.0 + * +**/ + +(function ($) { + + // parse initialization array and returns filterDef array to faster and easy use + // also sets defaults for properties that are not set + function parseInitArray(initArray) { + // initialization and setting defaults + let filterDef = { + "columns": [], + "columnsIdxList": [], + "bootstrap": false, + "autoSize": true, + "ajax": null, + "label": "Filter " + }; + + // set filter properties if they have been defined + // otherwise the defaults will be used + if (("bootstrap" in initArray) && (typeof initArray.bootstrap === 'boolean')) { + filterDef.bootstrap = initArray.bootstrap; + } + + if (("autoSize" in initArray) && (typeof initArray.autoSize === 'boolean')) { + filterDef.autoSize = initArray.autoSize; + } + + if (("ajax" in initArray) && (typeof initArray.ajax === 'string')) { + filterDef.ajax = initArray.ajax; + } + + if (("label" in initArray) && (typeof initArray.label === 'string')) { + filterDef.label = initArray.label; + } + + // add definition for each column + if ("columns" in initArray) { + initArray.columns.forEach(function (initColumn) { + if (("idx" in initColumn) && (typeof initColumn.idx === 'number')) { + // initialize column + let idx = initColumn.idx; + filterDef['columns'][idx] = { + "title": null, + "maxWidth": null, + "autoSize": true + }; + + // add to list of indices in same order they appear in the init array + filterDef['columnsIdxList'].push(idx); + + // set column properties if they have been defined + // otherwise the defaults will be used + if (('title' in initColumn) + && (typeof initColumn.title === 'string') + ) { + filterDef['columns'][idx].title = initColumn.title; + } + + if (('maxWidth' in initColumn) + && (typeof initColumn.maxWidth === 'string') + ) { + filterDef['columns'][idx].maxWidth = initColumn.maxWidth; + } + + if (('autoSize' in initColumn) + && (typeof initColumn.autoSize === 'boolean') + ) { + filterDef['columns'][idx].autoSize = initColumn.autoSize; + } + } + }); + } + return filterDef; + } + + // Add option d to given select object + function addOption(select, d) { + if (d != "") { + select.append(''); + } + } + + // initalizing select for current column and applying event to react to changes + function initSelectForColumn(id, column) { + let select = $("#" + id + "_filterSelect" + column.index()); + select.on('change', function () { + let val = $.fn.dataTable.util.escapeRegex($(this).val()); + column + .search(val ? '^' + val + '$' : '', true, false) + .draw(); + }); + return select + } + + // Add filterDropDown container div, draw select elements with default options + // use preInit so that elements are created and correctly shown before data is loaded + $(document).on('preInit.dt', function (e, settings) { + if (e.namespace !== 'dt') return; + + // get api object for current dt table + var api = new $.fn.dataTable.Api(settings); + + // get id of current table + var id = api.table().node().id; + + // get initialization object for current table to retrieve custom settings + var initObj = api.init(); + + // only proceed if filter has been defined in current table, otherwise don't do anything. + if (!("filterDropDown" in initObj)) return; + + // get current filter definition from init array + var filterDef = parseInitArray(initObj.filterDropDown); + + // only proceed if there are any columns defined + if (filterDef.columns.length == 0) return; + + // get container div for current data table to add new elements to + var container = api.table().container(); + + // add filter elements to DOM + var filterWrapperId = id + "_filterWrapper"; + var divCssClass = filterWrapperId + " " + ( + (filterDef.bootstrap) + ? "form-inline" + : "" + ); + $(container).prepend( + '
' + + filterDef.label + + '
' + ); + + api.columns(filterDef.columnsIdxList).every(function () { + let idx = this.index(); + + // set title of current column + let colName = (filterDef.columns[idx].title !== null) + ? filterDef.columns[idx].title + : $(this.header()).html(); + + if (colName == "") colName = 'column ' + (idx + 1); + + // adding select element for current column to container + let selectId = id + "_filterSelect" + idx; + $('#' + filterWrapperId).append( + '' + ); + + // initalizing select for current column and applying event to react to changes + let select = $("#" + selectId).empty() + .append(''); + + // set max width of select elements to current width (which is defined by the size of the title) + // turn off on for very small screens for responsive design or if autoSize has been set to false + if (filterDef.autoSize && filterDef.columns[idx].autoSize && (screen.width > 768)) { + select.css('max-width', select.outerWidth()); + } + + // apply optional css style if defined in init array + // will override automatic max width setting + if (filterDef.columns[idx].maxWidth !== null) { + select.css('max-width', filterDef.columns[idx].maxWidth); + } + }); + + }); + + // filter table and add available options to dropDowns + $(document).on('init.dt', function (e, settings) { + if (e.namespace !== 'dt') return; + + // get api object for current dt table + var api = new $.fn.dataTable.Api(settings); + + // get id of current table + var id = api.table().node().id; + + // get initialization object for current table to retrieve custom settings + var initObj = api.init(); + + // only proceed if filter has been defined in current table, otherwise don't do anything. + if (!("filterDropDown" in initObj)) return; + + // get current filter definition + var filterDef = parseInitArray(initObj.filterDropDown); + + if (filterDef.ajax == null) { + api.columns(filterDef.columnsIdxList).every(function () { + let column = this + let select = initSelectForColumn(id, column); + column.data().unique().sort().each(function (d) { + addOption(select, d) + }); + }); + } else { + // fetch column options from server for server side processing + let columnsQuery = ( + "columns=" + + encodeURIComponent( + api.columns(filterDef.columnsIdxList).dataSrc().join() + ) + ) + $.getJSON(filterDef.ajax + "?" + columnsQuery, function (columnsOptions) { + api.columns(filterDef.columnsIdxList).every(function () { + let column = this; + let select = initSelectForColumn(id, column); + let columnName = column.dataSrc() + if (columnName in columnsOptions) { + columnsOptions[columnName].forEach(function (d) { + addOption(select, d) + }); + } else { + console.warn( + "Missing column '" + columnName + "' in ajax response." + ) + } + }); + }); + } + }); + +}(jQuery)); diff --git a/allianceauth/static/allianceauth/js/filterDropDown/filterDropDown.min.js b/allianceauth/static/allianceauth/js/filterDropDown/filterDropDown.min.js index d19686ff..f4ac8527 100644 --- a/allianceauth/static/allianceauth/js/filterDropDown/filterDropDown.min.js +++ b/allianceauth/static/allianceauth/js/filterDropDown/filterDropDown.min.js @@ -1 +1 @@ -!function(t){function e(t){var e={columns:[],columnsIdxList:[],bootstrap:!1,autoSize:!0,label:"Filter "};if("bootstrap"in t&&"boolean"==typeof t.bootstrap&&(e.bootstrap=t.bootstrap),"autoSize"in t&&"boolean"==typeof t.autoSize&&(e.autoSize=t.autoSize),"label"in t&&"string"==typeof t.label&&(e.label=t.label),"columns"in t)for(var i=0;i'+r.label+""),o.columns(r.columnsIdxList).every(function(){var e=this.index(),i=null!==r.columns[e].title?r.columns[e].title:t(this.header()).html();""==i&&(i="column "+(e+1));var n="form-control "+a+"_filterSelect",o=a+"_filterSelect"+e;t("#"+s).append('');var l=t("#"+o).empty().append('");r.autoSize&&r.columns[e].autoSize&&screen.width>768&&l.css("max-width",l.outerWidth()),null!==r.columns[e].maxWidth&&l.css("max-width",r.columns[e].maxWidth)})}}}}),t(document).on("init.dt",function(i,n){if("dt"===i.namespace){var o=new t.fn.dataTable.Api(n),a=o.table().node().id,l=o.init();if("filterDropDown"in l){var r=e(l.filterDropDown);o.table().container();o.columns(r.columnsIdxList).every(function(){var e=this,i=e.index(),n=t("#"+(a+"_filterSelect"+i));n.on("change",function(){var i=t.fn.dataTable.util.escapeRegex(t(this).val());e.search(i?"^"+i+"$":"",!0,!1).draw()}),e.data().unique().sort().each(function(t,e){""!=t&&n.append('")})})}}})}(jQuery); \ No newline at end of file +!function(t){function n(t){let n={columns:[],columnsIdxList:[],bootstrap:!1,autoSize:!0,ajax:null,label:"Filter "};return"bootstrap"in t&&"boolean"==typeof t.bootstrap&&(n.bootstrap=t.bootstrap),"autoSize"in t&&"boolean"==typeof t.autoSize&&(n.autoSize=t.autoSize),"ajax"in t&&"string"==typeof t.ajax&&(n.ajax=t.ajax),"label"in t&&"string"==typeof t.label&&(n.label=t.label),"columns"in t&&t.columns.forEach(function(t){if("idx"in t&&"number"==typeof t.idx){let e=t.idx;n.columns[e]={title:null,maxWidth:null,autoSize:!0},n.columnsIdxList.push(e),"title"in t&&"string"==typeof t.title&&(n.columns[e].title=t.title),"maxWidth"in t&&"string"==typeof t.maxWidth&&(n.columns[e].maxWidth=t.maxWidth),"autoSize"in t&&"boolean"==typeof t.autoSize&&(n.columns[e].autoSize=t.autoSize)}}),n}function e(t,n){""!=n&&t.append('")}function i(n,e){let i=t("#"+n+"_filterSelect"+e.index());return i.on("change",function(){let n=t.fn.dataTable.util.escapeRegex(t(this).val());e.search(n?"^"+n+"$":"",!0,!1).draw()}),i}t(document).on("preInit.dt",function(e,i){if("dt"===e.namespace){var o=new t.fn.dataTable.Api(i),l=o.table().node().id,a=o.init();if("filterDropDown"in a){var u=n(a.filterDropDown);if(0!=u.columns.length){var s=o.table().container(),c=l+"_filterWrapper",r=c+" "+(u.bootstrap?"form-inline":"");t(s).prepend('
'+u.label+"
"),o.columns(u.columnsIdxList).every(function(){let n=this.index(),e=null!==u.columns[n].title?u.columns[n].title:t(this.header()).html();""==e&&(e="column "+(n+1));let i=l+"_filterSelect"+n;t("#"+c).append('');let o=t("#"+i).empty().append('");u.autoSize&&u.columns[n].autoSize&&screen.width>768&&o.css("max-width",o.outerWidth()),null!==u.columns[n].maxWidth&&o.css("max-width",u.columns[n].maxWidth)})}}}}),t(document).on("init.dt",function(o,l){if("dt"===o.namespace){var a=new t.fn.dataTable.Api(l),u=a.table().node().id,s=a.init();if("filterDropDown"in s){var c=n(s.filterDropDown);if(null==c.ajax)a.columns(c.columnsIdxList).every(function(){let t=i(u,this);this.data().unique().sort().each(function(n){e(t,n)})});else{let n="columns="+encodeURIComponent(a.columns(c.columnsIdxList).dataSrc().join());t.getJSON(c.ajax+"?"+n,function(t){a.columns(c.columnsIdxList).every(function(){let n=i(u,this),o=this.dataSrc();o in t?t[o].forEach(function(t){e(n,t)}):console.warn("Missing column '"+o+"' in ajax response.")})})}}}})}(jQuery); \ No newline at end of file