bootstrap-table-toolbar.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /**
  2. * @author: aperez <aperez@datadec.es>
  3. * @version: v2.0.0
  4. *
  5. * @update Dennis Hernández <http://djhvscf.github.io/Blog>
  6. * @update zhixin wen <wenzhixin2010@gmail.com>
  7. */
  8. const Utils = $.fn.bootstrapTable.utils
  9. const bootstrap = {
  10. bootstrap3: {
  11. icons: {
  12. advancedSearchIcon: 'glyphicon-chevron-down'
  13. },
  14. html: {
  15. modalHeader: `
  16. <div class="modal-header">
  17. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  18. <span aria-hidden="true">&times;</span>
  19. </button>
  20. <h4 class="modal-title">%s</h4>
  21. </div>
  22. `
  23. }
  24. },
  25. bootstrap4: {
  26. icons: {
  27. advancedSearchIcon: 'fa-chevron-down'
  28. },
  29. html: {
  30. modalHeader: `
  31. <div class="modal-header">
  32. <h4 class="modal-title">%s</h4>
  33. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  34. <span aria-hidden="true">&times;</span>
  35. </button>
  36. </div>
  37. `
  38. }
  39. }
  40. }[$.fn.bootstrapTable.theme]
  41. $.extend($.fn.bootstrapTable.defaults, {
  42. advancedSearch: false,
  43. idForm: 'advancedSearch',
  44. actionForm: '',
  45. idTable: undefined,
  46. onColumnAdvancedSearch (field, text) {
  47. return false
  48. }
  49. })
  50. $.extend($.fn.bootstrapTable.defaults.icons, {
  51. advancedSearchIcon: bootstrap.icons.advancedSearchIcon
  52. })
  53. $.extend($.fn.bootstrapTable.Constructor.EVENTS, {
  54. 'column-advanced-search.bs.table': 'onColumnAdvancedSearch'
  55. })
  56. $.extend($.fn.bootstrapTable.locales, {
  57. formatAdvancedSearch () {
  58. return 'Advanced search'
  59. },
  60. formatAdvancedCloseButton () {
  61. return 'Close'
  62. }
  63. })
  64. $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
  65. $.BootstrapTable = class extends $.BootstrapTable {
  66. initToolbar () {
  67. const o = this.options
  68. this.showToolbar = this.showToolbar ||
  69. (o.search &&
  70. o.advancedSearch &&
  71. o.idTable)
  72. super.initToolbar()
  73. if (!o.search || !o.advancedSearch || !o.idTable) {
  74. return
  75. }
  76. this.$toolbar.find('>.btn-group').append(`
  77. <button class="btn btn-default${Utils.sprintf(' btn-%s', o.buttonsClass)}${Utils.sprintf(' btn-%s', o.iconSize)}"
  78. type="button"
  79. name="advancedSearch"
  80. aria-label="advanced search"
  81. title="${o.formatAdvancedSearch()}">
  82. ${ this.options.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.advancedSearchIcon) : ''}
  83. ${ this.options.showButtonText ? this.options.formatAdvancedSearch() : ''}
  84. </button>
  85. `)
  86. this.$toolbar.find('button[name="advancedSearch"]').off('click').on('click', () => this.showAvdSearch())
  87. }
  88. showAvdSearch () {
  89. const o = this.options
  90. if (!$(`#avdSearchModal_${o.idTable}`).hasClass('modal')) {
  91. $('body').append(`
  92. <div id="avdSearchModal_${o.idTable}" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
  93. <div class="modal-dialog modal-xs">
  94. <div class="modal-content">
  95. ${Utils.sprintf(bootstrap.html.modalHeader, o.formatAdvancedSearch())}
  96. <div class="modal-body modal-body-custom">
  97. <div class="container-fluid" id="avdSearchModalContent_${o.idTable}"
  98. style="padding-right: 0px; padding-left: 0px;" >
  99. </div>
  100. </div>
  101. <div class="modal-footer">
  102. <button type="button" id="btnCloseAvd_${o.idTable}" class="btn btn-${o.buttonsClass}">
  103. ${o.formatAdvancedCloseButton()}
  104. </button>
  105. </div>
  106. </div>
  107. </div>
  108. </div>
  109. `)
  110. let timeoutId = 0
  111. $(`#avdSearchModalContent_${o.idTable}`).append(this.createFormAvd().join(''))
  112. $(`#${o.idForm}`).off('keyup blur', 'input').on('keyup blur', 'input', e => {
  113. if (o.sidePagination === 'server') {
  114. this.onColumnAdvancedSearch(e)
  115. } else {
  116. clearTimeout(timeoutId)
  117. timeoutId = setTimeout(() => {
  118. this.onColumnAdvancedSearch(e)
  119. }, o.searchTimeOut)
  120. }
  121. })
  122. $(`#btnCloseAvd_${o.idTable}`).click(() => {
  123. $(`#avdSearchModal_${o.idTable}`).modal('hide')
  124. if (o.sidePagination === 'server') {
  125. this.options.pageNumber = 1
  126. this.updatePagination()
  127. this.trigger('column-advanced-search', this.filterColumnsPartial)
  128. }
  129. })
  130. $(`#avdSearchModal_${o.idTable}`).modal()
  131. } else {
  132. $(`#avdSearchModal_${o.idTable}`).modal()
  133. }
  134. }
  135. createFormAvd () {
  136. const o = this.options
  137. const html = [`<form class="form-horizontal" id="${o.idForm}" action="${o.actionForm}">`]
  138. for (const column of this.columns) {
  139. if (!column.checkbox && column.visible && column.searchable) {
  140. html.push(`
  141. <div class="form-group row">
  142. <label class="col-sm-4 control-label">${column.title}</label>
  143. <div class="col-sm-6">
  144. <input type="text" class="form-control input-md" name="${column.field}" placeholder="${column.title}" id="${column.field}">
  145. </div>
  146. </div>
  147. `)
  148. }
  149. }
  150. html.push('</form>')
  151. return html
  152. }
  153. initSearch () {
  154. super.initSearch()
  155. if (!this.options.advancedSearch || this.options.sidePagination === 'server') {
  156. return
  157. }
  158. const fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial
  159. this.data = fp ? this.data.filter((item, i) => {
  160. for (const [key, v] of Object.entries(fp)) {
  161. const fval = v.toLowerCase()
  162. let value = item[key]
  163. const index = this.header.fields.indexOf(key)
  164. value = Utils.calculateObjectValue(this.header,
  165. this.header.formatters[index], [value, item, i], value)
  166. if (
  167. !(index !== -1 &&
  168. (typeof value === 'string' || typeof value === 'number') &&
  169. (`${value}`).toLowerCase().includes(fval))
  170. ) {
  171. return false
  172. }
  173. }
  174. return true
  175. }) : this.data
  176. }
  177. onColumnAdvancedSearch (e) {
  178. const text = $.trim($(e.currentTarget).val())
  179. const $field = $(e.currentTarget)[0].id
  180. if ($.isEmptyObject(this.filterColumnsPartial)) {
  181. this.filterColumnsPartial = {}
  182. }
  183. if (text) {
  184. this.filterColumnsPartial[$field] = text
  185. } else {
  186. delete this.filterColumnsPartial[$field]
  187. }
  188. if (this.options.sidePagination !== 'server') {
  189. this.options.pageNumber = 1
  190. this.onSearch(e)
  191. this.updatePagination()
  192. this.trigger('column-advanced-search', $field, text)
  193. }
  194. }
  195. }