bootstrap table支持高度百分比的实例代码


Posted in Javascript onFebruary 28, 2018

更改BootstrapTable.prototype.resetView 方法,以支持高度百分比定义,适应不同高度屏幕

BootstrapTable.prototype.resetView = function (params) {
    var 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);
    if (this.options.height) {
      var toolbarHeight = this.$toolbar.outerHeight(true),
        paginationHeight = this.$pagination.outerHeight(true),
        height = this.options.height;


 //关键代码
      if (this.options.height.toString().indexOf("%") != -1) {
        height = $(window).height() * (parseFloat(this.options.height) / 100);
      }
      height = height - toolbarHeight - paginationHeight;
      this.$tableContainer.css('height', height + 'px');
    }
    if (this.options.cardView) {
      // remove the element css
      this.$el.css('margin-top', '0');
      this.$tableContainer.css('padding-bottom', '0');
      this.$tableFooter.hide();
      return;
    }
    if (this.options.showHeader && this.options.height) {
      this.$tableHeader.show();
      this.resetHeader();
      padding += this.$header.outerHeight();
    } else {
      this.$tableHeader.hide();
      this.trigger('post-header');
    }
    if (this.options.showFooter) {
      this.resetFooter();
      if (this.options.height) {
        padding += this.$tableFooter.outerHeight() + 1;
      }
    }
    // Assign the correct sortable arrow
    this.getCaret();
    this.$tableContainer.css('padding-bottom', padding + 'px');
    this.trigger('reset-view');
  };

更改后的bootstrap-table.js的完整代码:

 

/**
 * @author zhixin wen <wenzhixin2010@gmail.com>
 * version: 1.11.1
 * https://github.com/wenzhixin/bootstrap-table/
 */
(function ($) {
  'use strict';
  // TOOLS DEFINITION
  // ======================
  var cachedWidth = null;
  // it only does '%s', and return '' when arguments are undefined
  var sprintf = function (str) {
    var args = arguments,
      flag = true,
      i = 1;
    str = str.replace(/%s/g, function () {
      var arg = args[i++];
      if (typeof arg === 'undefined') {
        flag = false;
        return '';
      }
      return arg;
    });
    return flag ? str : '';
  };
  var getPropertyFromOther = function (list, from, to, value) {
    var result = '';
    $.each(list, function (i, item) {
      if (item[from] === value) {
        result = item[to];
        return false;
      }
      return true;
    });
    return result;
  };
  var getFieldIndex = function (columns, field) {
    var index = -1;
    $.each(columns, function (i, column) {
      if (column.field === field) {
        index = i;
        return false;
      }
      return true;
    });
    return index;
  };
  // http://jsfiddle.net/wenyi/47nz7ez9/3/
  var setFieldIndex = function (columns) {
    var i, j, k,
      totalCol = 0,
      flag = [];
    for (i = 0; i < columns[0].length; i++) {
      totalCol += columns[0][i].colspan || 1;
    }
    for (i = 0; i < columns.length; i++) {
      flag[i] = [];
      for (j = 0; j < totalCol; j++) {
        flag[i][j] = false;
      }
    }
    for (i = 0; i < columns.length; i++) {
      for (j = 0; j < columns[i].length; j++) {
        var r = columns[i][j],
          rowspan = r.rowspan || 1,
          colspan = r.colspan || 1,
          index = $.inArray(false, flag[i]);
        if (colspan === 1) {
          r.fieldIndex = index;
          // when field is undefined, use index instead
          if (typeof r.field === 'undefined') {
            r.field = index;
          }
        }
        for (k = 0; k < rowspan; k++) {
          flag[i + k][index] = true;
        }
        for (k = 0; k < colspan; k++) {
          flag[i][index + k] = true;
        }
      }
    }
  };
  var getScrollBarWidth = function () {
    if (cachedWidth === null) {
      var inner = $('<p/>').addClass('fixed-table-scroll-inner'),
        outer = $('<div/>').addClass('fixed-table-scroll-outer'),
        w1, w2;
      outer.append(inner);
      $('body').append(outer);
      w1 = inner[0].offsetWidth;
      outer.css('overflow', 'scroll');
      w2 = inner[0].offsetWidth;
      if (w1 === w2) {
        w2 = outer[0].clientWidth;
      }
      outer.remove();
      cachedWidth = w1 - w2;
    }
    return cachedWidth;
  };
  var calculateObjectValue = function (self, name, args, defaultValue) {
    var func = name;
    if (typeof name === 'string') {
      // support obj.func1.func2
      var names = name.split('.');
      if (names.length > 1) {
        func = window;
        $.each(names, function (i, f) {
          func = func[f];
        });
      } else {
        func = window[name];
      }
    }
    if (typeof func === 'object') {
      return func;
    }
    if (typeof func === 'function') {
      return func.apply(self, args || []);
    }
    if (!func && typeof name === 'string' && sprintf.apply(this, [name].concat(args))) {
      return sprintf.apply(this, [name].concat(args));
    }
    return defaultValue;
  };
  var compareObjects = function (objectA, objectB, compareLength) {
    // Create arrays of property names
    var objectAProperties = Object.getOwnPropertyNames(objectA),
      objectBProperties = Object.getOwnPropertyNames(objectB),
      propName = '';
    if (compareLength) {
      // If number of properties is different, objects are not equivalent
      if (objectAProperties.length !== objectBProperties.length) {
        return false;
      }
    }
    for (var i = 0; i < objectAProperties.length; i++) {
      propName = objectAProperties[i];
      // If the property is not in the object B properties, continue with the next property
      if ($.inArray(propName, objectBProperties) > -1) {
        // If values of same property are not equal, objects are not equivalent
        if (objectA[propName] !== objectB[propName]) {
          return false;
        }
      }
    }
    // If we made it this far, objects are considered equivalent
    return true;
  };
  var escapeHTML = function (text) {
    if (typeof text === 'string') {
      return text
        .replace(/&/g, '&')
        .replace(/</g, '<')
        .replace(/>/g, '>')
        .replace(/"/g, '"')
        .replace(/'/g, ''')
        .replace(/`/g, '`');
    }
    return text;
  };
  var getRealDataAttr = function (dataAttr) {
    for (var attr in dataAttr) {
      var auxAttr = attr.split(/(?=[A-Z])/).join('-').toLowerCase();
      if (auxAttr !== attr) {
        dataAttr[auxAttr] = dataAttr[attr];
        delete dataAttr[attr];
      }
    }
    return dataAttr;
  };
  var getItemField = function (item, field, escape) {
    var value = item;
    if (typeof field !== 'string' || item.hasOwnProperty(field)) {
      return escape ? escapeHTML(item[field]) : item[field];
    }
    var props = field.split('.');
    for (var p in props) {
      if (props.hasOwnProperty(p)) {
        value = value && value[props[p]];
      }
    }
    return escape ? escapeHTML(value) : value;
  };
  var isIEBrowser = function () {
    return !!(navigator.userAgent.indexOf("MSIE ") > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./));
  };
  var objectKeys = function () {
    // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
    if (!Object.keys) {
      Object.keys = (function () {
        var hasOwnProperty = Object.prototype.hasOwnProperty,
          hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
          dontEnums = [
            'toString',
            'toLocaleString',
            'valueOf',
            'hasOwnProperty',
            'isPrototypeOf',
            'propertyIsEnumerable',
            'constructor'
          ],
          dontEnumsLength = dontEnums.length;
        return function (obj) {
          if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
            throw new TypeError('Object.keys called on non-object');
          }
          var result = [], prop, i;
          for (prop in obj) {
            if (hasOwnProperty.call(obj, prop)) {
              result.push(prop);
            }
          }
          if (hasDontEnumBug) {
            for (i = 0; i < dontEnumsLength; i++) {
              if (hasOwnProperty.call(obj, dontEnums[i])) {
                result.push(dontEnums[i]);
              }
            }
          }
          return result;
        };
      }());
    }
  };
  // BOOTSTRAP TABLE CLASS DEFINITION
  // ======================
  var BootstrapTable = function (el, options) {
    this.options = options;
    this.$el = $(el);
    this.$el_ = this.$el.clone();
    this.timeoutId_ = 0;
    this.timeoutFooter_ = 0;
    this.init();
  };
  BootstrapTable.DEFAULTS = {
    classes: 'table table-hover',
    sortClass: undefined,
    locale: undefined,
    height: undefined,
    undefinedText: '-',
    sortName: undefined,
    sortOrder: 'asc',
    sortStable: false,
    striped: false,
    columns: [[]],
    data: [],
    totalField: 'total',
    dataField: 'rows',
    method: 'get',
    url: undefined,
    ajax: undefined,
    cache: true,
    contentType: 'application/json',
    dataType: 'json',
    ajaxOptions: {},
    queryParams: function (params) {
      return params;
    },
    queryParamsType: 'limit', // undefined
    responseHandler: function (res) {
      return res;
    },
    pagination: false,
    onlyInfoPagination: false,
    paginationLoop: true,
    sidePagination: 'client', // client or server
    totalRows: 0, // server side need to set
    pageNumber: 1,
    pageSize: 10,
    pageList: [10, 25, 50, 100],
    paginationHAlign: 'right', //right, left
    paginationVAlign: 'bottom', //bottom, top, both
    paginationDetailHAlign: 'left', //right, left
    paginationPreText: '‹',
    paginationNextText: '›',
    search: false,
    searchOnEnterKey: false,
    strictSearch: false,
    searchAlign: 'right',
    selectItemName: 'btSelectItem',
    showHeader: true,
    showFooter: false,
    showColumns: false,
    showPaginationSwitch: false,
    showRefresh: false,
    showToggle: false,
    buttonsAlign: 'right',
    smartDisplay: true,
    escape: false,
    minimumCountColumns: 1,
    idField: undefined,
    uniqueId: undefined,
    cardView: false,
    detailView: false,
    detailFormatter: function (index, row) {
      return '';
    },
    trimOnSearch: true,
    clickToSelect: false,
    singleSelect: false,
    toolbar: undefined,
    toolbarAlign: 'left',
    checkboxHeader: true,
    sortable: true,
    silentSort: true,
    maintainSelected: false,
    searchTimeOut: 500,
    searchText: '',
    iconSize: undefined,
    buttonsClass: 'default',
    iconsPrefix: 'glyphicon', // glyphicon of fa (font awesome)
    icons: {
      paginationSwitchDown: 'glyphicon-collapse-down icon-chevron-down',
      paginationSwitchUp: 'glyphicon-collapse-up icon-chevron-up',
      refresh: 'glyphicon-refresh icon-refresh',
      toggle: 'glyphicon-list-alt icon-list-alt',
      columns: 'glyphicon-th icon-th',
      detailOpen: 'glyphicon-plus icon-plus',
      detailClose: 'glyphicon-minus icon-minus'
    },
    customSearch: $.noop,
    customSort: $.noop,
    rowStyle: function (row, index) {
      return {};
    },
    rowAttributes: function (row, index) {
      return {};
    },
    footerStyle: function (row, index) {
      return {};
    },
    onAll: function (name, args) {
      return false;
    },
    onClickCell: function (field, value, row, $element) {
      return false;
    },
    onDblClickCell: function (field, value, row, $element) {
      return false;
    },
    onClickRow: function (item, $element) {
      return false;
    },
    onDblClickRow: function (item, $element) {
      return false;
    },
    onSort: function (name, order) {
      return false;
    },
    onCheck: function (row) {
      return false;
    },
    onUncheck: function (row) {
      return false;
    },
    onCheckAll: function (rows) {
      return false;
    },
    onUncheckAll: function (rows) {
      return false;
    },
    onCheckSome: function (rows) {
      return false;
    },
    onUncheckSome: function (rows) {
      return false;
    },
    onLoadSuccess: function (data) {
      return false;
    },
    onLoadError: function (status) {
      return false;
    },
    onColumnSwitch: function (field, checked) {
      return false;
    },
    onPageChange: function (number, size) {
      return false;
    },
    onSearch: function (text) {
      return false;
    },
    onToggle: function (cardView) {
      return false;
    },
    onPreBody: function (data) {
      return false;
    },
    onPostBody: function () {
      return false;
    },
    onPostHeader: function () {
      return false;
    },
    onExpandRow: function (index, row, $detail) {
      return false;
    },
    onCollapseRow: function (index, row) {
      return false;
    },
    onRefreshOptions: function (options) {
      return false;
    },
    onRefresh: function (params) {
      return false;
    },
    onResetView: function () {
      return false;
    }
  };
  BootstrapTable.LOCALES = {};
  BootstrapTable.LOCALES['en-US'] = BootstrapTable.LOCALES.en = {
    formatLoadingMessage: function () {
      return 'Loading, please wait...';
    },
    formatRecordsPerPage: function (pageNumber) {
      return sprintf('%s rows per page', pageNumber);
    },
    formatShowingRows: function (pageFrom, pageTo, totalRows) {
      return sprintf('Showing %s to %s of %s rows', pageFrom, pageTo, totalRows);
    },
    formatDetailPagination: function (totalRows) {
      return sprintf('Showing %s rows', totalRows);
    },
    formatSearch: function () {
      return 'Search';
    },
    formatNoMatches: function () {
      return 'No matching records found';
    },
    formatPaginationSwitch: function () {
      return 'Hide/Show pagination';
    },
    formatRefresh: function () {
      return 'Refresh';
    },
    formatToggle: function () {
      return 'Toggle';
    },
    formatColumns: function () {
      return 'Columns';
    },
    formatAllRows: function () {
      return 'All';
    }
  };
  $.extend(BootstrapTable.DEFAULTS, BootstrapTable.LOCALES['en-US']);
  BootstrapTable.COLUMN_DEFAULTS = {
    radio: false,
    checkbox: false,
    checkboxEnabled: true,
    field: undefined,
    title: undefined,
    titleTooltip: undefined,
    'class': undefined,
    align: undefined, // left, right, center
    halign: undefined, // left, right, center
    falign: undefined, // left, right, center
    valign: undefined, // top, middle, bottom
    width: undefined,
    sortable: false,
    order: 'asc', // asc, desc
    visible: true,
    switchable: true,
    clickToSelect: true,
    formatter: undefined,
    footerFormatter: undefined,
    events: undefined,
    sorter: undefined,
    sortName: undefined,
    cellStyle: undefined,
    searchable: true,
    searchFormatter: true,
    cardVisible: true,
    escape: false
  };
  BootstrapTable.EVENTS = {
    'all.bs.table': 'onAll',
    'click-cell.bs.table': 'onClickCell',
    'dbl-click-cell.bs.table': 'onDblClickCell',
    'click-row.bs.table': 'onClickRow',
    'dbl-click-row.bs.table': 'onDblClickRow',
    'sort.bs.table': 'onSort',
    'check.bs.table': 'onCheck',
    'uncheck.bs.table': 'onUncheck',
    'check-all.bs.table': 'onCheckAll',
    'uncheck-all.bs.table': 'onUncheckAll',
    'check-some.bs.table': 'onCheckSome',
    'uncheck-some.bs.table': 'onUncheckSome',
    'load-success.bs.table': 'onLoadSuccess',
    'load-error.bs.table': 'onLoadError',
    'column-switch.bs.table': 'onColumnSwitch',
    'page-change.bs.table': 'onPageChange',
    'search.bs.table': 'onSearch',
    'toggle.bs.table': 'onToggle',
    'pre-body.bs.table': 'onPreBody',
    'post-body.bs.table': 'onPostBody',
    'post-header.bs.table': 'onPostHeader',
    'expand-row.bs.table': 'onExpandRow',
    'collapse-row.bs.table': 'onCollapseRow',
    'refresh-options.bs.table': 'onRefreshOptions',
    'reset-view.bs.table': 'onResetView',
    'refresh.bs.table': 'onRefresh'
  };
  BootstrapTable.prototype.init = function () {
    this.initLocale();
    this.initContainer();
    this.initTable();
    this.initHeader();
    this.initData();
    this.initHiddenRows();
    this.initFooter();
    this.initToolbar();
    this.initPagination();
    this.initBody();
    this.initSearchText();
    this.initServer();
  };
  BootstrapTable.prototype.initLocale = function () {
    if (this.options.locale) {
      var parts = this.options.locale.split(/-|_/);
      parts[0].toLowerCase();
      if (parts[1]) parts[1].toUpperCase();
      if ($.fn.bootstrapTable.locales[this.options.locale]) {
        // locale as requested
        $.extend(this.options, $.fn.bootstrapTable.locales[this.options.locale]);
      } else if ($.fn.bootstrapTable.locales[parts.join('-')]) {
        // locale with sep set to - (in case original was specified with _)
        $.extend(this.options, $.fn.bootstrapTable.locales[parts.join('-')]);
      } else if ($.fn.bootstrapTable.locales[parts[0]]) {
        // short locale language code (i.e. 'en')
        $.extend(this.options, $.fn.bootstrapTable.locales[parts[0]]);
      }
    }
  };
  BootstrapTable.prototype.initContainer = function () {
    this.$container = $([
      '<div class="bootstrap-table">',
      '<div class="fixed-table-toolbar"></div>',
      this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ?
        '<div class="fixed-table-pagination" style="clear: both;"></div>' :
        '',
      '<div class="fixed-table-container">',
      '<div class="fixed-table-header"><table></table></div>',
      '<div class="fixed-table-body">',
      '<div class="fixed-table-loading">',
      this.options.formatLoadingMessage(),
      '</div>',
      '</div>',
      '<div class="fixed-table-footer"><table><tr></tr></table></div>',
      this.options.paginationVAlign === 'bottom' || this.options.paginationVAlign === 'both' ?
        '<div class="fixed-table-pagination"></div>' :
        '',
      '</div>',
      '</div>'
    ].join(''));
    this.$container.insertAfter(this.$el);
    this.$tableContainer = this.$container.find('.fixed-table-container');
    this.$tableHeader = this.$container.find('.fixed-table-header');
    this.$tableBody = this.$container.find('.fixed-table-body');
    this.$tableLoading = this.$container.find('.fixed-table-loading');
    this.$tableFooter = this.$container.find('.fixed-table-footer');
    this.$toolbar = this.$container.find('.fixed-table-toolbar');
    this.$pagination = this.$container.find('.fixed-table-pagination');
    this.$tableBody.append(this.$el);
    this.$container.after('<div class="clearfix"></div>');
    this.$el.addClass(this.options.classes);
    if (this.options.striped) {
      this.$el.addClass('table-striped');
    }
    if ($.inArray('table-no-bordered', this.options.classes.split(' ')) !== -1) {
      this.$tableContainer.addClass('table-no-bordered');
    }
  };
  BootstrapTable.prototype.initTable = function () {
    var that = this,
      columns = [],
      data = [];
    this.$header = this.$el.find('>thead');
    if (!this.$header.length) {
      this.$header = $('<thead></thead>').appendTo(this.$el);
    }
    this.$header.find('tr').each(function () {
      var column = [];
      $(this).find('th').each(function () {
        // Fix #2014 - getFieldIndex and elsewhere assume this is string, causes issues if not
        if (typeof $(this).data('field') !== 'undefined') {
          $(this).data('field', $(this).data('field') + '');
        }
        column.push($.extend({}, {
          title: $(this).html(),
          'class': $(this).attr('class'),
          titleTooltip: $(this).attr('title'),
          rowspan: $(this).attr('rowspan') ? +$(this).attr('rowspan') : undefined,
          colspan: $(this).attr('colspan') ? +$(this).attr('colspan') : undefined
        }, $(this).data()));
      });
      columns.push(column);
    });
    if (!$.isArray(this.options.columns[0])) {
      this.options.columns = [this.options.columns];
    }
    this.options.columns = $.extend(true, [], columns, this.options.columns);
    this.columns = [];
    setFieldIndex(this.options.columns);
    $.each(this.options.columns, function (i, columns) {
      $.each(columns, function (j, column) {
        column = $.extend({}, BootstrapTable.COLUMN_DEFAULTS, column);
        if (typeof column.fieldIndex !== 'undefined') {
          that.columns[column.fieldIndex] = column;
        }
        that.options.columns[i][j] = column;
      });
    });
    // if options.data is setting, do not process tbody data
    if (this.options.data.length) {
      return;
    }
    var m = [];
    this.$el.find('>tbody>tr').each(function (y) {
      var row = {};
      // save tr's id, class and data-* attributes
      row._id = $(this).attr('id');
      row._class = $(this).attr('class');
      row._data = getRealDataAttr($(this).data());
      $(this).find('>td').each(function (x) {
        var $this = $(this),
          cspan = +$this.attr('colspan') || 1,
          rspan = +$this.attr('rowspan') || 1,
          tx, ty;
        for (; m[y] && m[y][x]; x++); //skip already occupied cells in current row
        for (tx = x; tx < x + cspan; tx++) { //mark matrix elements occupied by current cell with true
          for (ty = y; ty < y + rspan; ty++) {
            if (!m[ty]) { //fill missing rows
              m[ty] = [];
            }
            m[ty][tx] = true;
          }
        }
        var field = that.columns[x].field;
        row[field] = $(this).html();
        // save td's id, class and data-* attributes
        row['_' + field + '_id'] = $(this).attr('id');
        row['_' + field + '_class'] = $(this).attr('class');
        row['_' + field + '_rowspan'] = $(this).attr('rowspan');
        row['_' + field + '_colspan'] = $(this).attr('colspan');
        row['_' + field + '_title'] = $(this).attr('title');
        row['_' + field + '_data'] = getRealDataAttr($(this).data());
      });
      data.push(row);
    });
    this.options.data = data;
    if (data.length) this.fromHtml = true;
  };
  BootstrapTable.prototype.initHeader = function () {
    var that = this,
      visibleColumns = {},
      html = [];
    this.header = {
      fields: [],
      styles: [],
      classes: [],
      formatters: [],
      events: [],
      sorters: [],
      sortNames: [],
      cellStyles: [],
      searchables: []
    };
    $.each(this.options.columns, function (i, columns) {
      html.push('<tr>');
      if (i === 0 && !that.options.cardView && that.options.detailView) {
        html.push(sprintf('<th class="detail" rowspan="%s"><div class="fht-cell"></div></th>',
          that.options.columns.length));
      }
      $.each(columns, function (j, column) {
        var text = '',
          halign = '', // header align style
          align = '', // body align style
          style = '',
          class_ = sprintf(' class="%s"', column['class']),
          order = that.options.sortOrder || column.order,
          unitWidth = 'px',
          width = column.width;
        if (column.width !== undefined && (!that.options.cardView)) {
          if (typeof column.width === 'string') {
            if (column.width.indexOf('%') !== -1) {
              unitWidth = '%';
            }
          }
        }
        if (column.width && typeof column.width === 'string') {
          width = column.width.replace('%', '').replace('px', '');
        }
        halign = sprintf('text-align: %s; ', column.halign ? column.halign : column.align);
        align = sprintf('text-align: %s; ', column.align);
        style = sprintf('vertical-align: %s; ', column.valign);
        style += sprintf('width: %s; ', (column.checkbox || column.radio) && !width ?
          '36px' : (width ? width + unitWidth : undefined));
        if (typeof column.fieldIndex !== 'undefined') {
          that.header.fields[column.fieldIndex] = column.field;
          that.header.styles[column.fieldIndex] = align + style;
          that.header.classes[column.fieldIndex] = class_;
          that.header.formatters[column.fieldIndex] = column.formatter;
          that.header.events[column.fieldIndex] = column.events;
          that.header.sorters[column.fieldIndex] = column.sorter;
          that.header.sortNames[column.fieldIndex] = column.sortName;
          that.header.cellStyles[column.fieldIndex] = column.cellStyle;
          that.header.searchables[column.fieldIndex] = column.searchable;
          if (!column.visible) {
            return;
          }
          if (that.options.cardView && (!column.cardVisible)) {
            return;
          }
          visibleColumns[column.field] = column;
        }
        html.push('<th' + sprintf(' title="%s"', column.titleTooltip),
          column.checkbox || column.radio ?
            sprintf(' class="bs-checkbox %s"', column['class'] || '') :
            class_,
          sprintf(' style="%s"', halign + style),
          sprintf(' rowspan="%s"', column.rowspan),
          sprintf(' colspan="%s"', column.colspan),
          sprintf(' data-field="%s"', column.field),
          '>');
        html.push(sprintf('<div class="th-inner %s">', that.options.sortable && column.sortable ?
          'sortable both' : ''));
        text = that.options.escape ? escapeHTML(column.title) : column.title;
        if (column.checkbox) {
          if (!that.options.singleSelect && that.options.checkboxHeader) {
            text = '<input name="btSelectAll" type="checkbox" />';
          }
          that.header.stateField = column.field;
        }
        if (column.radio) {
          text = '';
          that.header.stateField = column.field;
          that.options.singleSelect = true;
        }
        html.push(text);
        html.push('</div>');
        html.push('<div class="fht-cell"></div>');
        html.push('</div>');
        html.push('</th>');
      });
      html.push('</tr>');
    });
    this.$header.html(html.join(''));
    this.$header.find('th[data-field]').each(function (i) {
      $(this).data(visibleColumns[$(this).data('field')]);
    });
    this.$container.off('click', '.th-inner').on('click', '.th-inner', function (event) {
      var target = $(this);
      if (that.options.detailView) {
        if (target.closest('.bootstrap-table')[0] !== that.$container[0])
          return false;
      }
      if (that.options.sortable && target.parent().data().sortable) {
        that.onSort(event);
      }
    });
    this.$header.children().children().off('keypress').on('keypress', function (event) {
      if (that.options.sortable && $(this).data().sortable) {
        var code = event.keyCode || event.which;
        if (code == 13) { //Enter keycode
          that.onSort(event);
        }
      }
    });
    $(window).off('resize.bootstrap-table');
    if (!this.options.showHeader || this.options.cardView) {
      this.$header.hide();
      this.$tableHeader.hide();
      this.$tableLoading.css('top', 0);
    } else {
      this.$header.show();
      this.$tableHeader.show();
      this.$tableLoading.css('top', this.$header.outerHeight() + 1);
      // Assign the correct sortable arrow
      this.getCaret();
      $(window).on('resize.bootstrap-table', $.proxy(this.resetWidth, this));
    }
    this.$selectAll = this.$header.find('[name="btSelectAll"]');
    this.$selectAll.off('click').on('click', function () {
      var checked = $(this).prop('checked');
      that[checked ? 'checkAll' : 'uncheckAll']();
      that.updateSelected();
    });
  };
  BootstrapTable.prototype.initFooter = function () {
    if (!this.options.showFooter || this.options.cardView) {
      this.$tableFooter.hide();
    } else {
      this.$tableFooter.show();
    }
  };
  /**
   * @param data
   * @param type: append / prepend
   */
  BootstrapTable.prototype.initData = function (data, type) {
    if (type === 'append') {
      this.data = this.data.concat(data);
    } else if (type === 'prepend') {
      this.data = [].concat(data).concat(this.data);
    } else {
      this.data = data || this.options.data;
    }
    // Fix #839 Records deleted when adding new row on filtered table
    if (type === 'append') {
      this.options.data = this.options.data.concat(data);
    } else if (type === 'prepend') {
      this.options.data = [].concat(data).concat(this.options.data);
    } else {
      this.options.data = this.data;
    }
    if (this.options.sidePagination === 'server') {
      return;
    }
    this.initSort();
  };
  BootstrapTable.prototype.initSort = function () {
    var that = this,
      name = this.options.sortName,
      order = this.options.sortOrder === 'desc' ? -1 : 1,
      index = $.inArray(this.options.sortName, this.header.fields),
      timeoutId = 0;
    if (this.options.customSort !== $.noop) {
      this.options.customSort.apply(this, [this.options.sortName, this.options.sortOrder]);
      return;
    }
    if (index !== -1) {
      if (this.options.sortStable) {
        $.each(this.data, function (i, row) {
          if (!row.hasOwnProperty('_position')) row._position = i;
        });
      }
      this.data.sort(function (a, b) {
        if (that.header.sortNames[index]) {
          name = that.header.sortNames[index];
        }
        var aa = getItemField(a, name, that.options.escape),
          bb = getItemField(b, name, that.options.escape),
          value = calculateObjectValue(that.header, that.header.sorters[index], [aa, bb]);
        if (value !== undefined) {
          return order * value;
        }
        // Fix #161: undefined or null string sort bug.
        if (aa === undefined || aa === null) {
          aa = '';
        }
        if (bb === undefined || bb === null) {
          bb = '';
        }
        if (that.options.sortStable && aa === bb) {
          aa = a._position;
          bb = b._position;
        }
        // IF both values are numeric, do a numeric comparison
        if ($.isNumeric(aa) && $.isNumeric(bb)) {
          // Convert numerical values form string to float.
          aa = parseFloat(aa);
          bb = parseFloat(bb);
          if (aa < bb) {
            return order * -1;
          }
          return order;
        }
        if (aa === bb) {
          return 0;
        }
        // If value is not a string, convert to string
        if (typeof aa !== 'string') {
          aa = aa.toString();
        }
        if (aa.localeCompare(bb) === -1) {
          return order * -1;
        }
        return order;
      });
      if (this.options.sortClass !== undefined) {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(function () {
          that.$el.removeClass(that.options.sortClass);
          var index = that.$header.find(sprintf('[data-field="%s"]',
            that.options.sortName).index() + 1);
          that.$el.find(sprintf('tr td:nth-child(%s)', index))
            .addClass(that.options.sortClass);
        }, 250);
      }
    }
  };
  BootstrapTable.prototype.onSort = function (event) {
    var $this = event.type === "keypress" ? $(event.currentTarget) : $(event.currentTarget).parent(),
      $this_ = this.$header.find('th').eq($this.index());
    this.$header.add(this.$header_).find('span.order').remove();
    if (this.options.sortName === $this.data('field')) {
      this.options.sortOrder = this.options.sortOrder === 'asc' ? 'desc' : 'asc';
    } else {
      this.options.sortName = $this.data('field');
      this.options.sortOrder = $this.data('order') === 'asc' ? 'desc' : 'asc';
    }
    this.trigger('sort', this.options.sortName, this.options.sortOrder);
    $this.add($this_).data('order', this.options.sortOrder);
    // Assign the correct sortable arrow
    this.getCaret();
    if (this.options.sidePagination === 'server') {
      this.initServer(this.options.silentSort);
      return;
    }
    this.initSort();
    this.initBody();
  };
  BootstrapTable.prototype.initToolbar = function () {
    var that = this,
      html = [],
      timeoutId = 0,
      $keepOpen,
      $search,
      switchableCount = 0;
    if (this.$toolbar.find('.bs-bars').children().length) {
      $('body').append($(this.options.toolbar));
    }
    this.$toolbar.html('');
    if (typeof this.options.toolbar === 'string' || typeof this.options.toolbar === 'object') {
      $(sprintf('<div class="bs-bars pull-%s"></div>', this.options.toolbarAlign))
        .appendTo(this.$toolbar)
        .append($(this.options.toolbar));
    }
    // showColumns, showToggle, showRefresh
    html = [sprintf('<div class="columns columns-%s btn-group pull-%s">',
      this.options.buttonsAlign, this.options.buttonsAlign)];
    if (typeof this.options.icons === 'string') {
      this.options.icons = calculateObjectValue(null, this.options.icons);
    }
    if (this.options.showPaginationSwitch) {
      html.push(sprintf('<button class="btn' +
        sprintf(' btn-%s', this.options.buttonsClass) +
        sprintf(' btn-%s', this.options.iconSize) +
        '" type="button" name="paginationSwitch" aria-label="pagination Switch" title="%s">',
        this.options.formatPaginationSwitch()),
        sprintf('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.paginationSwitchDown),
        '</button>');
    }
    if (this.options.showRefresh) {
      html.push(sprintf('<button class="btn' +
        sprintf(' btn-%s', this.options.buttonsClass) +
        sprintf(' btn-%s', this.options.iconSize) +
        '" type="button" name="refresh" aria-label="refresh" title="%s">',
        this.options.formatRefresh()),
        sprintf('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.refresh),
        '</button>');
    }
    if (this.options.showToggle) {
      html.push(sprintf('<button class="btn' +
        sprintf(' btn-%s', this.options.buttonsClass) +
        sprintf(' btn-%s', this.options.iconSize) +
        '" type="button" name="toggle" aria-label="toggle" title="%s">',
        this.options.formatToggle()),
        sprintf('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.toggle),
        '</button>');
    }
    if (this.options.showColumns) {
      html.push(sprintf('<div class="keep-open btn-group" title="%s">',
        this.options.formatColumns()),
        '<button type="button" aria-label="columns" class="btn' +
        sprintf(' btn-%s', this.options.buttonsClass) +
        sprintf(' btn-%s', this.options.iconSize) +
        ' dropdown-toggle" data-toggle="dropdown">',
        sprintf('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.columns),
        ' <span class="caret"></span>',
        '</button>',
        '<ul class="dropdown-menu" role="menu">');
      $.each(this.columns, function (i, column) {
        if (column.radio || column.checkbox) {
          return;
        }
        if (that.options.cardView && !column.cardVisible) {
          return;
        }
        var checked = column.visible ? ' checked="checked"' : '';
        if (column.switchable) {
          html.push(sprintf('<li role="menuitem">' +
            '<label><input type="checkbox" data-field="%s" value="%s"%s> %s</label>' +
            '</li>', column.field, i, checked, column.title));
          switchableCount++;
        }
      });
      html.push('</ul>',
        '</div>');
    }
    html.push('</div>');
    // Fix #188: this.showToolbar is for extensions
    if (this.showToolbar || html.length > 2) {
      this.$toolbar.append(html.join(''));
    }
    if (this.options.showPaginationSwitch) {
      this.$toolbar.find('button[name="paginationSwitch"]')
        .off('click').on('click', $.proxy(this.togglePagination, this));
    }
    if (this.options.showRefresh) {
      this.$toolbar.find('button[name="refresh"]')
        .off('click').on('click', $.proxy(this.refresh, this));
    }
    if (this.options.showToggle) {
      this.$toolbar.find('button[name="toggle"]')
        .off('click').on('click', function () {
          that.toggleView();
        });
    }
    if (this.options.showColumns) {
      $keepOpen = this.$toolbar.find('.keep-open');
      if (switchableCount <= this.options.minimumCountColumns) {
        $keepOpen.find('input').prop('disabled', true);
      }
      $keepOpen.find('li').off('click').on('click', function (event) {
        event.stopImmediatePropagation();
      });
      $keepOpen.find('input').off('click').on('click', function () {
        var $this = $(this);
        that.toggleColumn($(this).val(), $this.prop('checked'), false);
        that.trigger('column-switch', $(this).data('field'), $this.prop('checked'));
      });
    }
    if (this.options.search) {
      html = [];
      html.push(
        '<div class="pull-' + this.options.searchAlign + ' search">',
        sprintf('<input class="form-control' +
          sprintf(' input-%s', this.options.iconSize) +
          '" type="text" placeholder="%s">',
          this.options.formatSearch()),
        '</div>');
      this.$toolbar.append(html.join(''));
      $search = this.$toolbar.find('.search input');
      $search.off('keyup drop blur').on('keyup drop blur', function (event) {
        if (that.options.searchOnEnterKey && event.keyCode !== 13) {
          return;
        }
        if ($.inArray(event.keyCode, [37, 38, 39, 40]) > -1) {
          return;
        }
        clearTimeout(timeoutId); // doesn't matter if it's 0
        timeoutId = setTimeout(function () {
          that.onSearch(event);
        }, that.options.searchTimeOut);
      });
      if (isIEBrowser()) {
        $search.off('mouseup').on('mouseup', function (event) {
          clearTimeout(timeoutId); // doesn't matter if it's 0
          timeoutId = setTimeout(function () {
            that.onSearch(event);
          }, that.options.searchTimeOut);
        });
      }
    }
  };
  BootstrapTable.prototype.onSearch = function (event) {
    var text = $.trim($(event.currentTarget).val());
    // trim search input
    if (this.options.trimOnSearch && $(event.currentTarget).val() !== text) {
      $(event.currentTarget).val(text);
    }
    if (text === this.searchText) {
      return;
    }
    this.searchText = text;
    this.options.searchText = text;
    this.options.pageNumber = 1;
    this.initSearch();
    this.updatePagination();
    this.trigger('search', text);
  };
  BootstrapTable.prototype.initSearch = function () {
    var that = this;
    if (this.options.sidePagination !== 'server') {
      if (this.options.customSearch !== $.noop) {
        this.options.customSearch.apply(this, [this.searchText]);
        return;
      }
      var s = this.searchText && (this.options.escape ?
        escapeHTML(this.searchText) : this.searchText).toLowerCase();
      var f = $.isEmptyObject(this.filterColumns) ? null : this.filterColumns;
      // Check filter
      this.data = f ? $.grep(this.options.data, function (item, i) {
        for (var key in f) {
          if ($.isArray(f[key]) && $.inArray(item[key], f[key]) === -1 ||
            !$.isArray(f[key]) && item[key] !== f[key]) {
            return false;
          }
        }
        return true;
      }) : this.options.data;
      this.data = s ? $.grep(this.data, function (item, i) {
        for (var j = 0; j < that.header.fields.length; j++) {
          if (!that.header.searchables[j]) {
            continue;
          }
          var key = $.isNumeric(that.header.fields[j]) ? parseInt(that.header.fields[j], 10) : that.header.fields[j];
          var column = that.columns[getFieldIndex(that.columns, key)];
          var value;
          if (typeof key === 'string') {
            value = item;
            var props = key.split('.');
            for (var prop_index = 0; prop_index < props.length; prop_index++) {
              value = value[props[prop_index]];
            }
            // Fix #142: respect searchForamtter boolean
            if (column && column.searchFormatter) {
              value = calculateObjectValue(column,
                that.header.formatters[j], [value, item, i], value);
            }
          } else {
            value = item[key];
          }
          if (typeof value === 'string' || typeof value === 'number') {
            if (that.options.strictSearch) {
              if ((value + '').toLowerCase() === s) {
                return true;
              }
            } else {
              if ((value + '').toLowerCase().indexOf(s) !== -1) {
                return true;
              }
            }
          }
        }
        return false;
      }) : this.data;
    }
  };
  BootstrapTable.prototype.initPagination = function () {
    if (!this.options.pagination) {
      this.$pagination.hide();
      return;
    } else {
      this.$pagination.show();
    }
    var that = this,
      html = [],
      $allSelected = false,
      i, from, to,
      $pageList,
      $first, $pre,
      $next, $last,
      $number,
      data = this.getData(),
      pageList = this.options.pageList;
    if (this.options.sidePagination !== 'server') {
      this.options.totalRows = data.length;
    }
    this.totalPages = 0;
    if (this.options.totalRows) {
      if (this.options.pageSize === this.options.formatAllRows()) {
        this.options.pageSize = this.options.totalRows;
        $allSelected = true;
      } else if (this.options.pageSize === this.options.totalRows) {
        // Fix #667 Table with pagination,
        // multiple pages and a search that matches to one page throws exception
        var pageLst = typeof this.options.pageList === 'string' ?
          this.options.pageList.replace('[', '').replace(']', '')
            .replace(/ /g, '').toLowerCase().split(',') : this.options.pageList;
        if ($.inArray(this.options.formatAllRows().toLowerCase(), pageLst) > -1) {
          $allSelected = true;
        }
      }
      this.totalPages = ~~((this.options.totalRows - 1) / this.options.pageSize) + 1;
      this.options.totalPages = this.totalPages;
    }
    if (this.totalPages > 0 && this.options.pageNumber > this.totalPages) {
      this.options.pageNumber = this.totalPages;
    }
    this.pageFrom = (this.options.pageNumber - 1) * this.options.pageSize + 1;
    this.pageTo = this.options.pageNumber * this.options.pageSize;
    if (this.pageTo > this.options.totalRows) {
      this.pageTo = this.options.totalRows;
    }
    html.push(
      '<div class="pull-' + this.options.paginationDetailHAlign + ' pagination-detail">',
      '<span class="pagination-info">',
      this.options.onlyInfoPagination ? this.options.formatDetailPagination(this.options.totalRows) :
        this.options.formatShowingRows(this.pageFrom, this.pageTo, this.options.totalRows),
      '</span>');
    if (!this.options.onlyInfoPagination) {
      html.push('<span class="page-list">');
      var pageNumber = [
        sprintf('<span class="btn-group %s">',
          this.options.paginationVAlign === 'top' || this.options.paginationVAlign === 'both' ?
            'dropdown' : 'dropup'),
        '<button type="button" class="btn' +
        sprintf(' btn-%s', this.options.buttonsClass) +
        sprintf(' btn-%s', this.options.iconSize) +
        ' dropdown-toggle" data-toggle="dropdown">',
        '<span class="page-size">',
        $allSelected ? this.options.formatAllRows() : this.options.pageSize,
        '</span>',
        ' <span class="caret"></span>',
        '</button>',
        '<ul class="dropdown-menu" role="menu">'
      ];
      if (typeof this.options.pageList === 'string') {
        var list = this.options.pageList.replace('[', '').replace(']', '')
          .replace(/ /g, '').split(',');
        pageList = [];
        $.each(list, function (i, value) {
          pageList.push(value.toUpperCase() === that.options.formatAllRows().toUpperCase() ?
            that.options.formatAllRows() : +value);
        });
      }
      $.each(pageList, function (i, page) {
        if (!that.options.smartDisplay || i === 0 || pageList[i - 1] < that.options.totalRows) {
          var active;
          if ($allSelected) {
            active = page === that.options.formatAllRows() ? ' class="active"' : '';
          } else {
            active = page === that.options.pageSize ? ' class="active"' : '';
          }
          pageNumber.push(sprintf('<li role="menuitem"%s><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >%s</a></li>', active, page));
        }
      });
      pageNumber.push('</ul></span>');
      html.push(this.options.formatRecordsPerPage(pageNumber.join('')));
      html.push('</span>');
      html.push('</div>',
        '<div class="pull-' + this.options.paginationHAlign + ' pagination">',
        '<ul class="pagination' + sprintf(' pagination-%s', this.options.iconSize) + '">',
        '<li class="page-pre"><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >' + this.options.paginationPreText + '</a></li>');
      if (this.totalPages < 5) {
        from = 1;
        to = this.totalPages;
      } else {
        from = this.options.pageNumber - 2;
        to = from + 4;
        if (from < 1) {
          from = 1;
          to = 5;
        }
        if (to > this.totalPages) {
          to = this.totalPages;
          from = to - 4;
        }
      }
      if (this.totalPages >= 6) {
        if (this.options.pageNumber >= 3) {
          html.push('<li class="page-first' + (1 === this.options.pageNumber ? ' active' : '') + '">',
            '<a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >', 1, '</a>',
            '</li>');
          from++;
        }
        if (this.options.pageNumber >= 4) {
          if (this.options.pageNumber == 4 || this.totalPages == 6 || this.totalPages == 7) {
            from--;
          } else {
            html.push('<li class="page-first-separator disabled">',
              '<a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >...</a>',
              '</li>');
          }
          to--;
        }
      }
      if (this.totalPages >= 7) {
        if (this.options.pageNumber >= (this.totalPages - 2)) {
          from--;
        }
      }
      if (this.totalPages == 6) {
        if (this.options.pageNumber >= (this.totalPages - 2)) {
          to++;
        }
      } else if (this.totalPages >= 7) {
        if (this.totalPages == 7 || this.options.pageNumber >= (this.totalPages - 3)) {
          to++;
        }
      }
      for (i = from; i <= to; i++) {
        html.push('<li class="page-number' + (i === this.options.pageNumber ? ' active' : '') + '">',
          '<a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >', i, '</a>',
          '</li>');
      }
      if (this.totalPages >= 8) {
        if (this.options.pageNumber <= (this.totalPages - 4)) {
          html.push('<li class="page-last-separator disabled">',
            '<a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >...</a>',
            '</li>');
        }
      }
      if (this.totalPages >= 6) {
        if (this.options.pageNumber <= (this.totalPages - 3)) {
          html.push('<li class="page-last' + (this.totalPages === this.options.pageNumber ? ' active' : '') + '">',
            '<a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >', this.totalPages, '</a>',
            '</li>');
        }
      }
      html.push(
        '<li class="page-next"><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >' + this.options.paginationNextText + '</a></li>',
        '</ul>',
        '</div>');
    }
    this.$pagination.html(html.join(''));
    if (!this.options.onlyInfoPagination) {
      $pageList = this.$pagination.find('.page-list a');
      $first = this.$pagination.find('.page-first');
      $pre = this.$pagination.find('.page-pre');
      $next = this.$pagination.find('.page-next');
      $last = this.$pagination.find('.page-last');
      $number = this.$pagination.find('.page-number');
      if (this.options.smartDisplay) {
        if (this.totalPages <= 1) {
          this.$pagination.find('div.pagination').hide();
        }
        if (pageList.length < 2 || this.options.totalRows <= pageList[0]) {
          this.$pagination.find('span.page-list').hide();
        }
        // when data is empty, hide the pagination
        this.$pagination[this.getData().length ? 'show' : 'hide']();
      }
      if (!this.options.paginationLoop) {
        if (this.options.pageNumber === 1) {
          $pre.addClass('disabled');
        }
        if (this.options.pageNumber === this.totalPages) {
          $next.addClass('disabled');
        }
      }
      if ($allSelected) {
        this.options.pageSize = this.options.formatAllRows();
      }
      $pageList.off('click').on('click', $.proxy(this.onPageListChange, this));
      $first.off('click').on('click', $.proxy(this.onPageFirst, this));
      $pre.off('click').on('click', $.proxy(this.onPagePre, this));
      $next.off('click').on('click', $.proxy(this.onPageNext, this));
      $last.off('click').on('click', $.proxy(this.onPageLast, this));
      $number.off('click').on('click', $.proxy(this.onPageNumber, this));
    }
  };
  BootstrapTable.prototype.updatePagination = function (event) {
    // Fix #171: IE disabled button can be clicked bug.
    if (event && $(event.currentTarget).hasClass('disabled')) {
      return;
    }
    if (!this.options.maintainSelected) {
      this.resetRows();
    }
    this.initPagination();
    if (this.options.sidePagination === 'server') {
      this.initServer();
    } else {
      this.initBody();
    }
    this.trigger('page-change', this.options.pageNumber, this.options.pageSize);
  };
  BootstrapTable.prototype.onPageListChange = function (event) {
    var $this = $(event.currentTarget);
    $this.parent().addClass('active').siblings().removeClass('active');
    this.options.pageSize = $this.text().toUpperCase() === this.options.formatAllRows().toUpperCase() ?
      this.options.formatAllRows() : +$this.text();
    this.$toolbar.find('.page-size').text(this.options.pageSize);
    this.updatePagination(event);
    return false;
  };
  BootstrapTable.prototype.onPageFirst = function (event) {
    this.options.pageNumber = 1;
    this.updatePagination(event);
    return false;
  };
  BootstrapTable.prototype.onPagePre = function (event) {
    if ((this.options.pageNumber - 1) === 0) {
      this.options.pageNumber = this.options.totalPages;
    } else {
      this.options.pageNumber--;
    }
    this.updatePagination(event);
    return false;
  };
  BootstrapTable.prototype.onPageNext = function (event) {
    if ((this.options.pageNumber + 1) > this.options.totalPages) {
      this.options.pageNumber = 1;
    } else {
      this.options.pageNumber++;
    }
    this.updatePagination(event);
    return false;
  };
  BootstrapTable.prototype.onPageLast = function (event) {
    this.options.pageNumber = this.totalPages;
    this.updatePagination(event);
    return false;
  };
  BootstrapTable.prototype.onPageNumber = function (event) {
    if (this.options.pageNumber === +$(event.currentTarget).text()) {
      return;
    }
    this.options.pageNumber = +$(event.currentTarget).text();
    this.updatePagination(event);
    return false;
  };
  BootstrapTable.prototype.initRow = function (item, i, data, parentDom) {
    var that = this,
      key,
      html = [],
      style = {},
      csses = [],
      data_ = '',
      attributes = {},
      htmlAttributes = [];
    if ($.inArray(item, this.hiddenRows) > -1) {
      return;
    }
    style = calculateObjectValue(this.options, this.options.rowStyle, [item, i], style);
    if (style && style.css) {
      for (key in style.css) {
        csses.push(key + ': ' + style.css[key]);
      }
    }
    attributes = calculateObjectValue(this.options,
      this.options.rowAttributes, [item, i], attributes);
    if (attributes) {
      for (key in attributes) {
        htmlAttributes.push(sprintf('%s="%s"', key, escapeHTML(attributes[key])));
      }
    }
    if (item._data && !$.isEmptyObject(item._data)) {
      $.each(item._data, function (k, v) {
        // ignore data-index
        if (k === 'index') {
          return;
        }
        data_ += sprintf(' data-%s="%s"', k, v);
      });
    }
    html.push('<tr',
      sprintf(' %s', htmlAttributes.join(' ')),
      sprintf(' id="%s"', $.isArray(item) ? undefined : item._id),
      sprintf(' class="%s"', style.classes || ($.isArray(item) ? undefined : item._class)),
      sprintf(' data-index="%s"', i),
      sprintf(' data-uniqueid="%s"', item[this.options.uniqueId]),
      sprintf('%s', data_),
      '>'
    );
    if (this.options.cardView) {
      html.push(sprintf('<td colspan="%s"><div class="card-views">', this.header.fields.length));
    }
    if (!this.options.cardView && this.options.detailView) {
      html.push('<td>',
        '<a class="detail-icon" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >',
        sprintf('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.detailOpen),
        '</a>',
        '</td>');
    }
    $.each(this.header.fields, function (j, field) {
      var text = '',
        value_ = getItemField(item, field, that.options.escape),
        value = '',
        type = '',
        cellStyle = {},
        id_ = '',
        class_ = that.header.classes[j],
        data_ = '',
        rowspan_ = '',
        colspan_ = '',
        title_ = '',
        column = that.columns[j];
      if (that.fromHtml && typeof value_ === 'undefined') {
        return;
      }
      if (!column.visible) {
        return;
      }
      if (that.options.cardView && (!column.cardVisible)) {
        return;
      }
      if (column.escape) {
        value_ = escapeHTML(value_);
      }
      style = sprintf('style="%s"', csses.concat(that.header.styles[j]).join('; '));
      // handle td's id and class
      if (item['_' + field + '_id']) {
        id_ = sprintf(' id="%s"', item['_' + field + '_id']);
      }
      if (item['_' + field + '_class']) {
        class_ = sprintf(' class="%s"', item['_' + field + '_class']);
      }
      if (item['_' + field + '_rowspan']) {
        rowspan_ = sprintf(' rowspan="%s"', item['_' + field + '_rowspan']);
      }
      if (item['_' + field + '_colspan']) {
        colspan_ = sprintf(' colspan="%s"', item['_' + field + '_colspan']);
      }
      if (item['_' + field + '_title']) {
        title_ = sprintf(' title="%s"', item['_' + field + '_title']);
      }
      cellStyle = calculateObjectValue(that.header,
        that.header.cellStyles[j], [value_, item, i, field], cellStyle);
      if (cellStyle.classes) {
        class_ = sprintf(' class="%s"', cellStyle.classes);
      }
      if (cellStyle.css) {
        var csses_ = [];
        for (var key in cellStyle.css) {
          csses_.push(key + ': ' + cellStyle.css[key]);
        }
        style = sprintf('style="%s"', csses_.concat(that.header.styles[j]).join('; '));
      }
      value = calculateObjectValue(column,
        that.header.formatters[j], [value_, item, i], value_);
      if (item['_' + field + '_data'] && !$.isEmptyObject(item['_' + field + '_data'])) {
        $.each(item['_' + field + '_data'], function (k, v) {
          // ignore data-index
          if (k === 'index') {
            return;
          }
          data_ += sprintf(' data-%s="%s"', k, v);
        });
      }
      if (column.checkbox || column.radio) {
        type = column.checkbox ? 'checkbox' : type;
        type = column.radio ? 'radio' : type;
        text = [sprintf(that.options.cardView ?
          '<div class="card-view %s">' : '<td class="bs-checkbox %s">', column['class'] || ''),
        '<input' +
        sprintf(' data-index="%s"', i) +
        sprintf(' name="%s"', that.options.selectItemName) +
        sprintf(' type="%s"', type) +
        sprintf(' value="%s"', item[that.options.idField]) +
        sprintf(' checked="%s"', value === true ||
          (value_ || value && value.checked) ? 'checked' : undefined) +
        sprintf(' disabled="%s"', !column.checkboxEnabled ||
          (value && value.disabled) ? 'disabled' : undefined) +
        ' />',
        that.header.formatters[j] && typeof value === 'string' ? value : '',
        that.options.cardView ? '</div>' : '</td>'
        ].join('');
        item[that.header.stateField] = value === true || (value && value.checked);
      } else {
        value = typeof value === 'undefined' || value === null ?
          that.options.undefinedText : value;
        text = that.options.cardView ? ['<div class="card-view">',
          that.options.showHeader ? sprintf('<span class="title" %s>%s</span>', style,
            getPropertyFromOther(that.columns, 'field', 'title', field)) : '',
          sprintf('<span class="value">%s</span>', value),
          '</div>'
        ].join('') : [sprintf('<td%s %s %s %s %s %s %s>',
          id_, class_, style, data_, rowspan_, colspan_, title_),
          value,
          '</td>'
        ].join('');
        // Hide empty data on Card view when smartDisplay is set to true.
        if (that.options.cardView && that.options.smartDisplay && value === '') {
          // Should set a placeholder for event binding correct fieldIndex
          text = '<div class="card-view"></div>';
        }
      }
      html.push(text);
    });
    if (this.options.cardView) {
      html.push('</div></td>');
    }
    html.push('</tr>');
    return html.join(' ');
  };
  BootstrapTable.prototype.initBody = function (fixedScroll) {
    var that = this,
      html = [],
      data = this.getData();
    this.trigger('pre-body', data);
    this.$body = this.$el.find('>tbody');
    if (!this.$body.length) {
      this.$body = $('<tbody></tbody>').appendTo(this.$el);
    }
    //Fix #389 Bootstrap-table-flatJSON is not working
    if (!this.options.pagination || this.options.sidePagination === 'server') {
      this.pageFrom = 1;
      this.pageTo = data.length;
    }
    var trFragments = $(document.createDocumentFragment());
    var hasTr;
    for (var i = this.pageFrom - 1; i < this.pageTo; i++) {
      var item = data[i];
      var tr = this.initRow(item, i, data, trFragments);
      hasTr = hasTr || !!tr;
      if (tr && tr !== true) {
        trFragments.append(tr);
      }
    }
    // show no records
    if (!hasTr) {
      trFragments.append('<tr class="no-records-found">' +
        sprintf('<td colspan="%s">%s</td>',
          this.$header.find('th').length,
          this.options.formatNoMatches()) +
        '</tr>');
    }
    this.$body.html(trFragments);
    if (!fixedScroll) {
      this.scrollTo(0);
    }
    // click to select by column
    this.$body.find('> tr[data-index] > td').off('click dblclick').on('click dblclick', function (e) {
      var $td = $(this),
        $tr = $td.parent(),
        item = that.data[$tr.data('index')],
        index = $td[0].cellIndex,
        fields = that.getVisibleFields(),
        field = fields[that.options.detailView && !that.options.cardView ? index - 1 : index],
        column = that.columns[getFieldIndex(that.columns, field)],
        value = getItemField(item, field, that.options.escape);
      if ($td.find('.detail-icon').length) {
        return;
      }
      that.trigger(e.type === 'click' ? 'click-cell' : 'dbl-click-cell', field, value, item, $td);
      that.trigger(e.type === 'click' ? 'click-row' : 'dbl-click-row', item, $tr, field);
      // if click to select - then trigger the checkbox/radio click
      if (e.type === 'click' && that.options.clickToSelect && column.clickToSelect) {
        var $selectItem = $tr.find(sprintf('[name="%s"]', that.options.selectItemName));
        if ($selectItem.length) {
          $selectItem[0].click(); // #144: .trigger('click') bug
        }
      }
    });
    this.$body.find('> tr[data-index] > td > .detail-icon').off('click').on('click', function () {
      var $this = $(this),
        $tr = $this.parent().parent(),
        index = $tr.data('index'),
        row = data[index]; // Fix #980 Detail view, when searching, returns wrong row
      // remove and update
      if ($tr.next().is('tr.detail-view')) {
        $this.find('i').attr('class', sprintf('%s %s', that.options.iconsPrefix, that.options.icons.detailOpen));
        that.trigger('collapse-row', index, row);
        $tr.next().remove();
      } else {
        $this.find('i').attr('class', sprintf('%s %s', that.options.iconsPrefix, that.options.icons.detailClose));
        $tr.after(sprintf('<tr class="detail-view"><td colspan="%s"></td></tr>', $tr.find('td').length));
        var $element = $tr.next().find('td');
        var content = calculateObjectValue(that.options, that.options.detailFormatter, [index, row, $element], '');
        if ($element.length === 1) {
          $element.append(content);
        }
        that.trigger('expand-row', index, row, $element);
      }
      that.resetView();
      return false;
    });
    this.$selectItem = this.$body.find(sprintf('[name="%s"]', this.options.selectItemName));
    this.$selectItem.off('click').on('click', function (event) {
      event.stopImmediatePropagation();
      var $this = $(this),
        checked = $this.prop('checked'),
        row = that.data[$this.data('index')];
      if (that.options.maintainSelected && $(this).is(':radio')) {
        $.each(that.options.data, function (i, row) {
          row[that.header.stateField] = false;
        });
      }
      row[that.header.stateField] = checked;
      if (that.options.singleSelect) {
        that.$selectItem.not(this).each(function () {
          that.data[$(this).data('index')][that.header.stateField] = false;
        });
        that.$selectItem.filter(':checked').not(this).prop('checked', false);
      }
      that.updateSelected();
      that.trigger(checked ? 'check' : 'uncheck', row, $this);
    });
    $.each(this.header.events, function (i, events) {
      if (!events) {
        return;
      }
      // fix bug, if events is defined with namespace
      if (typeof events === 'string') {
        events = calculateObjectValue(null, events);
      }
      var field = that.header.fields[i],
        fieldIndex = $.inArray(field, that.getVisibleFields());
      if (that.options.detailView && !that.options.cardView) {
        fieldIndex += 1;
      }
      for (var key in events) {
        that.$body.find('>tr:not(.no-records-found)').each(function () {
          var $tr = $(this),
            $td = $tr.find(that.options.cardView ? '.card-view' : 'td').eq(fieldIndex),
            index = key.indexOf(' '),
            name = key.substring(0, index),
            el = key.substring(index + 1),
            func = events[key];
          $td.find(el).off(name).on(name, function (e) {
            var index = $tr.data('index'),
              row = that.data[index],
              value = row[field];
            func.apply(this, [e, value, row, index]);
          });
        });
      }
    });
    this.updateSelected();
    this.resetView();
    this.trigger('post-body', data);
  };
  BootstrapTable.prototype.initServer = function (silent, query, url) {
    var that = this,
      data = {},
      params = {
        searchText: this.searchText,
        sortName: this.options.sortName,
        sortOrder: this.options.sortOrder
      },
      request;
    if (this.options.pagination) {
      params.pageSize = this.options.pageSize === this.options.formatAllRows() ?
        this.options.totalRows : this.options.pageSize;
      params.pageNumber = this.options.pageNumber;
    }
    if (!(url || this.options.url) && !this.options.ajax) {
      return;
    }
    if (this.options.queryParamsType === 'limit') {
      params = {
        search: params.searchText,
        sort: params.sortName,
        order: params.sortOrder
      };
      if (this.options.pagination) {
        params.offset = this.options.pageSize === this.options.formatAllRows() ?
          0 : this.options.pageSize * (this.options.pageNumber - 1);
        params.limit = this.options.pageSize === this.options.formatAllRows() ?
          this.options.totalRows : this.options.pageSize;
      }
    }
    if (!($.isEmptyObject(this.filterColumnsPartial))) {
      params.filter = JSON.stringify(this.filterColumnsPartial, null);
    }
    data = calculateObjectValue(this.options, this.options.queryParams, [params], data);
    $.extend(data, query || {});
    // false to stop request
    if (data === false) {
      return;
    }
    if (!silent) {
      this.$tableLoading.show();
    }
    request = $.extend({}, calculateObjectValue(null, this.options.ajaxOptions), {
      type: this.options.method,
      url: url || this.options.url,
      data: this.options.contentType === 'application/json' && this.options.method === 'post' ?
        JSON.stringify(data) : data,
      cache: this.options.cache,
      contentType: this.options.contentType,
      dataType: this.options.dataType,
      success: function (res) {
        res = calculateObjectValue(that.options, that.options.responseHandler, [res], res);
        that.load(res);
        that.trigger('load-success', res);
        if (!silent) that.$tableLoading.hide();
      },
      error: function (res) {
        that.trigger('load-error', res.status, res);
        if (!silent) that.$tableLoading.hide();
      }
    });
    if (this.options.ajax) {
      calculateObjectValue(this, this.options.ajax, [request], null);
    } else {
      if (this._xhr && this._xhr.readyState !== 4) {
        this._xhr.abort();
      }
      this._xhr = $.ajax(request);
    }
  };
  BootstrapTable.prototype.initSearchText = function () {
    if (this.options.search) {
      if (this.options.searchText !== '') {
        var $search = this.$toolbar.find('.search input');
        $search.val(this.options.searchText);
        this.onSearch({ currentTarget: $search });
      }
    }
  };
  BootstrapTable.prototype.getCaret = function () {
    var that = this;
    $.each(this.$header.find('th'), function (i, th) {
      $(th).find('.sortable').removeClass('desc asc').addClass($(th).data('field') === that.options.sortName ? that.options.sortOrder : 'both');
    });
  };
  BootstrapTable.prototype.updateSelected = function () {
    var checkAll = this.$selectItem.filter(':enabled').length &&
      this.$selectItem.filter(':enabled').length ===
      this.$selectItem.filter(':enabled').filter(':checked').length;
    this.$selectAll.add(this.$selectAll_).prop('checked', checkAll);
    this.$selectItem.each(function () {
      $(this).closest('tr')[$(this).prop('checked') ? 'addClass' : 'removeClass']('selected');
    });
  };
  BootstrapTable.prototype.updateRows = function () {
    var that = this;
    this.$selectItem.each(function () {
      that.data[$(this).data('index')][that.header.stateField] = $(this).prop('checked');
    });
  };
  BootstrapTable.prototype.resetRows = function () {
    var that = this;
    $.each(this.data, function (i, row) {
      that.$selectAll.prop('checked', false);
      that.$selectItem.prop('checked', false);
      if (that.header.stateField) {
        row[that.header.stateField] = false;
      }
    });
    this.initHiddenRows();
  };
  BootstrapTable.prototype.trigger = function (name) {
    var args = Array.prototype.slice.call(arguments, 1);
    name += '.bs.table';
    this.options[BootstrapTable.EVENTS[name]].apply(this.options, args);
    this.$el.trigger($.Event(name), args);
    this.options.onAll(name, args);
    this.$el.trigger($.Event('all.bs.table'), [name, args]);
  };
  BootstrapTable.prototype.resetHeader = function () {
    // fix #61: the hidden table reset header bug.
    // fix bug: get $el.css('width') error sometime (height = 500)
    clearTimeout(this.timeoutId_);
    this.timeoutId_ = setTimeout($.proxy(this.fitHeader, this), this.$el.is(':hidden') ? 100 : 0);
  };
  BootstrapTable.prototype.fitHeader = function () {
    var that = this,
      fixedBody,
      scrollWidth,
      focused,
      focusedTemp;
    if (that.$el.is(':hidden')) {
      that.timeoutId_ = setTimeout($.proxy(that.fitHeader, that), 100);
      return;
    }
    fixedBody = this.$tableBody.get(0);
    scrollWidth = fixedBody.scrollWidth > fixedBody.clientWidth &&
      fixedBody.scrollHeight > fixedBody.clientHeight + this.$header.outerHeight() ?
      getScrollBarWidth() : 0;
    this.$el.css('margin-top', -this.$header.outerHeight());
    focused = $(':focus');
    if (focused.length > 0) {
      var $th = focused.parents('th');
      if ($th.length > 0) {
        var dataField = $th.attr('data-field');
        if (dataField !== undefined) {
          var $headerTh = this.$header.find("[data-field='" + dataField + "']");
          if ($headerTh.length > 0) {
            $headerTh.find(":input").addClass("focus-temp");
          }
        }
      }
    }
    this.$header_ = this.$header.clone(true, true);
    this.$selectAll_ = this.$header_.find('[name="btSelectAll"]');
    this.$tableHeader.css({
      'margin-right': scrollWidth
    }).find('table').css('width', this.$el.outerWidth())
      .html('').attr('class', this.$el.attr('class'))
      .append(this.$header_);
    focusedTemp = $('.focus-temp:visible:eq(0)');
    if (focusedTemp.length > 0) {
      focusedTemp.focus();
      this.$header.find('.focus-temp').removeClass('focus-temp');
    }
    // fix bug: $.data() is not working as expected after $.append()
    this.$header.find('th[data-field]').each(function (i) {
      that.$header_.find(sprintf('th[data-field="%s"]', $(this).data('field'))).data($(this).data());
    });
    var visibleFields = this.getVisibleFields(),
      $ths = this.$header_.find('th');
    this.$body.find('>tr:first-child:not(.no-records-found) > *').each(function (i) {
      var $this = $(this),
        index = i;
      if (that.options.detailView && !that.options.cardView) {
        if (i === 0) {
          that.$header_.find('th.detail').find('.fht-cell').width($this.innerWidth());
        }
        index = i - 1;
      }
      var $th = that.$header_.find(sprintf('th[data-field="%s"]', visibleFields[index]));
      if ($th.length > 1) {
        $th = $($ths[$this[0].cellIndex]);
      }
      $th.find('.fht-cell').width($this.innerWidth());
    });
    // horizontal scroll event
    // TODO: it's probably better improving the layout than binding to scroll event
    this.$tableBody.off('scroll').on('scroll', function () {
      that.$tableHeader.scrollLeft($(this).scrollLeft());
      if (that.options.showFooter && !that.options.cardView) {
        that.$tableFooter.scrollLeft($(this).scrollLeft());
      }
    });
    that.trigger('post-header');
  };
  BootstrapTable.prototype.resetFooter = function () {
    var that = this,
      data = that.getData(),
      html = [];
    if (!this.options.showFooter || this.options.cardView) { //do nothing
      return;
    }
    if (!this.options.cardView && this.options.detailView) {
      html.push('<td><div class="th-inner"> </div><div class="fht-cell"></div></td>');
    }
    $.each(this.columns, function (i, column) {
      var key,
        falign = '', // footer align style
        valign = '',
        csses = [],
        style = {},
        class_ = sprintf(' class="%s"', column['class']);
      if (!column.visible) {
        return;
      }
      if (that.options.cardView && (!column.cardVisible)) {
        return;
      }
      falign = sprintf('text-align: %s; ', column.falign ? column.falign : column.align);
      valign = sprintf('vertical-align: %s; ', column.valign);
      style = calculateObjectValue(null, that.options.footerStyle);
      if (style && style.css) {
        for (key in style.css) {
          csses.push(key + ': ' + style.css[key]);
        }
      }
      html.push('<td', class_, sprintf(' style="%s"', falign + valign + csses.concat().join('; ')), '>');
      html.push('<div class="th-inner">');
      html.push(calculateObjectValue(column, column.footerFormatter, [data], ' ') || ' ');
      html.push('</div>');
      html.push('<div class="fht-cell"></div>');
      html.push('</div>');
      html.push('</td>');
    });
    this.$tableFooter.find('tr').html(html.join(''));
    this.$tableFooter.show();
    clearTimeout(this.timeoutFooter_);
    this.timeoutFooter_ = setTimeout($.proxy(this.fitFooter, this),
      this.$el.is(':hidden') ? 100 : 0);
  };
  BootstrapTable.prototype.fitFooter = function () {
    var that = this,
      $footerTd,
      elWidth,
      scrollWidth;
    clearTimeout(this.timeoutFooter_);
    if (this.$el.is(':hidden')) {
      this.timeoutFooter_ = setTimeout($.proxy(this.fitFooter, this), 100);
      return;
    }
    elWidth = this.$el.css('width');
    scrollWidth = elWidth > this.$tableBody.width() ? getScrollBarWidth() : 0;
    this.$tableFooter.css({
      'margin-right': scrollWidth
    }).find('table').css('width', elWidth)
      .attr('class', this.$el.attr('class'));
    $footerTd = this.$tableFooter.find('td');
    this.$body.find('>tr:first-child:not(.no-records-found) > *').each(function (i) {
      var $this = $(this);
      $footerTd.eq(i).find('.fht-cell').width($this.innerWidth());
    });
  };
  BootstrapTable.prototype.toggleColumn = function (index, checked, needUpdate) {
    if (index === -1) {
      return;
    }
    this.columns[index].visible = checked;
    this.initHeader();
    this.initSearch();
    this.initPagination();
    this.initBody();
    if (this.options.showColumns) {
      var $items = this.$toolbar.find('.keep-open input').prop('disabled', false);
      if (needUpdate) {
        $items.filter(sprintf('[value="%s"]', index)).prop('checked', checked);
      }
      if ($items.filter(':checked').length <= this.options.minimumCountColumns) {
        $items.filter(':checked').prop('disabled', true);
      }
    }
  };
  BootstrapTable.prototype.getVisibleFields = function () {
    var that = this,
      visibleFields = [];
    $.each(this.header.fields, function (j, field) {
      var column = that.columns[getFieldIndex(that.columns, field)];
      if (!column.visible) {
        return;
      }
      visibleFields.push(field);
    });
    return visibleFields;
  };
  // PUBLIC FUNCTION DEFINITION
  // =======================
  BootstrapTable.prototype.resetView = function (params) {
    var 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);
    if (this.options.height) {
      var toolbarHeight = this.$toolbar.outerHeight(true),
        paginationHeight = this.$pagination.outerHeight(true),
        height = this.options.height;
      if (this.options.height.toString().indexOf("%") != -1) {
        height = $(window).height() * (parseFloat(this.options.height) / 100);
      }
      height = height - toolbarHeight - paginationHeight;
      this.$tableContainer.css('height', height + 'px');
    }
    if (this.options.cardView) {
      // remove the element css
      this.$el.css('margin-top', '0');
      this.$tableContainer.css('padding-bottom', '0');
      this.$tableFooter.hide();
      return;
    }
    if (this.options.showHeader && this.options.height) {
      this.$tableHeader.show();
      this.resetHeader();
      padding += this.$header.outerHeight();
    } else {
      this.$tableHeader.hide();
      this.trigger('post-header');
    }
    if (this.options.showFooter) {
      this.resetFooter();
      if (this.options.height) {
        padding += this.$tableFooter.outerHeight() + 1;
      }
    }
    // Assign the correct sortable arrow
    this.getCaret();
    this.$tableContainer.css('padding-bottom', padding + 'px');
    this.trigger('reset-view');
  };
  BootstrapTable.prototype.getData = function (useCurrentPage) {
    return (this.searchText || !$.isEmptyObject(this.filterColumns) || !$.isEmptyObject(this.filterColumnsPartial)) ?
      (useCurrentPage ? this.data.slice(this.pageFrom - 1, this.pageTo) : this.data) :
      (useCurrentPage ? this.options.data.slice(this.pageFrom - 1, this.pageTo) : this.options.data);
  };
  BootstrapTable.prototype.load = function (data) {
    var fixedScroll = false;
    // #431: support pagination
    if (this.options.sidePagination === 'server') {
      this.options.totalRows = data[this.options.totalField];
      fixedScroll = data.fixedScroll;
      data = data[this.options.dataField];
    } else if (!$.isArray(data)) { // support fixedScroll
      fixedScroll = data.fixedScroll;
      data = data.data;
    }
    this.initData(data);
    this.initSearch();
    this.initPagination();
    this.initBody(fixedScroll);
  };
  BootstrapTable.prototype.append = function (data) {
    this.initData(data, 'append');
    this.initSearch();
    this.initPagination();
    this.initSort();
    this.initBody(true);
  };
  BootstrapTable.prototype.prepend = function (data) {
    this.initData(data, 'prepend');
    this.initSearch();
    this.initPagination();
    this.initSort();
    this.initBody(true);
  };
  BootstrapTable.prototype.remove = function (params) {
    var len = this.options.data.length,
      i, row;
    if (!params.hasOwnProperty('field') || !params.hasOwnProperty('values')) {
      return;
    }
    for (i = len - 1; i >= 0; i--) {
      row = this.options.data[i];
      if (!row.hasOwnProperty(params.field)) {
        continue;
      }
      if ($.inArray(row[params.field], params.values) !== -1) {
        this.options.data.splice(i, 1);
        if (this.options.sidePagination === 'server') {
          this.options.totalRows -= 1;
        }
      }
    }
    if (len === this.options.data.length) {
      return;
    }
    this.initSearch();
    this.initPagination();
    this.initSort();
    this.initBody(true);
  };
  BootstrapTable.prototype.removeAll = function () {
    if (this.options.data.length > 0) {
      this.options.data.splice(0, this.options.data.length);
      this.initSearch();
      this.initPagination();
      this.initBody(true);
    }
  };
  BootstrapTable.prototype.getRowByUniqueId = function (id) {
    var uniqueId = this.options.uniqueId,
      len = this.options.data.length,
      dataRow = null,
      i, row, rowUniqueId;
    for (i = len - 1; i >= 0; i--) {
      row = this.options.data[i];
      if (row.hasOwnProperty(uniqueId)) { // uniqueId is a column
        rowUniqueId = row[uniqueId];
      } else if (row._data.hasOwnProperty(uniqueId)) { // uniqueId is a row data property
        rowUniqueId = row._data[uniqueId];
      } else {
        continue;
      }
      if (typeof rowUniqueId === 'string') {
        id = id.toString();
      } else if (typeof rowUniqueId === 'number') {
        if ((Number(rowUniqueId) === rowUniqueId) && (rowUniqueId % 1 === 0)) {
          id = parseInt(id);
        } else if ((rowUniqueId === Number(rowUniqueId)) && (rowUniqueId !== 0)) {
          id = parseFloat(id);
        }
      }
      if (rowUniqueId === id) {
        dataRow = row;
        break;
      }
    }
    return dataRow;
  };
  BootstrapTable.prototype.removeByUniqueId = function (id) {
    var len = this.options.data.length,
      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);
  };
  BootstrapTable.prototype.updateByUniqueId = function (params) {
    var that = this;
    var allParams = $.isArray(params) ? params : [params];
    $.each(allParams, function (i, params) {
      var rowId;
      if (!params.hasOwnProperty('id') || !params.hasOwnProperty('row')) {
        return;
      }
      rowId = $.inArray(that.getRowByUniqueId(params.id), that.options.data);
      if (rowId === -1) {
        return;
      }
      $.extend(that.options.data[rowId], params.row);
    });
    this.initSearch();
    this.initPagination();
    this.initSort();
    this.initBody(true);
  };
  BootstrapTable.prototype.insertRow = function (params) {
    if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {
      return;
    }
    this.data.splice(params.index, 0, params.row);
    this.initSearch();
    this.initPagination();
    this.initSort();
    this.initBody(true);
  };
  BootstrapTable.prototype.updateRow = function (params) {
    var that = this;
    var allParams = $.isArray(params) ? params : [params];
    $.each(allParams, function (i, params) {
      if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {
        return;
      }
      $.extend(that.options.data[params.index], params.row);
    });
    this.initSearch();
    this.initPagination();
    this.initSort();
    this.initBody(true);
  };
  BootstrapTable.prototype.initHiddenRows = function () {
    this.hiddenRows = [];
  };
  BootstrapTable.prototype.showRow = function (params) {
    this.toggleRow(params, true);
  };
  BootstrapTable.prototype.hideRow = function (params) {
    this.toggleRow(params, false);
  };
  BootstrapTable.prototype.toggleRow = function (params, visible) {
    var row, index;
    if (params.hasOwnProperty('index')) {
      row = this.getData()[params.index];
    } else if (params.hasOwnProperty('uniqueId')) {
      row = this.getRowByUniqueId(params.uniqueId);
    }
    if (!row) {
      return;
    }
    index = $.inArray(row, this.hiddenRows);
    if (!visible && index === -1) {
      this.hiddenRows.push(row);
    } else if (visible && index > -1) {
      this.hiddenRows.splice(index, 1);
    }
    this.initBody(true);
  };
  BootstrapTable.prototype.getHiddenRows = function (show) {
    var that = this,
      data = this.getData(),
      rows = [];
    $.each(data, function (i, row) {
      if ($.inArray(row, that.hiddenRows) > -1) {
        rows.push(row);
      }
    });
    this.hiddenRows = rows;
    return rows;
  };
  BootstrapTable.prototype.mergeCells = function (options) {
    var row = options.index,
      col = $.inArray(options.field, this.getVisibleFields()),
      rowspan = options.rowspan || 1,
      colspan = options.colspan || 1,
      i, j,
      $tr = this.$body.find('>tr'),
      $td;
    if (this.options.detailView && !this.options.cardView) {
      col += 1;
    }
    $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();
  };
  BootstrapTable.prototype.updateCell = function (params) {
    if (!params.hasOwnProperty('index') ||
      !params.hasOwnProperty('field') ||
      !params.hasOwnProperty('value')) {
      return;
    }
    this.data[params.index][params.field] = params.value;
    if (params.reinit === false) {
      return;
    }
    this.initSort();
    this.initBody(true);
  };
  BootstrapTable.prototype.getOptions = function () {
    return this.options;
  };
  BootstrapTable.prototype.getSelections = function () {
    var that = this;
    return $.grep(this.options.data, function (row) {
      // fix #2424: from html with checkbox
      return row[that.header.stateField] === true;
    });
  };
  BootstrapTable.prototype.getAllSelections = function () {
    var that = this;
    return $.grep(this.options.data, function (row) {
      return row[that.header.stateField];
    });
  };
  BootstrapTable.prototype.checkAll = function () {
    this.checkAll_(true);
  };
  BootstrapTable.prototype.uncheckAll = function () {
    this.checkAll_(false);
  };
  BootstrapTable.prototype.checkInvert = function () {
    var that = this;
    var rows = that.$selectItem.filter(':enabled');
    var checked = rows.filter(':checked');
    rows.each(function () {
      $(this).prop('checked', !$(this).prop('checked'));
    });
    that.updateRows();
    that.updateSelected();
    that.trigger('uncheck-some', checked);
    checked = that.getSelections();
    that.trigger('check-some', checked);
  };
  BootstrapTable.prototype.checkAll_ = function (checked) {
    var rows;
    if (!checked) {
      rows = this.getSelections();
    }
    this.$selectAll.add(this.$selectAll_).prop('checked', checked);
    this.$selectItem.filter(':enabled').prop('checked', checked);
    this.updateRows();
    if (checked) {
      rows = this.getSelections();
    }
    this.trigger(checked ? 'check-all' : 'uncheck-all', rows);
  };
  BootstrapTable.prototype.check = function (index) {
    this.check_(true, index);
  };
  BootstrapTable.prototype.uncheck = function (index) {
    this.check_(false, index);
  };
  BootstrapTable.prototype.check_ = function (checked, index) {
    var $el = this.$selectItem.filter(sprintf('[data-index="%s"]', index)).prop('checked', checked);
    this.data[index][this.header.stateField] = checked;
    this.updateSelected();
    this.trigger(checked ? 'check' : 'uncheck', this.data[index], $el);
  };
  BootstrapTable.prototype.checkBy = function (obj) {
    this.checkBy_(true, obj);
  };
  BootstrapTable.prototype.uncheckBy = function (obj) {
    this.checkBy_(false, obj);
  };
  BootstrapTable.prototype.checkBy_ = function (checked, obj) {
    if (!obj.hasOwnProperty('field') || !obj.hasOwnProperty('values')) {
      return;
    }
    var isTrigger = true;
    /*是否触发选中事件,还是静默处理*/
    if (obj.hasOwnProperty('isTrigger') && !obj['isTrigger']) {
      isTrigger = false
    }
    var that = this,
      rows = [];
    $.each(this.options.data, function (index, row) {
      if (!row.hasOwnProperty(obj.field)) {
        return false;
      }
      if ($.inArray(row[obj.field], obj.values) !== -1) {
        var $el = that.$selectItem.filter(':enabled')
          .filter(sprintf('[data-index="%s"]', index)).prop('checked', checked);
        row[that.header.stateField] = checked;
        rows.push(row);
        if (isTrigger) {
          that.trigger(checked ? 'check' : 'uncheck', row, $el);
        }
      }
    });
    this.updateSelected();
    if (isTrigger) {
      this.trigger(checked ? 'check-some' : 'uncheck-some', rows);
    }
  };
  BootstrapTable.prototype.destroy = function () {
    this.$el.insertBefore(this.$container);
    $(this.options.toolbar).insertBefore(this.$el);
    this.$container.next().remove();
    this.$container.remove();
    this.$el.html(this.$el_.html())
      .css('margin-top', '0')
      .attr('class', this.$el_.attr('class') || ''); // reset the class
  };
  BootstrapTable.prototype.showLoading = function () {
    this.$tableLoading.show();
  };
  BootstrapTable.prototype.hideLoading = function () {
    this.$tableLoading.hide();
  };
  BootstrapTable.prototype.togglePagination = function () {
    this.options.pagination = !this.options.pagination;
    var button = this.$toolbar.find('button[name="paginationSwitch"] i');
    if (this.options.pagination) {
      button.attr("class", this.options.iconsPrefix + " " + this.options.icons.paginationSwitchDown);
    } else {
      button.attr("class", this.options.iconsPrefix + " " + this.options.icons.paginationSwitchUp);
    }
    this.updatePagination();
  };
  BootstrapTable.prototype.refresh = function (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.initServer(params && params.silent,
      params && params.query, params && params.url);
    this.trigger('refresh', params);
  };
  BootstrapTable.prototype.resetWidth = function () {
    if (this.options.showHeader && this.options.height) {
      this.fitHeader();
    }
    if (this.options.showFooter) {
      this.fitFooter();
    }
  };
  BootstrapTable.prototype.showColumn = function (field) {
    this.toggleColumn(getFieldIndex(this.columns, field), true, true);
  };
  BootstrapTable.prototype.hideColumn = function (field) {
    this.toggleColumn(getFieldIndex(this.columns, field), false, true);
  };
  BootstrapTable.prototype.getHiddenColumns = function () {
    return $.grep(this.columns, function (column) {
      return !column.visible;
    });
  };
  BootstrapTable.prototype.getVisibleColumns = function () {
    return $.grep(this.columns, function (column) {
      return column.visible;
    });
  };
  BootstrapTable.prototype.toggleAllColumns = function (visible) {
    $.each(this.columns, function (i, column) {
      this.columns[i].visible = visible;
    });
    this.initHeader();
    this.initSearch();
    this.initPagination();
    this.initBody();
    if (this.options.showColumns) {
      var $items = this.$toolbar.find('.keep-open input').prop('disabled', false);
      if ($items.filter(':checked').length <= this.options.minimumCountColumns) {
        $items.filter(':checked').prop('disabled', true);
      }
    }
  };
  BootstrapTable.prototype.showAllColumns = function () {
    this.toggleAllColumns(true);
  };
  BootstrapTable.prototype.hideAllColumns = function () {
    this.toggleAllColumns(false);
  };
  BootstrapTable.prototype.filterBy = function (columns) {
    this.filterColumns = $.isEmptyObject(columns) ? {} : columns;
    this.options.pageNumber = 1;
    this.initSearch();
    this.updatePagination();
  };
  BootstrapTable.prototype.scrollTo = function (value) {
    if (typeof value === 'string') {
      value = value === 'bottom' ? this.$tableBody[0].scrollHeight : 0;
    }
    if (typeof value === 'number') {
      this.$tableBody.scrollTop(value);
    }
    if (typeof value === 'undefined') {
      return this.$tableBody.scrollTop();
    }
  };
  BootstrapTable.prototype.getScrollPosition = function () {
    return this.scrollTo();
  };
  BootstrapTable.prototype.selectPage = function (page) {
    if (page > 0 && page <= this.options.totalPages) {
      this.options.pageNumber = page;
      this.updatePagination();
    }
  };
  BootstrapTable.prototype.prevPage = function () {
    if (this.options.pageNumber > 1) {
      this.options.pageNumber--;
      this.updatePagination();
    }
  };
  BootstrapTable.prototype.nextPage = function () {
    if (this.options.pageNumber < this.options.totalPages) {
      this.options.pageNumber++;
      this.updatePagination();
    }
  };
  BootstrapTable.prototype.toggleView = function () {
    this.options.cardView = !this.options.cardView;
    this.initHeader();
    // Fixed remove toolbar when click cardView button.
    //that.initToolbar();
    this.initBody();
    this.trigger('toggle', this.options.cardView);
  };
  BootstrapTable.prototype.refreshOptions = function (options) {
    //If the objects are equivalent then avoid the call of destroy / init methods
    if (compareObjects(this.options, options, true)) {
      return;
    }
    this.options = $.extend(this.options, options);
    this.trigger('refresh-options', this.options);
    this.destroy();
    this.init();
  };
  BootstrapTable.prototype.resetSearch = function (text) {
    var $search = this.$toolbar.find('.search input');
    $search.val(text || '');
    this.onSearch({ currentTarget: $search });
  };
  BootstrapTable.prototype.expandRow_ = function (expand, index) {
    var $tr = this.$body.find(sprintf('> tr[data-index="%s"]', index));
    if ($tr.next().is('tr.detail-view') === (expand ? false : true)) {
      $tr.find('> td > .detail-icon').click();
    }
  };
  BootstrapTable.prototype.expandRow = function (index) {
    this.expandRow_(true, index);
  };
  BootstrapTable.prototype.collapseRow = function (index) {
    this.expandRow_(false, index);
  };
  BootstrapTable.prototype.expandAllRows = function (isSubTable) {
    if (isSubTable) {
      var $tr = this.$body.find(sprintf('> tr[data-index="%s"]', 0)),
        that = this,
        detailIcon = null,
        executeInterval = false,
        idInterval = -1;
      if (!$tr.next().is('tr.detail-view')) {
        $tr.find('> td > .detail-icon').click();
        executeInterval = true;
      } else if (!$tr.next().next().is('tr.detail-view')) {
        $tr.next().find(".detail-icon").click();
        executeInterval = true;
      }
      if (executeInterval) {
        try {
          idInterval = setInterval(function () {
            detailIcon = that.$body.find("tr.detail-view").last().find(".detail-icon");
            if (detailIcon.length > 0) {
              detailIcon.click();
            } else {
              clearInterval(idInterval);
            }
          }, 1);
        } catch (ex) {
          clearInterval(idInterval);
        }
      }
    } else {
      var trs = this.$body.children();
      for (var i = 0; i < trs.length; i++) {
        this.expandRow_(true, $(trs[i]).data("index"));
      }
    }
  };
  BootstrapTable.prototype.collapseAllRows = function (isSubTable) {
    if (isSubTable) {
      this.expandRow_(false, 0);
    } else {
      var trs = this.$body.children();
      for (var i = 0; i < trs.length; i++) {
        this.expandRow_(false, $(trs[i]).data("index"));
      }
    }
  };
  BootstrapTable.prototype.updateFormatText = function (name, text) {
    if (this.options[sprintf('format%s', name)]) {
      if (typeof text === 'string') {
        this.options[sprintf('format%s', name)] = function () {
          return text;
        };
      } else if (typeof text === 'function') {
        this.options[sprintf('format%s', name)] = text;
      }
    }
    this.initToolbar();
    this.initPagination();
    this.initBody();
  };
  // BOOTSTRAP TABLE PLUGIN DEFINITION
  // =======================
  var allowedMethods = [
    'getOptions',
    'getSelections', 'getAllSelections', 'getData',
    'load', 'append', 'prepend', 'remove', 'removeAll',
    'insertRow', 'updateRow', 'updateCell', 'updateByUniqueId', 'removeByUniqueId',
    'getRowByUniqueId', 'showRow', 'hideRow', 'getHiddenRows',
    'mergeCells',
    'checkAll', 'uncheckAll', 'checkInvert',
    'check', 'uncheck',
    'checkBy', 'uncheckBy',
    'refresh',
    'resetView',
    'resetWidth',
    'destroy',
    'showLoading', 'hideLoading',
    'showColumn', 'hideColumn', 'getHiddenColumns', 'getVisibleColumns',
    'showAllColumns', 'hideAllColumns',
    'filterBy',
    'scrollTo',
    'getScrollPosition',
    'selectPage', 'prevPage', 'nextPage',
    'togglePagination',
    'toggleView',
    'refreshOptions',
    'resetSearch',
    'expandRow', 'collapseRow', 'expandAllRows', 'collapseAllRows',
    'updateFormatText'
  ];
  $.fn.bootstrapTable = function (option) {
    var value,
      args = Array.prototype.slice.call(arguments, 1);
    this.each(function () {
      var $this = $(this),
        data = $this.data('bootstrap.table'),
        options = $.extend({}, BootstrapTable.DEFAULTS, $this.data(),
          typeof option === 'object' && option);
      if (typeof option === 'string') {
        if ($.inArray(option, allowedMethods) < 0) {
          throw new Error("Unknown method: " + option);
        }
        if (!data) {
          return;
        }
        value = data[option].apply(data, args);
        if (option === 'destroy') {
          $this.removeData('bootstrap.table');
        }
      }
      if (!data) {
        $this.data('bootstrap.table', (data = new BootstrapTable(this, options)));
      }
    });
    return typeof value === 'undefined' ? this : value;
  };
  $.fn.bootstrapTable.Constructor = BootstrapTable;
  $.fn.bootstrapTable.defaults = BootstrapTable.DEFAULTS;
  $.fn.bootstrapTable.columnDefaults = BootstrapTable.COLUMN_DEFAULTS;
  $.fn.bootstrapTable.locales = BootstrapTable.LOCALES;
  $.fn.bootstrapTable.methods = allowedMethods;
  $.fn.bootstrapTable.utils = {
    sprintf: sprintf,
    getFieldIndex: getFieldIndex,
    compareObjects: compareObjects,
    calculateObjectValue: calculateObjectValue,
    getItemField: getItemField,
    objectKeys: objectKeys,
    isIEBrowser: isIEBrowser
  };
  // BOOTSTRAP TABLE INIT
  // =======================
  $(function () {
    $('[data-toggle="table"]').bootstrapTable();
  });
})(jQuery);

总结

以上所述是小编给大家介绍的bootstrap table支持高度百分比的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
33个优秀的 jQuery 图片展示插件分享
Mar 14 Javascript
关于编写性能高效的javascript事件的技术
Nov 28 Javascript
jQuery知识点整理
Jan 30 Javascript
jQuery幻灯片特效代码分享--鼠标滑过按钮时切换(2)
Nov 18 Javascript
js获取页面及个元素高度、宽度的代码
Apr 26 Javascript
浅谈js中的in-for循环
Jun 28 Javascript
关于jQuery EasyUI 中刷新Tab选项卡后一个页面变形的解决方法
Mar 02 Javascript
JS去掉字符串末尾的标点符号及删除最后一个字符的方法
Oct 24 Javascript
vue组件之间通信实例总结(点赞功能)
Dec 05 Javascript
vue用BMap百度地图实现即时搜索功能
Sep 26 Javascript
浅谈vuex的基本用法和mapaction传值问题
Nov 08 Javascript
使用vue构建多页面应用的示例
Oct 22 Javascript
vue 2.x 中axios 封装的get 和post方法
Feb 28 #Javascript
浅析node应用的timing-attack安全漏洞
Feb 28 #Javascript
vue组件传递对象中实现单向绑定的示例
Feb 28 #Javascript
在Vue组件中使用 TypeScript的方法
Feb 28 #Javascript
React组件中的this的具体使用
Feb 28 #Javascript
浅谈Vue网络请求之interceptors实际应用
Feb 28 #Javascript
Node.js中DNS模块学习总结
Feb 28 #Javascript
You might like
用PHP4访问Oracle815
2006/10/09 PHP
PHP令牌 Token改进版
2008/07/18 PHP
php图片缩放实现方法
2014/02/20 PHP
PHP异常Parse error: syntax error, unexpected T_VAR错误解决方法
2014/05/06 PHP
PHP树-不需要递归的实现方法
2016/06/21 PHP
定位地理位置PHP判断员工打卡签到经纬度是否在打卡之内
2019/05/23 PHP
JavaScript 权威指南(第四版) 读书笔记
2009/08/11 Javascript
Mootools 1.2教程 Tooltips
2009/09/15 Javascript
Jquery下attr和removeAttr的使用方法
2010/12/28 Javascript
js 第二代身份证号码的验证机制代码
2011/05/12 Javascript
jQuery使用技巧简单汇总
2013/04/18 Javascript
JS 实现点击a标签的时候让其背景更换
2013/10/15 Javascript
点击标签切换和自动切换DIV选项卡
2014/08/10 Javascript
sogou地图API用法实例教程
2014/09/11 Javascript
原生JS和JQuery动态添加、删除表格行的方法
2015/05/28 Javascript
javascript中mouseover、mouseout使用详解
2015/07/19 Javascript
Bootstrap~多级导航(级联导航)的实现效果【附代码】
2016/03/08 Javascript
原生JavaScript实现Ajax的方法
2016/04/07 Javascript
AngularJs中Bootstrap3 datetimepicker使用实例
2016/12/13 Javascript
js实现分页功能
2017/05/24 Javascript
JQuery中DOM节点的操作与访问方法实例分析
2019/12/23 jQuery
Vue简单封装axios之解决post请求后端接收不到参数问题
2020/02/16 Javascript
[02:27]DOTA2英雄基础教程 莱恩
2014/01/17 DOTA
python解决pandas处理缺失值为空字符串的问题
2018/04/08 Python
浅谈Django中的QueryDict元素为数组的坑
2020/03/31 Python
python3 sleep 延时秒 毫秒实例
2020/05/04 Python
Css3实现无缝滚动防抖
2020/09/14 HTML / CSS
酒店中秋节活动方案
2014/01/31 职场文书
超市活动计划书
2014/04/24 职场文书
马丁路德金演讲稿
2014/05/19 职场文书
食品仓管员岗位职责
2015/04/01 职场文书
行政主管岗位职责范本
2015/04/09 职场文书
送达通知书
2015/04/25 职场文书
狼牙山五壮士观后感
2015/06/09 职场文书
《叶问2》观后感
2015/06/15 职场文书
小学毕业教师寄语
2019/06/21 职场文书