bootstrap-table-editable.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /**
  2. * @author zhixin wen <wenzhixin2010@gmail.com>
  3. * extensions: https://github.com/vitalets/x-editable
  4. */
  5. const Utils = $.fn.bootstrapTable.utils
  6. $.extend($.fn.bootstrapTable.defaults, {
  7. editable: true,
  8. onEditableInit () {
  9. return false
  10. },
  11. onEditableSave (field, row, rowIndex, oldValue, $el) {
  12. return false
  13. },
  14. onEditableShown (field, row, $el, editable) {
  15. return false
  16. },
  17. onEditableHidden (field, row, $el, reason) {
  18. return false
  19. }
  20. })
  21. $.extend($.fn.bootstrapTable.Constructor.EVENTS, {
  22. 'editable-init.bs.table': 'onEditableInit',
  23. 'editable-save.bs.table': 'onEditableSave',
  24. 'editable-shown.bs.table': 'onEditableShown',
  25. 'editable-hidden.bs.table': 'onEditableHidden'
  26. })
  27. $.BootstrapTable = class extends $.BootstrapTable {
  28. initTable () {
  29. super.initTable()
  30. if (!this.options.editable) {
  31. return
  32. }
  33. $.each(this.columns, (i, column) => {
  34. if (!column.editable) {
  35. return
  36. }
  37. const editableOptions = {}
  38. const editableDataMarkup = []
  39. const editableDataPrefix = 'editable-'
  40. const processDataOptions = (key, value) => {
  41. // Replace camel case with dashes.
  42. const dashKey = key.replace(/([A-Z])/g, $1 => `-${$1.toLowerCase()}`)
  43. if (dashKey.indexOf(editableDataPrefix) === 0) {
  44. editableOptions[dashKey.replace(editableDataPrefix, 'data-')] = value
  45. }
  46. }
  47. $.each(this.options, processDataOptions)
  48. column.formatter = column.formatter || (value => value)
  49. column._formatter = column._formatter ? column._formatter : column.formatter
  50. column.formatter = (value, row, index) => {
  51. let result = Utils.calculateObjectValue(column, column._formatter, [value, row, index], value)
  52. result = typeof result === 'undefined' || result === null ? this.options.undefinedText : result
  53. $.each(column, processDataOptions)
  54. $.each(editableOptions, (key, value) => {
  55. editableDataMarkup.push(` ${key}="${value}"`)
  56. })
  57. let _dont_edit_formatter = false
  58. if (column.editable.hasOwnProperty('noeditFormatter')) {
  59. _dont_edit_formatter = column.editable.noeditFormatter(value, row, index)
  60. }
  61. if (_dont_edit_formatter === false) {
  62. return `<a href="javascript:void(0)"
  63. data-name="${column.field}"
  64. data-pk="${row[this.options.idField]}"
  65. data-value="${result}"
  66. ${editableDataMarkup.join('')}></a>`
  67. }
  68. return _dont_edit_formatter
  69. }
  70. })
  71. }
  72. initBody (fixedScroll) {
  73. super.initBody(fixedScroll)
  74. if (!this.options.editable) {
  75. return
  76. }
  77. $.each(this.columns, (i, column) => {
  78. if (!column.editable) {
  79. return
  80. }
  81. const data = this.getData()
  82. const $field = this.$body.find(`a[data-name="${column.field}"]`)
  83. $field.each((i, element) => {
  84. const $element = $(element)
  85. const $tr = $element.closest('tr')
  86. const index = $tr.data('index')
  87. const row = data[index]
  88. const editableOpts = Utils.calculateObjectValue(column,
  89. column.editable, [index, row, $element], {})
  90. $element.editable(editableOpts)
  91. })
  92. $field.off('save').on('save', ({currentTarget}, {submitValue}) => {
  93. const $this = $(currentTarget)
  94. const data = this.getData()
  95. const rowIndex = $this.parents('tr[data-index]').data('index')
  96. const row = data[rowIndex]
  97. const oldValue = row[column.field]
  98. $this.data('value', submitValue)
  99. row[column.field] = submitValue
  100. this.trigger('editable-save', column.field, row, rowIndex, oldValue, $this)
  101. this.initBody()
  102. })
  103. $field.off('shown').on('shown', ({currentTarget}, editable) => {
  104. const $this = $(currentTarget)
  105. const data = this.getData()
  106. const rowIndex = $this.parents('tr[data-index]').data('index')
  107. const row = data[rowIndex]
  108. this.trigger('editable-shown', column.field, row, $this, editable)
  109. })
  110. $field.off('hidden').on('hidden', ({currentTarget}, reason) => {
  111. const $this = $(currentTarget)
  112. const data = this.getData()
  113. const rowIndex = $this.parents('tr[data-index]').data('index')
  114. const row = data[rowIndex]
  115. this.trigger('editable-hidden', column.field, row, $this, reason)
  116. })
  117. })
  118. this.trigger('editable-init')
  119. }
  120. }