-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMPDataTable.js
More file actions
219 lines (212 loc) · 10.7 KB
/
Copy pathMPDataTable.js
File metadata and controls
219 lines (212 loc) · 10.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/**
* Created by Jeroen 2016-2018, Marketplaces ELE. Kolibri Solutions
* General init wrapper script for all datatables, including copy and csv export.
* make sure your table has the class ".datatable"
*/
//global options, so this only works when only one .datatable on the page.
var options; // datatable options. global to preserve on re-init (for responsive change).
var dt; // used to dynamic update the datatable from local code.
/**
* Function to transform all tables with class '.datatable' to a DataTable.
* Features on top of default DataTables:
* - Store/recall sorting/filtering settings in URL to share/bookmark a sorted table
* - Dropdown selects in the table header, for any column supplied in dropdownColumns. (Append a <br /> after the header text)
* - CSV/Copy buttons with datatables.buttons. Customize columns to export using exportColumns
* - Export valid URLs to CSV/Copy by prepending the domain before exporting
* - Add extra buttons with 'extraButtons'
* - Responsive view for small screens
* - Use with normal datatables-options using the customOptions argument
* @param cols array of options for each column. At least a Null array with a null for each column.
* @param dropdownColumns array of column indices. Each column index in this array gets a dropdown select.
* @param exportColumns array of columns, or Column selector. Included columns are used for the export to csv/copy.
* @param extraButtons extra buttons from DataTables.Buttons to include above the table.
* @param customOptions custom DataTables options to extend the default options with.
* @constructor
*/
var MPDataTable = function (cols, dropdownColumns, exportColumns, extraButtons, customOptions) {
//definition of the buttons. All these buttons are overriden (removed) if customOptions['buttons'] is set.
var buttonCommon = {
//function to strip the dropdowns of the headers, to not show the dropdown values in the csv/copy
exportOptions: {
format: {
//modifier for table headers export
header: function (data, row, column, node) {
// get the part of 'data' (the table header) up to the first "<" which is the html start tag.
var i = data.indexOf("<");
if (i !== -1){
return data.substring(0, i);
}else{
return data;
}
},
// modifier for table body export, foreach cell.
body: function (data, row, column, node) {
// non empty cells
if(data) {
//make a domain+URL from the hidden column with the url
if (cols[column] !== null && cols[column]["prependDomain"] === true) {
return window.location.origin + data;
} else {
// put the cell content to jquery object
var obj = $("<div />").html(data);
if (obj[0].firstChild.nodeName === "UL") {
// if the table cell contains a list
//a list of values, get all li's and merge them
var txt = '';
obj.children().children().each(function (d, j) {
txt += (j.innerText.trim() + " + ");
});
return txt.slice(0, -3);
} else {
//normal text, make sure commas are removed.
return obj.text().trim().replace(/;/g, ',');
}
}
}else{
// replace empty cells with a bar.
return '-';
}
}
},
// specify which columns to include for csv/copy export buttons.
// https://datatables.net/extensions/buttons/examples/html5/columns.html
columns: exportColumns
}
};
// https://datatables.net/extensions/buttons/examples/html5/outputFormat-function.html
// the buttons to show above the table. Uses 'buttonCommon' to clean the copy/csv output.
var buttons = [
//first button
$.extend(true, {}, buttonCommon, {
extend: 'copyHtml5'
}),
//second button
$.extend(true, {}, buttonCommon, {
extend: 'csvHtml5',
fieldSeparator: ';'
})
];
//add the optional extrabuttons to the buttons.
buttons.push(extraButtons);
//Default options.
options = {
//default page length
"pageLength": 100,
//order for the dt items to appear
"dom": 'Blfrtip',
//responsive table layout
"responsive": false,
//custom buttons on top of the table
"buttons": buttons,
//function to store settings in uri
"stateSave": true,
"stateSaveCallback": function (settings, data) {
//function to store sorting and filtering in the URI
var store = {
"s": data.start, // start offset (for paging)
"l": data.length, // #entries on one page
"f": encodeURIComponent(data.search.search), // global search/find
"o": btoa(JSON.stringify(data.order[0])) // column to order, asc or desc
};
var s, i;
for (i = 0; i < dropdownColumns.length; i++) { // selected dropdown for columns with dropdown.
s = data.columns[dropdownColumns[i]].search.search;
if (s !== '') {
store[dropdownColumns[i]] = encodeURIComponent(s.slice(1, -1)); //slice to strip the regex chars ^ and $
}
}
//add the stored elements to the URL history
window.history.pushState("", data.time, window.location.pathname + "?" + $.param(store));
},
//custom column options, like disable search
"columns": cols,
//function for the dropdown lists
initComplete: function () {
$(".dt-button").addClass("button"); //style the datatable button
this.api().columns(dropdownColumns).every(function (currentValue) {
var column = this;
var id = "dt-select-dropdown-" + currentValue;
// add a newline to the header, to put dropdowns below header text.
if (column.header().children.length === 0) {
$('<br />').appendTo($(column.header()));
}
// add the dropdowns. Only add if header contains exactly one item ( the <br /> ); only add if not yet added (for reinitialization)
if (column.header().children.length === 1) {
var select = $('<select id=' + id + '><option value=""></option></select>')
.appendTo($(column.header()));
//append the dropdowns, mark them selected if a stored value is applied to the selection
column.data().unique().sort().each(function (d, j) {
//only get the text inside the cell
d = $("<div />").html(d).text().trim();
if (column.search().replace(/\\/g, '') === '^' + d + '$') { //also match on backslash escaped chars
select.append('<option value="' + d + '" selected="selected">' + d + '</option>')
} else {
select.append('<option value="' + d + '">' + d + '</option>')
}
});
}
//Bind events
$("#" + id).on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
//the actual filter on change of the dropdown.
column
.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
});
}
};
//Extends the options that are passed in the argument. When conflicting, the options from the arguments are used.
$.extend(options, customOptions);
// executed on load of the page.
// set custom sort options from url GET params, overrides previously set options.
var i;
options["searchCols"] = [];
//make null array for the dropdowncolumns options
for (i = 0; i < options.columns.length; i++) {
options["searchCols"].push(null);
}
//GET strings, stored in URL.
var vars = window.location.search.substring(1).split("&");
var k, v, a;
for (i = 0; i < vars.length; i++) {
a = vars[i].split("=");
k = a[0]; //key
v = a[1]; //value
if (v !== '') {
v = decodeURIComponent(v);
switch (k) {
case 's': //start offset
options['displayStart'] = v;
break;
case 'l': //length of page (#items)
options['pageLength'] = v;
break;
case 'f': //global search/find string
v = decodeURIComponent(v); //The search string is twice URI encoded.
options['search'] = {'search': v};
break;
case 'o': //which column to order the table as base64 array
options['order'] = [JSON.parse(atob(v))];
break;
default: //custom column filters. Some checks to prevent injections
k = parseFloat(k); //k could be an index of a column to sort with a dropdown.
if (!isNaN(k) && isFinite(k)) {
if (dropdownColumns.indexOf(k) !== -1) { // only if the GET column is a column with dropdown.
v = "^" + decodeURIComponent(v) + "$"; //decode URI. searchstring is URI encoded twice.
options["searchCols"][k] = {'search': v, "regex": true, "smart": false};
}
}
break;
}
}
}
var table = $('.datatable');
dt = table.DataTable(options); //global, because used outside this file.
//do not sort the table when clicking a dropdown select.
$("th>select").click(function () {
return false;
})
};