1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | const Utils = $.fn.bootstrapTable.utils
|
10 |
|
11 | const theme = {
|
12 | bootstrap3: {
|
13 | icons: {
|
14 | advancedSearchIcon: 'glyphicon-chevron-down'
|
15 | },
|
16 | classes: {},
|
17 | html: {
|
18 | modal: `
|
19 | <div id="avdSearchModal_%s" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
|
20 | <div class="modal-dialog modal-xs">
|
21 | <div class="modal-content">
|
22 | <div class="modal-header">
|
23 | <button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
24 | <span aria-hidden="true">×</span>
|
25 | </button>
|
26 | <h4 class="modal-title">%s</h4>
|
27 | </div>
|
28 | <div class="modal-body modal-body-custom">
|
29 | <div class="container-fluid" id="avdSearchModalContent_%s"
|
30 | style="padding-right: 0px; padding-left: 0px;" >
|
31 | </div>
|
32 | </div>
|
33 | <div class="modal-footer">
|
34 | <button type="button" id="btnCloseAvd_%s" class="btn btn-%s">%s</button>
|
35 | </div>
|
36 | </div>
|
37 | </div>
|
38 | </div>
|
39 | `
|
40 | }
|
41 | },
|
42 | bootstrap4: {
|
43 | icons: {
|
44 | advancedSearchIcon: 'fa-chevron-down'
|
45 | },
|
46 | classes: {},
|
47 | html: {
|
48 | modal: `
|
49 | <div id="avdSearchModal_%s" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
|
50 | <div class="modal-dialog modal-xs">
|
51 | <div class="modal-content">
|
52 | <div class="modal-header">
|
53 | <h4 class="modal-title">%s</h4>
|
54 | <button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
55 | <span aria-hidden="true">×</span>
|
56 | </button>
|
57 | </div>
|
58 | <div class="modal-body modal-body-custom">
|
59 | <div class="container-fluid" id="avdSearchModalContent_%s"
|
60 | style="padding-right: 0; padding-left: 0;" >
|
61 | </div>
|
62 | </div>
|
63 | <div class="modal-footer">
|
64 | <button type="button" id="btnCloseAvd_%s" class="btn btn-%s">%s</button>
|
65 | </div>
|
66 | </div>
|
67 | </div>
|
68 | </div>
|
69 | `
|
70 | }
|
71 | },
|
72 | bootstrap5: {
|
73 | icons: {
|
74 | advancedSearchIcon: 'bi-chevron-down'
|
75 | },
|
76 | classes: {
|
77 | formGroup: 'mb-3'
|
78 | },
|
79 | html: {
|
80 | modal: `
|
81 | <div id="avdSearchModal_%s" class="modal fade" tabindex="-1" aria-labelledby="mySmallModalLabel" aria-hidden="true">
|
82 | <div class="modal-dialog modal-xs">
|
83 | <div class="modal-content">
|
84 | <div class="modal-header">
|
85 | <h5 class="modal-title">%s</h5>
|
86 | <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
87 | </div>
|
88 | <div class="modal-body modal-body-custom">
|
89 | <div class="container-fluid" id="avdSearchModalContent_%s"
|
90 | style="padding-right: 0; padding-left: 0;" >
|
91 | </div>
|
92 | </div>
|
93 | <div class="modal-footer">
|
94 | <button type="button" id="btnCloseAvd_%s" class="btn btn-%s">%s</button>
|
95 | </div>
|
96 | </div>
|
97 | </div>
|
98 | </div>
|
99 | `
|
100 | }
|
101 | },
|
102 | bulma: {
|
103 | icons: {
|
104 | advancedSearchIcon: 'fa-chevron-down'
|
105 | },
|
106 | classes: {},
|
107 | html: {
|
108 | modal: `
|
109 | <div class="modal" id="avdSearchModal_%s">
|
110 | <div class="modal-background"></div>
|
111 | <div class="modal-card">
|
112 | <header class="modal-card-head">
|
113 | <p class="modal-card-title">%s</p>
|
114 | <button class="delete" aria-label="close"></button>
|
115 | </header>
|
116 | <section class="modal-card-body" id="avdSearchModalContent_%s"></section>
|
117 | <footer class="modal-card-foot">
|
118 | <button class="button" id="btnCloseAvd_%s" data-close="btn btn-%s">%s</button>
|
119 | </footer>
|
120 | </div>
|
121 | </div>
|
122 | `
|
123 | }
|
124 | },
|
125 | foundation: {
|
126 | icons: {
|
127 | advancedSearchIcon: 'fa-chevron-down'
|
128 | },
|
129 | classes: {},
|
130 | html: {
|
131 | modal: `
|
132 | <div class="reveal" id="avdSearchModal_%s" data-reveal>
|
133 | <h1>%s</h1>
|
134 | <div id="avdSearchModalContent_%s">
|
135 |
|
136 | </div>
|
137 | <button class="close-button" data-close aria-label="Close modal" type="button">
|
138 | <span aria-hidden="true">×</span>
|
139 | </button>
|
140 |
|
141 | <button id="btnCloseAvd_%s" class="%s" type="button">%s</button>
|
142 | </div>
|
143 | `
|
144 | }
|
145 | },
|
146 | materialize: {
|
147 | icons: {
|
148 | advancedSearchIcon: 'expand_more'
|
149 | },
|
150 | classes: {},
|
151 | html: {
|
152 | modal: `
|
153 | <div id="avdSearchModal_%s" class="modal">
|
154 | <div class="modal-content">
|
155 | <h4>%s</h4>
|
156 | <div id="avdSearchModalContent_%s">
|
157 |
|
158 | </div>
|
159 | </div>
|
160 | <div class="modal-footer">
|
161 | <a href="javascript:void(0)"" id="btnCloseAvd_%s" class="modal-close waves-effect waves-green btn-flat %s">%s</a>
|
162 | </div>
|
163 | </div>
|
164 | `
|
165 | }
|
166 | },
|
167 | semantic: {
|
168 | icons: {
|
169 | advancedSearchIcon: 'fa-chevron-down'
|
170 | },
|
171 | classes: {},
|
172 | html: {
|
173 | modal: `
|
174 | <div class="ui modal" id="avdSearchModal_%s">
|
175 | <i class="close icon"></i>
|
176 | <div class="header">
|
177 | %s
|
178 | </div>
|
179 | <div class="image content ui form" id="avdSearchModalContent_%s"></div>
|
180 | <div class="actions">
|
181 | <div id="btnCloseAvd_%s" class="ui black deny button %s">%s</div>
|
182 | </div>
|
183 | </div>
|
184 | `
|
185 | }
|
186 | }
|
187 | }[$.fn.bootstrapTable.theme]
|
188 |
|
189 | $.extend($.fn.bootstrapTable.defaults, {
|
190 | advancedSearch: false,
|
191 | idForm: 'advancedSearch',
|
192 | actionForm: '',
|
193 | idTable: undefined,
|
194 |
|
195 | onColumnAdvancedSearch (field, text) {
|
196 | return false
|
197 | }
|
198 | })
|
199 |
|
200 | $.extend($.fn.bootstrapTable.defaults.icons, {
|
201 | advancedSearchIcon: theme.icons.advancedSearchIcon
|
202 | })
|
203 |
|
204 | $.extend($.fn.bootstrapTable.Constructor.EVENTS, {
|
205 | 'column-advanced-search.bs.table': 'onColumnAdvancedSearch'
|
206 | })
|
207 |
|
208 | $.extend($.fn.bootstrapTable.locales, {
|
209 | formatAdvancedSearch () {
|
210 | return 'Advanced search'
|
211 | },
|
212 | formatAdvancedCloseButton () {
|
213 | return 'Close'
|
214 | }
|
215 | })
|
216 |
|
217 | $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
|
218 |
|
219 | $.BootstrapTable = class extends $.BootstrapTable {
|
220 | initToolbar () {
|
221 | const o = this.options
|
222 |
|
223 | this.showToolbar = this.showToolbar ||
|
224 | (o.search &&
|
225 | o.advancedSearch &&
|
226 | o.idTable)
|
227 |
|
228 | if (o.search && o.advancedSearch && o.idTable) {
|
229 | this.buttons = Object.assign(this.buttons, {
|
230 | advancedSearch: {
|
231 | text: this.options.formatAdvancedSearch(),
|
232 | icon: this.options.icons.advancedSearchIcon,
|
233 | event: this.showAvdSearch,
|
234 | attributes: {
|
235 | 'aria-label': this.options.formatAdvancedSearch(),
|
236 | title: this.options.formatAdvancedSearch()
|
237 | }
|
238 | }
|
239 | })
|
240 | }
|
241 |
|
242 | super.initToolbar()
|
243 | }
|
244 |
|
245 | showAvdSearch () {
|
246 | const o = this.options
|
247 | const modalSelector = `#avdSearchModal_${ o.idTable}`
|
248 |
|
249 | if ($(modalSelector).length <= 0) {
|
250 | $('body').append(Utils.sprintf(theme.html.modal, o.idTable, o.formatAdvancedSearch(), o.idTable, o.idTable, o.buttonsClass, o.formatAdvancedCloseButton()))
|
251 |
|
252 | let timeoutId = 0
|
253 |
|
254 | $(`#avdSearchModalContent_${o.idTable}`).append(this.createFormAvd().join(''))
|
255 |
|
256 | $(`#${o.idForm}`).off('keyup blur', 'input').on('keyup blur', 'input', e => {
|
257 | if (o.sidePagination === 'server') {
|
258 | this.onColumnAdvancedSearch(e)
|
259 | } else {
|
260 | clearTimeout(timeoutId)
|
261 | timeoutId = setTimeout(() => {
|
262 | this.onColumnAdvancedSearch(e)
|
263 | }, o.searchTimeOut)
|
264 | }
|
265 | })
|
266 |
|
267 | $(`#btnCloseAvd_${o.idTable}`).click(() => this.hideModal())
|
268 |
|
269 | if ($.fn.bootstrapTable.theme === 'bulma') {
|
270 | $(modalSelector).find('.delete').off('click').on('click', () => this.hideModal())
|
271 | }
|
272 |
|
273 | this.showModal()
|
274 | } else {
|
275 | this.showModal()
|
276 | }
|
277 | }
|
278 |
|
279 | showModal () {
|
280 | const modalSelector = `#avdSearchModal_${ this.options.idTable}`
|
281 |
|
282 | if ($.inArray($.fn.bootstrapTable.theme, ['bootstrap3', 'bootstrap4']) !== -1) {
|
283 | $(modalSelector).modal()
|
284 | } else if ($.fn.bootstrapTable.theme === 'bootstrap5') {
|
285 | if (!this.toolbarModal) {
|
286 |
|
287 | this.toolbarModal = new bootstrap.Modal(document.getElementById(`avdSearchModal_${ this.options.idTable}`), {})
|
288 | }
|
289 | this.toolbarModal.show()
|
290 | } else if ($.fn.bootstrapTable.theme === 'bulma') {
|
291 | $(modalSelector).toggleClass('is-active')
|
292 | } else if ($.fn.bootstrapTable.theme === 'foundation') {
|
293 | if (!this.toolbarModal) {
|
294 |
|
295 | this.toolbarModal = new Foundation.Reveal($(modalSelector))
|
296 | }
|
297 | this.toolbarModal.open()
|
298 | } else if ($.fn.bootstrapTable.theme === 'materialize') {
|
299 | $(modalSelector).modal()
|
300 | $(modalSelector).modal('open')
|
301 | } else if ($.fn.bootstrapTable.theme === 'semantic') {
|
302 | $(modalSelector).modal('show')
|
303 | }
|
304 |
|
305 | }
|
306 |
|
307 | hideModal () {
|
308 | const $closeModalButton = $(`#avdSearchModal_${this.options.idTable}`)
|
309 | const modalSelector = `#avdSearchModal_${ this.options.idTable}`
|
310 |
|
311 | if ($.inArray($.fn.bootstrapTable.theme, ['bootstrap3', 'bootstrap4']) !== -1) {
|
312 | $closeModalButton.modal('hide')
|
313 | } else if ($.fn.bootstrapTable.theme === 'bootstrap5') {
|
314 | this.toolbarModal.hide()
|
315 | } else if ($.fn.bootstrapTable.theme === 'bulma') {
|
316 | $('html').toggleClass('is-clipped')
|
317 | $(modalSelector).toggleClass('is-active')
|
318 | } else if ($.fn.bootstrapTable.theme === 'foundation') {
|
319 | this.toolbarModal.close()
|
320 | } else if ($.fn.bootstrapTable.theme === 'materialize') {
|
321 | $(modalSelector).modal('open')
|
322 | } else if ($.fn.bootstrapTable.theme === 'semantic') {
|
323 | $(modalSelector).modal('close')
|
324 | }
|
325 |
|
326 | if (this.options.sidePagination === 'server') {
|
327 | this.options.pageNumber = 1
|
328 | this.updatePagination()
|
329 | this.trigger('column-advanced-search', this.filterColumnsPartial)
|
330 | }
|
331 | }
|
332 |
|
333 |
|
334 | createFormAvd () {
|
335 | const o = this.options
|
336 | const html = [`<form class="form-horizontal" id="${o.idForm}" action="${o.actionForm}">`]
|
337 |
|
338 | for (const column of this.columns) {
|
339 | if (!column.checkbox && column.visible && column.searchable) {
|
340 | html.push(`
|
341 | <div class="form-group row ${theme.classes.formGroup || ''}">
|
342 | <label class="col-sm-4 control-label">${column.title}</label>
|
343 | <div class="col-sm-6">
|
344 | <input type="text" class="form-control ${this.constants.classes.input}" name="${column.field}" placeholder="${column.title}" id="${column.field}">
|
345 | </div>
|
346 | </div>
|
347 | `)
|
348 | }
|
349 | }
|
350 |
|
351 | html.push('</form>')
|
352 |
|
353 | return html
|
354 | }
|
355 |
|
356 | initSearch () {
|
357 | super.initSearch()
|
358 |
|
359 | if (!this.options.advancedSearch || this.options.sidePagination === 'server') {
|
360 | return
|
361 | }
|
362 |
|
363 | const fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial
|
364 |
|
365 | this.data = fp ? this.data.filter((item, i) => {
|
366 | for (const [key, v] of Object.entries(fp)) {
|
367 | const fval = v.toLowerCase()
|
368 | let value = item[key]
|
369 | const index = this.header.fields.indexOf(key)
|
370 |
|
371 | value = Utils.calculateObjectValue(this.header,
|
372 | this.header.formatters[index], [value, item, i], value)
|
373 |
|
374 | if (
|
375 | !(index !== -1 &&
|
376 | (typeof value === 'string' || typeof value === 'number') &&
|
377 | (`${value}`).toLowerCase().includes(fval))
|
378 | ) {
|
379 | return false
|
380 | }
|
381 | }
|
382 | return true
|
383 | }) : this.data
|
384 | this.unsortedData = [...this.data]
|
385 | }
|
386 |
|
387 | onColumnAdvancedSearch (e) {
|
388 | const text = $(e.currentTarget).val().trim()
|
389 | const $field = $(e.currentTarget)[0].id
|
390 |
|
391 | if ($.isEmptyObject(this.filterColumnsPartial)) {
|
392 | this.filterColumnsPartial = {}
|
393 | }
|
394 | if (text) {
|
395 | this.filterColumnsPartial[$field] = text
|
396 | } else {
|
397 | delete this.filterColumnsPartial[$field]
|
398 | }
|
399 |
|
400 | if (this.options.sidePagination !== 'server') {
|
401 | this.options.pageNumber = 1
|
402 | this.initSearch()
|
403 | this.updatePagination()
|
404 | this.trigger('column-advanced-search', $field, text)
|
405 | }
|
406 | }
|
407 | }
|