Browse Source

Updated methods order and docs

zhixin 6 years ago
parent
commit
0688cf7585
4 changed files with 444 additions and 435 deletions
  1. 119 111
      site/docs/api/methods.md
  2. 303 303
      src/bootstrap-table.js
  3. 20 19
      src/constants/index.js
  4. 2 2
      tools/check-api.js

+ 119 - 111
site/docs/api/methods.md

@@ -16,29 +16,37 @@ The calling method syntax: `$('#table').bootstrapTable('method', parameter)`.
 
   Return the options object.
 
-## getSelections
+## refreshOptions
 
-- **Parameter:** `undefined`
+- **Parameter:** `options`
 
 - **Detail:**
 
-  Return selected rows, when no record selected, an empty array will return.
+  Refresh the table `options`.
 
-## getAllSelections
+## getData
+
+- **Parameter:** `useCurrentPage`
+
+- **Detail:**
+
+  Get the loaded data of table at the moment that this method is called. If you set the `useCurrentPage` to `true` the method will return the data in the current page.
+
+## getSelections
 
 - **Parameter:** `undefined`
 
 - **Detail:**
 
-  Return all selected rows contain search or filter, when no record selected, an empty array will return.
+  Return selected rows, when no record selected, an empty array will return.
 
-## getData
+## getAllSelections
 
-- **Parameter:** `useCurrentPage`
+- **Parameter:** `undefined`
 
 - **Detail:**
 
-  Get the loaded data of table at the moment that this method is called. If you set the `useCurrentPage` to `true` the method will return the data in the current page.
+  Return all selected rows contain search or filter, when no record selected, an empty array will return.
 
 ## load
 
@@ -105,19 +113,13 @@ The calling method syntax: `$('#table').bootstrapTable('method', parameter)`.
   * `index`: the row index to be updated.
   * `row`: the new row data.
 
-## updateCell
+## getRowByUniqueId
 
-- **Parameter:** `params`
+- **Parameter:** `id`
 
 - **Detail:**
 
-  Update one cell, the params contain following properties:
-
-  * `index`: the row index.
-  * `field`: the field name.
-  * `value`: the new field value.
-
-  To disable table re-initialization you can set `{reinit: false}`.
+  Get data from table, the row that contains the `id` passed by parameter.
 
 ## updateByUniqueId
 
@@ -138,13 +140,31 @@ The calling method syntax: `$('#table').bootstrapTable('method', parameter)`.
 
   Remove data from table, the row that contains the `id` passed by parameter.
 
-## getRowByUniqueId
+## updateCell
 
-- **Parameter:** `id`
+- **Parameter:** `params`
 
 - **Detail:**
 
-  Get data from table, the row that contains the `id` passed by parameter.
+  Update one cell, the params contain following properties:
+
+  * `index`: the row index.
+  * `field`: the field name.
+  * `value`: the new field value.
+
+  To disable table re-initialization you can set `{reinit: false}`.
+
+## updateCellByUniqueId
+
+- **Parameter:** `params`
+
+- **Detail:**
+
+  Update the cell specified by the id, each params contain following properties:
+
+  * `id`: row id where the id should be the `uniqueId` field assigned to the table.
+  * `field`: field name of the cell to be updated.
+  * `value`: new value of the cell.
 
 ## showRow
 
@@ -176,29 +196,68 @@ The calling method syntax: `$('#table').bootstrapTable('method', parameter)`.
 
   Get all rows hidden and if you pass the `show` parameter `true` the rows will be shown again, otherwise, the method only will return the rows hidden.
 
-## mergeCells
+## showColumn
 
-- **Parameter:** `params`
+- **Parameter:** `field`
 
 - **Detail:**
 
-  Merge some cells to one cell, the params contain following properties:
+  Show the specified `field` column.
+  The parameter can be a string or a array of fields.
 
-  * `index`: the row index.
-  * `field`: the field name.
-  * `rowspan`: the rowspan count to be merged.
-  * `colspan`: the colspan count to be merged.
+## hideColumn
 
-## refreshColumnTitle
+- **Parameter:** `field`
+
+- **Detail:**
+
+  Hide the specified `field` column.
+  The parameter can be a string or a array of fields.
+
+## getVisibleColumns
+
+- **Parameter:** `-`
+
+- **Detail:**
+
+  Get visible columns.
+
+## getHiddenColumns
+
+- **Parameter:** `undefined`
+
+- **Detail:**
+
+  Get hidden columns.
+
+## showAllColumns
+
+- **Parameter:** `undefined`
+
+- **Detail:**
+
+  Show All the columns.
+
+## hideAllColumns
+
+- **Parameter:** `undefined`
+
+- **Detail:**
+
+  Hide All the columns.
+
+## mergeCells
 
 - **Parameter:** `params`
 
 - **Detail:**
 
-  Refresh the field title of column, the params contain following properties:
+  Merge some cells to one cell, the params contain following properties:
 
+  * `index`: the row index.
   * `field`: the field name.
-  * `title`: the field title.
+  * `rowspan`: the rowspan count to be merged.
+  * `colspan`: the colspan count to be merged.
 
 ## checkAll
 
@@ -270,6 +329,14 @@ The calling method syntax: `$('#table').bootstrapTable('method', parameter)`.
 
   Refresh the remote server data, you can set `{silent: true}` to refresh the data silently, and set `{url: newUrl, pageNumber: pageNumber, pageSize: pageSize}` to change the url (optional), page number (optional) and page size (optional). To supply query params specific to this request, set `{query: {foo: 'bar'}}`.
 
+## destroy
+
+- **Parameter:** `undefined`
+
+- **Detail:**
+
+  Destroy the Bootstrap Table.
+
 ## resetView
 
 - **Parameter:** `params`
@@ -288,14 +355,6 @@ The calling method syntax: `$('#table').bootstrapTable('method', parameter)`.
 
   Resizes header and footer to fit current columns width.
 
-## destroy
-
-- **Parameter:** `undefined`
-
-- **Detail:**
-
-  Destroy the Bootstrap Table.
-
 ## showLoading
 
 - **Parameter:** `undefined`
@@ -312,55 +371,37 @@ The calling method syntax: `$('#table').bootstrapTable('method', parameter)`.
 
   Hide loading status.
 
-## showColumn
-
-- **Parameter:** `field`
-
-- **Detail:**
-
-  Show the specified `field` column.
-  The parameter can be a string or a array of fields.
-
-## hideColumn
-
-- **Parameter:** `field`
-
-- **Detail:**
-
-  Hide the specified `field` column.
-  The parameter can be a string or a array of fields.
-
-## getHiddenColumns
+## togglePagination
 
 - **Parameter:** `undefined`
 
 - **Detail:**
 
-  Get hidden columns.
+  Toggle the pagination option.
 
-## getVisibleColumns
+## toggleFullscreen
 
-- **Parameter:** `-`
+- **Parameter:** `undefined`
 
 - **Detail:**
 
-  Get visible columns.
+  Toggle fullscreen.
 
-## showAllColumns
+## toggleView
 
 - **Parameter:** `undefined`
 
 - **Detail:**
 
-  Show All the columns.
+  Toggle the card/table view.
 
-## hideAllColumns
+## resetSearch
 
-- **Parameter:** `undefined`
+- **Parameter:** `text`
 
 - **Detail:**
 
-  Hide All the columns.
+  Set the search `text`.
 
 ## filterBy
 
@@ -440,37 +481,13 @@ The calling method syntax: `$('#table').bootstrapTable('method', parameter)`.
 
   Go to next page.
 
-## togglePagination
-
-- **Parameter:** `undefined`
-
-- **Detail:**
-
-  Toggle the pagination option.
-
-## toggleView
-
-- **Parameter:** `undefined`
-
-- **Detail:**
-
-  Toggle the card/table view.
-
-## refreshOptions
-
-- **Parameter:** `options`
-
-- **Detail:**
-
-  Refresh the table `options`.
-
-## resetSearch
+## toggleDetailView
 
-- **Parameter:** `text`
+- **Parameter:** `index`
 
 - **Detail:**
 
-  Set the search `text`.
+  Toggle the row that has the `index` passed by parameter if the detail view option is set to `true`.
 
 ## expandRow
 
@@ -488,14 +505,6 @@ The calling method syntax: `$('#table').bootstrapTable('method', parameter)`.
 
   Collapse the row that has the `index` passed by parameter if the detail view option is set to `true`.
 
-## toggleDetailView
-
-- **Parameter:** `index`
-
-- **Detail:**
-
-  Toggle the row that has the `index` passed by parameter if the detail view option is set to `true`.
-
 ## expandAllRows
 
 - **Parameter:** `undefined`
@@ -512,22 +521,21 @@ The calling method syntax: `$('#table').bootstrapTable('method', parameter)`.
 
   Collapse all rows if the detail view option is set to `true`.
 
-## updateFormatText
+## updateColumnTitle
 
-- **Parameter:** `formatName, text`
+- **Parameter:** `params`
 
 - **Detail:**
 
-  Update the localizations format text.
+  Refresh the field title of column, the params contain following properties:
 
-## updateCellById
+  * `field`: the field name.
+  * `title`: the field title.
 
-- **Parameter:** `params`
+## updateFormatText
 
-- **Detail:**
+- **Parameter:** `formatName, text`
 
-  Update the cell specified by the id, each params contain following properties:
+- **Detail:**
 
-  * `id`: row id where the id should be the uniqueid field assigned to the table.
-  * `field`: field name of the cell to be updated.
-  * `value`: new value of the cell.
+  Update the localizations format text.

+ 303 - 303
src/bootstrap-table.js

@@ -590,7 +590,7 @@ class BootstrapTable {
       $keepOpen.find('input').off('click').on('click', ({currentTarget}) => {
         const $this = $(currentTarget)
 
-        this.toggleColumn($this.val(), $this.prop('checked'), false)
+        this._toggleColumn($this.val(), $this.prop('checked'), false)
         this.trigger('column-switch', $this.data('field'), $this.prop('checked'))
       })
     }
@@ -1420,7 +1420,7 @@ class BootstrapTable {
       e.stopImmediatePropagation()
 
       const $this = $(e.currentTarget)
-      this.check_($this.prop('checked'), $this.data('index'))
+      this._toggleCheck($this.prop('checked'), $this.data('index'))
     })
 
     this.header.events.forEach((_events, i) => {
@@ -1474,18 +1474,6 @@ class BootstrapTable {
     this.trigger('post-body', data)
   }
 
-  toggleDetailView (index, _columnDetailFormatter) {
-    const $tr = this.$body.find(Utils.sprintf('> tr[data-index="%s"]', index))
-
-    if ($tr.next().is('tr.detail-view')) {
-      this.collapseRow(index)
-    } else {
-      this.expandRow(index, _columnDetailFormatter)
-    }
-
-    this.resetView()
-  }
-
   initServer (silent, query, url) {
     let data = {}
     const index = this.header.fields.indexOf(this.options.sortName)
@@ -1862,29 +1850,6 @@ class BootstrapTable {
     })
   }
 
-  toggleColumn (index, checked, needUpdate) {
-    if (index === -1) {
-      return
-    }
-    this.columns[index].visible = checked
-    this.initHeader()
-    this.initSearch()
-    this.initPagination()
-    this.initBody()
-
-    if (this.options.showColumns) {
-      const $items = this.$toolbar.find('.keep-open input').prop('disabled', false)
-
-      if (needUpdate) {
-        $items.filter(Utils.sprintf('[value="%s"]', index)).prop('checked', checked)
-      }
-
-      if ($items.filter(':checked').length <= this.options.minimumCountColumns) {
-        $items.filter(':checked').prop('disabled', true)
-      }
-    }
-  }
-
   getVisibleFields () {
     const visibleFields = []
 
@@ -1899,59 +1864,29 @@ class BootstrapTable {
     return visibleFields
   }
 
+  initHiddenRows () {
+    this.hiddenRows = []
+  }
+
   // PUBLIC FUNCTION DEFINITION
   // =======================
 
-  resetView (params) {
-    let padding = 0
-
-    if (params && params.height) {
-      this.options.height = params.height
-    }
-
-    this.$selectAll.prop('checked', this.$selectItem.length > 0 &&
-      this.$selectItem.length === this.$selectItem.filter(':checked').length)
-
-    this.$tableContainer.toggleClass('has-card-view', this.options.cardView)
-
-    if (!this.options.cardView && this.options.showHeader && this.options.height) {
-      this.$tableHeader.show()
-      this.resetHeader()
-      padding += this.$header.outerHeight(true)
-    } else {
-      this.$tableHeader.hide()
-      this.trigger('post-header')
-    }
-
-    if (!this.options.cardView && this.options.showFooter) {
-      this.$tableFooter.show()
-      this.fitFooter()
-      if (this.options.height) {
-        padding += this.$tableFooter.outerHeight(true)
-      }
-    }
-
-    if (this.options.height) {
-      const toolbarHeight = this.$toolbar.outerHeight(true)
-      const paginationHeight = this.$pagination.outerHeight(true)
-      const height = this.options.height - toolbarHeight - paginationHeight
-      const tableHeight = this.$tableBody.find('table').outerHeight(true)
-      this.$tableContainer.css('height', `${height}px`)
-      this.$tableBorder && this.$tableBorder.css('height', `${height - tableHeight - padding - 1}px`)
-    }
+  getOptions () {
+    // deep copy and remove data
+    const options = JSON.parse(JSON.stringify(this.options))
+    delete options.data
+    return options
+  }
 
-    if (this.options.cardView) {
-      // remove the element css
-      this.$el.css('margin-top', '0')
-      this.$tableContainer.css('padding-bottom', '0')
-      this.$tableFooter.hide()
-    } else {
-      // Assign the correct sortable arrow
-      this.getCaret()
-      this.$tableContainer.css('padding-bottom', `${padding}px`)
+  refreshOptions (options) {
+    // If the objects are equivalent then avoid the call of destroy / init methods
+    if (Utils.compareObjects(this.options, options, true)) {
+      return
     }
-
-    this.trigger('reset-view')
+    this.options = $.extend(this.options, options)
+    this.trigger('refresh-options', this.options)
+    this.destroy()
+    this.init()
   }
 
   getData (useCurrentPage) {
@@ -1967,6 +1902,16 @@ class BootstrapTable {
     return data
   }
 
+  getSelections () {
+    // fix #2424: from html with checkbox
+    return this.options.data.filter(row =>
+      row[this.header.stateField] === true)
+  }
+
+  getAllSelections () {
+    return this.options.data.filter(row => row[this.header.stateField])
+  }
+
   load (_data) {
     let fixedScroll = false
     let data = _data
@@ -2047,6 +1992,33 @@ class BootstrapTable {
     }
   }
 
+  insertRow (params) {
+    if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {
+      return
+    }
+    this.options.data.splice(params.index, 0, params.row)
+    this.initSearch()
+    this.initPagination()
+    this.initSort()
+    this.initBody(true)
+  }
+
+  updateRow (params) {
+    const allParams = Array.isArray(params) ? params : [params]
+
+    for (const params of allParams) {
+      if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {
+        continue
+      }
+      $.extend(this.options.data[params.index], params.row)
+    }
+
+    this.initSearch()
+    this.initPagination()
+    this.initSort()
+    this.initBody(true)
+  }
+
   getRowByUniqueId (_id) {
     const uniqueId = this.options.uniqueId
     const len = this.options.data.length
@@ -2086,23 +2058,6 @@ class BootstrapTable {
     return dataRow
   }
 
-  removeByUniqueId (id) {
-    const len = this.options.data.length
-    const row = this.getRowByUniqueId(id)
-
-    if (row) {
-      this.options.data.splice(this.options.data.indexOf(row), 1)
-    }
-
-    if (len === this.options.data.length) {
-      return
-    }
-
-    this.initSearch()
-    this.initPagination()
-    this.initBody(true)
-  }
-
   updateByUniqueId (params) {
     const allParams = Array.isArray(params) ? params : [params]
 
@@ -2125,65 +2080,71 @@ class BootstrapTable {
     this.initBody(true)
   }
 
-  refreshColumnTitle (params) {
-    if (!params.hasOwnProperty('field') || !params.hasOwnProperty('title')) {
+  removeByUniqueId (id) {
+    const len = this.options.data.length
+    const row = this.getRowByUniqueId(id)
+
+    if (row) {
+      this.options.data.splice(this.options.data.indexOf(row), 1)
+    }
+
+    if (len === this.options.data.length) {
       return
     }
 
-    this.columns[this.fieldsColumnsIndex[params.field]].title =
-      this.options.escape ? Utils.escapeHTML(params.title) : params.title
+    this.initSearch()
+    this.initPagination()
+    this.initBody(true)
+  }
 
-    if (this.columns[this.fieldsColumnsIndex[params.field]].visible) {
-      const header = this.options.height !== undefined ? this.$tableHeader : this.$header
-      header.find('th[data-field]').each((i, el) => {
-        if ($(el).data('field') === params.field) {
-          $($(el).find('.th-inner')[0]).text(params.title)
-          return false
-        }
-      })
+  updateCell (params) {
+    if (!params.hasOwnProperty('index') ||
+      !params.hasOwnProperty('field') ||
+      !params.hasOwnProperty('value')) {
+      return
     }
-  }
+    this.data[params.index][params.field] = params.value
 
-  insertRow (params) {
-    if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {
+    if (params.reinit === false) {
       return
     }
-    this.options.data.splice(params.index, 0, params.row)
-    this.initSearch()
-    this.initPagination()
     this.initSort()
     this.initBody(true)
   }
 
-  updateRow (params) {
+  updateCellByUniqueId (params) {
+    if (!params.hasOwnProperty('id') ||
+      !params.hasOwnProperty('field') ||
+      !params.hasOwnProperty('value')) {
+      return
+    }
     const allParams = Array.isArray(params) ? params : [params]
 
-    for (const params of allParams) {
-      if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {
-        continue
+    allParams.forEach(({id, field, value}) => {
+      const rowId = this.options.data.indexOf(this.getRowByUniqueId(id))
+
+      if (rowId === -1) {
+        return
       }
-      $.extend(this.options.data[params.index], params.row)
-    }
+      this.data[rowId][field] = value
+    })
 
-    this.initSearch()
-    this.initPagination()
+    if (params.reinit === false) {
+      return
+    }
     this.initSort()
     this.initBody(true)
   }
 
-  initHiddenRows () {
-    this.hiddenRows = []
-  }
-
   showRow (params) {
-    this.toggleRow(params, true)
+    this._toggleRow(params, true)
   }
 
   hideRow (params) {
-    this.toggleRow(params, false)
+    this._toggleRow(params, false)
   }
 
-  toggleRow (params, visible) {
+  _toggleRow (params, visible) {
     let row
 
     if (params.hasOwnProperty('index')) {
@@ -2224,112 +2185,114 @@ class BootstrapTable {
     return rows
   }
 
-  mergeCells (options) {
-    const row = options.index
-    let col = this.getVisibleFields().indexOf(options.field)
-    const rowspan = options.rowspan || 1
-    const colspan = options.colspan || 1
-    let i
-    let j
-    const $tr = this.$body.find('>tr')
-
-    if (this.options.detailView && !this.options.cardView) {
-      col += 1
-    }
+  showColumn (field) {
+    const fields = Array.isArray(field) ? field : [field]
+    fields.forEach(field => {
+      this._toggleColumn(this.fieldsColumnsIndex[field], true, true)
+    })
+  }
 
-    const $td = $tr.eq(row).find('>td').eq(col)
+  hideColumn (field) {
+    const fields = Array.isArray(field) ? field : [field]
+    fields.forEach(field => {
+      this._toggleColumn(this.fieldsColumnsIndex[field], false, true)
+    })
+  }
 
-    if (row < 0 || col < 0 || row >= this.data.length) {
+  _toggleColumn (index, checked, needUpdate) {
+    if (index === -1) {
       return
     }
+    this.columns[index].visible = checked
+    this.initHeader()
+    this.initSearch()
+    this.initPagination()
+    this.initBody()
 
-    for (i = row; i < row + rowspan; i++) {
-      for (j = col; j < col + colspan; j++) {
-        $tr.eq(i).find('>td').eq(j).hide()
-      }
-    }
+    if (this.options.showColumns) {
+      const $items = this.$toolbar.find('.keep-open input').prop('disabled', false)
 
-    $td.attr('rowspan', rowspan).attr('colspan', colspan).show()
-  }
+      if (needUpdate) {
+        $items.filter(Utils.sprintf('[value="%s"]', index)).prop('checked', checked)
+      }
 
-  updateCell (params) {
-    if (!params.hasOwnProperty('index') ||
-      !params.hasOwnProperty('field') ||
-      !params.hasOwnProperty('value')) {
-      return
+      if ($items.filter(':checked').length <= this.options.minimumCountColumns) {
+        $items.filter(':checked').prop('disabled', true)
+      }
     }
-    this.data[params.index][params.field] = params.value
+  }
 
-    if (params.reinit === false) {
-      return
-    }
-    this.initSort()
-    this.initBody(true)
+  getVisibleColumns () {
+    return this.columns.filter(({visible}) => visible)
   }
 
-  updateCellById (params) {
-    if (!params.hasOwnProperty('id') ||
-      !params.hasOwnProperty('field') ||
-      !params.hasOwnProperty('value')) {
-      return
+  getHiddenColumns () {
+    return this.columns.filter(({visible}) => !visible)
+  }
+
+  showAllColumns () {
+    this._toggleAllColumns(true)
+  }
+
+  hideAllColumns () {
+    this._toggleAllColumns(false)
+  }
+
+  _toggleAllColumns (visible) {
+    for (const column of this.columns) {
+      column.visible = visible
     }
-    const allParams = Array.isArray(params) ? params : [params]
 
-    allParams.forEach(({id, field, value}) => {
-      const rowId = this.options.data.indexOf(this.getRowByUniqueId(id))
+    this.initHeader()
+    this.initSearch()
+    this.initPagination()
+    this.initBody()
+    if (this.options.showColumns) {
+      const $items = this.$toolbar.find('.keep-open input').prop('disabled', false)
 
-      if (rowId === -1) {
-        return
+      if ($items.filter(':checked').length <= this.options.minimumCountColumns) {
+        $items.filter(':checked').prop('disabled', true)
       }
-      this.data[rowId][field] = value
-    })
-
-    if (params.reinit === false) {
-      return
     }
-    this.initSort()
-    this.initBody(true)
   }
 
-  getOptions () {
-    // deep copy and remove data
-    const options = JSON.parse(JSON.stringify(this.options))
-    delete options.data
-    return options
-  }
+  mergeCells (options) {
+    const row = options.index
+    let col = this.getVisibleFields().indexOf(options.field)
+    const rowspan = options.rowspan || 1
+    const colspan = options.colspan || 1
+    let i
+    let j
+    const $tr = this.$body.find('>tr')
 
-  getSelections () {
-    // fix #2424: from html with checkbox
-    return this.options.data.filter(row =>
-      row[this.header.stateField] === true)
-  }
+    if (this.options.detailView && !this.options.cardView) {
+      col += 1
+    }
 
-  getAllSelections () {
-    return this.options.data.filter(row => row[this.header.stateField])
+    const $td = $tr.eq(row).find('>td').eq(col)
+
+    if (row < 0 || col < 0 || row >= this.data.length) {
+      return
+    }
+
+    for (i = row; i < row + rowspan; i++) {
+      for (j = col; j < col + colspan; j++) {
+        $tr.eq(i).find('>td').eq(j).hide()
+      }
+    }
+
+    $td.attr('rowspan', rowspan).attr('colspan', colspan).show()
   }
 
   checkAll () {
-    this.checkAll_(true)
+    this._toggleCheckAll(true)
   }
 
   uncheckAll () {
-    this.checkAll_(false)
-  }
-
-  checkInvert () {
-    const $items = this.$selectItem.filter(':enabled')
-    let checked = $items.filter(':checked')
-    $items.each((i, el) => {
-      $(el).prop('checked', !$(el).prop('checked'))
-    })
-    this.updateRows()
-    this.updateSelected()
-    this.trigger('uncheck-some', checked)
-    checked = this.getSelections()
-    this.trigger('check-some', checked)
+    this._toggleCheckAll(false)
   }
 
-  checkAll_ (checked) {
+  _toggleCheckAll (checked) {
     const rowsBefore = this.getSelections()
     this.$selectAll.add(this.$selectAll_).prop('checked', checked)
     this.$selectItem.filter(':enabled').prop('checked', checked)
@@ -2344,15 +2307,28 @@ class BootstrapTable {
     this.trigger('uncheck-all', rowsAfter, rowsBefore)
   }
 
+  checkInvert () {
+    const $items = this.$selectItem.filter(':enabled')
+    let checked = $items.filter(':checked')
+    $items.each((i, el) => {
+      $(el).prop('checked', !$(el).prop('checked'))
+    })
+    this.updateRows()
+    this.updateSelected()
+    this.trigger('uncheck-some', checked)
+    checked = this.getSelections()
+    this.trigger('check-some', checked)
+  }
+
   check (index) {
-    this.check_(true, index)
+    this._toggleCheck(true, index)
   }
 
   uncheck (index) {
-    this.check_(false, index)
+    this._toggleCheck(false, index)
   }
 
-  check_ (checked, index) {
+  _toggleCheck (checked, index) {
     const $el = this.$selectItem.filter(`[data-index="${index}"]`)
     const row = this.data[index]
 
@@ -2392,14 +2368,14 @@ class BootstrapTable {
   }
 
   checkBy (obj) {
-    this.checkBy_(true, obj)
+    this._toggleCheckBy(true, obj)
   }
 
   uncheckBy (obj) {
-    this.checkBy_(false, obj)
+    this._toggleCheckBy(false, obj)
   }
 
-  checkBy_ (checked, obj) {
+  _toggleCheckBy (checked, obj) {
     if (!obj.hasOwnProperty('field') || !obj.hasOwnProperty('values')) {
       return
     }
@@ -2421,6 +2397,20 @@ class BootstrapTable {
     this.trigger(checked ? 'check-some' : 'uncheck-some', rows)
   }
 
+  refresh (params) {
+    if (params && params.url) {
+      this.options.url = params.url
+    }
+    if (params && params.pageNumber) {
+      this.options.pageNumber = params.pageNumber
+    }
+    if (params && params.pageSize) {
+      this.options.pageSize = params.pageSize
+    }
+    this.trigger('refresh', this.initServer(params && params.silent,
+      params && params.query, params && params.url))
+  }
+
   destroy () {
     this.$el.insertBefore(this.$container)
     $(this.options.toolbar).insertBefore(this.$el)
@@ -2431,39 +2421,56 @@ class BootstrapTable {
       .attr('class', this.$el_.attr('class') || '') // reset the class
   }
 
-  showLoading () {
-    this.$tableLoading.css('display', 'flex')
-  }
+  resetView (params) {
+    let padding = 0
 
-  hideLoading () {
-    this.$tableLoading.css('display', 'none')
-  }
+    if (params && params.height) {
+      this.options.height = params.height
+    }
 
-  togglePagination () {
-    this.options.pagination = !this.options.pagination
-    this.$toolbar.find('button[name="paginationSwitch"]')
-      .html(Utils.sprintf(this.constants.html.icon, this.options.iconsPrefix,
-        this.options.pagination ? this.options.icons.paginationSwitchDown : this.options.icons.paginationSwitchUp))
-    this.updatePagination()
-  }
+    this.$selectAll.prop('checked', this.$selectItem.length > 0 &&
+      this.$selectItem.length === this.$selectItem.filter(':checked').length)
 
-  toggleFullscreen () {
-    this.$el.closest('.bootstrap-table').toggleClass('fullscreen')
-    this.resetView()
-  }
+    this.$tableContainer.toggleClass('has-card-view', this.options.cardView)
 
-  refresh (params) {
-    if (params && params.url) {
-      this.options.url = params.url
+    if (!this.options.cardView && this.options.showHeader && this.options.height) {
+      this.$tableHeader.show()
+      this.resetHeader()
+      padding += this.$header.outerHeight(true)
+    } else {
+      this.$tableHeader.hide()
+      this.trigger('post-header')
     }
-    if (params && params.pageNumber) {
-      this.options.pageNumber = params.pageNumber
+
+    if (!this.options.cardView && this.options.showFooter) {
+      this.$tableFooter.show()
+      this.fitFooter()
+      if (this.options.height) {
+        padding += this.$tableFooter.outerHeight(true)
+      }
     }
-    if (params && params.pageSize) {
-      this.options.pageSize = params.pageSize
+
+    if (this.options.height) {
+      const toolbarHeight = this.$toolbar.outerHeight(true)
+      const paginationHeight = this.$pagination.outerHeight(true)
+      const height = this.options.height - toolbarHeight - paginationHeight
+      const tableHeight = this.$tableBody.find('table').outerHeight(true)
+      this.$tableContainer.css('height', `${height}px`)
+      this.$tableBorder && this.$tableBorder.css('height', `${height - tableHeight - padding - 1}px`)
     }
-    this.trigger('refresh', this.initServer(params && params.silent,
-      params && params.query, params && params.url))
+
+    if (this.options.cardView) {
+      // remove the element css
+      this.$el.css('margin-top', '0')
+      this.$tableContainer.css('padding-bottom', '0')
+      this.$tableFooter.hide()
+    } else {
+      // Assign the correct sortable arrow
+      this.getCaret()
+      this.$tableContainer.css('padding-bottom', `${padding}px`)
+    }
+
+    this.trigger('reset-view')
   }
 
   resetWidth () {
@@ -2475,52 +2482,43 @@ class BootstrapTable {
     }
   }
 
-  showColumn (field) {
-    const fields = Array.isArray(field) ? field : [field]
-    fields.forEach(field => {
-      this.toggleColumn(this.fieldsColumnsIndex[field], true, true)
-    })
+  showLoading () {
+    this.$tableLoading.css('display', 'flex')
   }
 
-  hideColumn (field) {
-    const fields = Array.isArray(field) ? field : [field]
-    fields.forEach(field => {
-      this.toggleColumn(this.fieldsColumnsIndex[field], false, true)
-    })
+  hideLoading () {
+    this.$tableLoading.css('display', 'none')
   }
 
-  getHiddenColumns () {
-    return this.columns.filter(({visible}) => !visible)
+  togglePagination () {
+    this.options.pagination = !this.options.pagination
+    this.$toolbar.find('button[name="paginationSwitch"]')
+      .html(Utils.sprintf(this.constants.html.icon, this.options.iconsPrefix,
+        this.options.pagination ? this.options.icons.paginationSwitchDown : this.options.icons.paginationSwitchUp))
+    this.updatePagination()
   }
 
-  getVisibleColumns () {
-    return this.columns.filter(({visible}) => visible)
+  toggleFullscreen () {
+    this.$el.closest('.bootstrap-table').toggleClass('fullscreen')
+    this.resetView()
   }
 
-  toggleAllColumns (visible) {
-    for (const column of this.columns) {
-      column.visible = visible
-    }
-
+  toggleView () {
+    this.options.cardView = !this.options.cardView
     this.initHeader()
-    this.initSearch()
-    this.initPagination()
+    // Fixed remove toolbar when click cardView button.
+    // this.initToolbar();
+    this.$toolbar.find('button[name="toggle"]')
+      .html(Utils.sprintf(this.constants.html.icon, this.options.iconsPrefix,
+        this.options.cardView ? this.options.icons.toggleOn : this.options.icons.toggleOff))
     this.initBody()
-    if (this.options.showColumns) {
-      const $items = this.$toolbar.find('.keep-open input').prop('disabled', false)
-
-      if ($items.filter(':checked').length <= this.options.minimumCountColumns) {
-        $items.filter(':checked').prop('disabled', true)
-      }
-    }
-  }
-
-  showAllColumns () {
-    this.toggleAllColumns(true)
+    this.trigger('toggle', this.options.cardView)
   }
 
-  hideAllColumns () {
-    this.toggleAllColumns(false)
+  resetSearch (text) {
+    const $search = this.$toolbar.find('.search input')
+    $search.val(text || '')
+    this.onSearch({currentTarget: $search})
   }
 
   filterBy (columns, options) {
@@ -2581,33 +2579,16 @@ class BootstrapTable {
     }
   }
 
-  toggleView () {
-    this.options.cardView = !this.options.cardView
-    this.initHeader()
-    // Fixed remove toolbar when click cardView button.
-    // this.initToolbar();
-    this.$toolbar.find('button[name="toggle"]')
-      .html(Utils.sprintf(this.constants.html.icon, this.options.iconsPrefix,
-        this.options.cardView ? this.options.icons.toggleOn : this.options.icons.toggleOff))
-    this.initBody()
-    this.trigger('toggle', this.options.cardView)
-  }
+  toggleDetailView (index, _columnDetailFormatter) {
+    const $tr = this.$body.find(Utils.sprintf('> tr[data-index="%s"]', index))
 
-  refreshOptions (options) {
-    // If the objects are equivalent then avoid the call of destroy / init methods
-    if (Utils.compareObjects(this.options, options, true)) {
-      return
+    if ($tr.next().is('tr.detail-view')) {
+      this.collapseRow(index)
+    } else {
+      this.expandRow(index, _columnDetailFormatter)
     }
-    this.options = $.extend(this.options, options)
-    this.trigger('refresh-options', this.options)
-    this.destroy()
-    this.init()
-  }
 
-  resetSearch (text) {
-    const $search = this.$toolbar.find('.search input')
-    $search.val(text || '')
-    this.onSearch({currentTarget: $search})
+    this.resetView()
   }
 
   expandRow (index, _columnDetailFormatter) {
@@ -2663,6 +2644,25 @@ class BootstrapTable {
     }
   }
 
+  updateColumnTitle (params) {
+    if (!params.hasOwnProperty('field') || !params.hasOwnProperty('title')) {
+      return
+    }
+
+    this.columns[this.fieldsColumnsIndex[params.field]].title =
+      this.options.escape ? Utils.escapeHTML(params.title) : params.title
+
+    if (this.columns[this.fieldsColumnsIndex[params.field]].visible) {
+      const header = this.options.height !== undefined ? this.$tableHeader : this.$header
+      header.find('th[data-field]').each((i, el) => {
+        if ($(el).data('field') === params.field) {
+          $($(el).find('.th-inner')[0]).text(params.title)
+          return false
+        }
+      })
+    }
+  }
+
   updateFormatText (formatName, text) {
     if (!/^format/.test(formatName) || !this.options[formatName]) {
       return

+ 20 - 19
src/constants/index.js

@@ -371,34 +371,35 @@ const COLUMN_DEFAULTS = {
 
 const METHODS = [
   'getOptions',
-  'getSelections', 'getAllSelections', 'getData',
-  'load', 'append', 'prepend', 'remove', 'removeAll',
-  'insertRow', 'updateRow', 'updateCell',
-  'updateByUniqueId', 'removeByUniqueId',
-  'getRowByUniqueId', 'showRow', 'hideRow', 'getHiddenRows',
-  'mergeCells', 'refreshColumnTitle',
+  'refreshOptions',
+  'getData',
+  'getSelections', 'getAllSelections',
+  'load', 'append', 'prepend',
+  'remove', 'removeAll',
+  'insertRow', 'updateRow',
+  'getRowByUniqueId', 'updateByUniqueId', 'removeByUniqueId',
+  'updateCell', 'updateCellByUniqueId',
+  'showRow', 'hideRow', 'getHiddenRows',
+  'showColumn', 'hideColumn',
+  'getVisibleColumns', 'getHiddenColumns',
+  'showAllColumns', 'hideAllColumns',
+  'mergeCells',
   'checkAll', 'uncheckAll', 'checkInvert',
   'check', 'uncheck',
   'checkBy', 'uncheckBy',
   'refresh',
-  'resetView',
-  'resetWidth',
   'destroy',
+  'resetView', 'resetWidth',
   'showLoading', 'hideLoading',
-  'showColumn', 'hideColumn',
-  'getHiddenColumns', 'getVisibleColumns',
-  'showAllColumns', 'hideAllColumns',
+  'togglePagination', 'toggleFullscreen', 'toggleView',
+  'resetSearch',
   'filterBy',
-  'scrollTo',
-  'getScrollPosition',
+  'scrollTo', 'getScrollPosition',
   'selectPage', 'prevPage', 'nextPage',
-  'togglePagination',
-  'toggleView',
-  'refreshOptions',
-  'resetSearch',
-  'expandRow', 'collapseRow', 'toggleDetailView',
+  'toggleDetailView',
+  'expandRow', 'collapseRow',
   'expandAllRows', 'collapseAllRows',
-  'updateFormatText', 'updateCellById'
+  'updateColumnTitle', 'updateFormatText'
 ]
 
 const EVENTS = {

+ 2 - 2
tools/check-api.js

@@ -68,7 +68,7 @@ class ColumnOptions extends API {
   init () {
     this.file = 'column-options.md'
     this.options = Object.keys(Constants.COLUMN_DEFAULTS)
-    this.attributes = ['Attribute', 'Type', 'Detail', 'Default' , 'Example']
+    this.attributes = ['Attribute', 'Type', 'Detail', 'Default', 'Example']
   }
 }
 
@@ -76,7 +76,7 @@ class Methods extends API {
   init () {
     this.file = 'methods.md'
     this.options = Constants.METHODS
-    this.attributes = ['Parameter', 'Detail']// , 'Example']
+    this.attributes = ['Parameter', 'Detail']//, 'Example']
   }
 }