bootstrap-table-toolbar.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. 3: {
  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. 4: {
  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. }[Utils.bootstrapVersion]
  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. <i class="${o.iconsPrefix} ${o.icons.advancedSearchIcon}"></i>
  83. </button>
  84. `)
  85. this.$toolbar.find('button[name="advancedSearch"]').off('click').on('click', () => this.showAvdSearch())
  86. }
  87. showAvdSearch () {
  88. const o = this.options
  89. if (!$(`#avdSearchModal_${o.idTable}`).hasClass('modal')) {
  90. $('body').append(`
  91. <div id="avdSearchModal_${o.idTable}" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
  92. <div class="modal-dialog modal-xs">
  93. <div class="modal-content">
  94. ${Utils.sprintf(bootstrap.html.modalHeader, o.formatAdvancedSearch())}
  95. <div class="modal-body modal-body-custom">
  96. <div class="container-fluid" id="avdSearchModalContent_${o.idTable}"
  97. style="padding-right: 0px; padding-left: 0px;" >
  98. </div>
  99. </div>
  100. <div class="modal-footer">
  101. <button type="button" id="btnCloseAvd_${o.idTable}" class="btn btn-${o.buttonsClass}">
  102. ${o.formatAdvancedCloseButton()}
  103. </button>
  104. </div>
  105. </div>
  106. </div>
  107. </div>
  108. `)
  109. let timeoutId = 0
  110. $(`#avdSearchModalContent_${o.idTable}`).append(this.createFormAvd().join(''))
  111. $(`#${o.idForm}`).off('keyup blur', 'input').on('keyup blur', 'input', e => {
  112. if (o.sidePagination === 'server') {
  113. this.onColumnAdvancedSearch(e)
  114. } else {
  115. clearTimeout(timeoutId)
  116. timeoutId = setTimeout(() => {
  117. this.onColumnAdvancedSearch(e)
  118. }, o.searchTimeOut)
  119. }
  120. })
  121. $(`#btnCloseAvd_${o.idTable}`).click(() => {
  122. $(`#avdSearchModal_${o.idTable}`).modal('hide')
  123. if (o.sidePagination === 'server') {
  124. this.options.pageNumber = 1
  125. this.updatePagination()
  126. this.trigger('column-advanced-search', this.filterColumnsPartial)
  127. }
  128. })
  129. $(`#avdSearchModal_${o.idTable}`).modal()
  130. } else {
  131. $(`#avdSearchModal_${o.idTable}`).modal()
  132. }
  133. }
  134. createFormAvd () {
  135. const o = this.options
  136. const html = [`<form class="form-horizontal" id="${o.idForm}" action="${o.actionForm}">`]
  137. for (const column of this.columns) {
  138. if (!column.checkbox && column.visible && column.searchable) {
  139. html.push(`
  140. <div class="form-group row">
  141. <label class="col-sm-4 control-label">${column.title}</label>
  142. <div class="col-sm-6">
  143. <input type="text" class="form-control input-md" name="${column.field}" placeholder="${column.title}" id="${column.field}">
  144. </div>
  145. </div>
  146. `)
  147. }
  148. }
  149. html.push('</form>')
  150. return html
  151. }
  152. initSearch () {
  153. super.initSearch()
  154. if (!this.options.advancedSearch || this.options.sidePagination === 'server') {
  155. return
  156. }
  157. const fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial
  158. this.data = fp ? this.data.filter((item, i) => {
  159. for (const [key, v] of Object.entries(fp)) {
  160. const fval = v.toLowerCase()
  161. let value = item[key]
  162. const index = this.header.fields.indexOf(key)
  163. value = Utils.calculateObjectValue(this.header,
  164. this.header.formatters[index], [value, item, i], value)
  165. if (
  166. !(index !== -1 &&
  167. (typeof value === 'string' || typeof value === 'number') &&
  168. (`${value}`).toLowerCase().includes(fval))
  169. ) {
  170. return false
  171. }
  172. }
  173. return true
  174. }) : this.data
  175. }
  176. onColumnAdvancedSearch (e) {
  177. const text = $.trim($(e.currentTarget).val())
  178. const $field = $(e.currentTarget)[0].id
  179. if ($.isEmptyObject(this.filterColumnsPartial)) {
  180. this.filterColumnsPartial = {}
  181. }
  182. if (text) {
  183. this.filterColumnsPartial[$field] = text
  184. } else {
  185. delete this.filterColumnsPartial[$field]
  186. }
  187. if (this.options.sidePagination !== 'server') {
  188. this.options.pageNumber = 1
  189. this.onSearch(e)
  190. this.updatePagination()
  191. this.trigger('column-advanced-search', $field, text)
  192. }
  193. }
  194. }