bootstrap-table.js 73 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137
  1. /**
  2. * @author zhixin wen <wenzhixin2010@gmail.com>
  3. * version: 1.6.0
  4. * https://github.com/wenzhixin/bootstrap-table/
  5. */
  6. !function ($) {
  7. 'use strict';
  8. var cellHeight = 37, // update css if changed
  9. idStateSave = '',
  10. idSortOrderStateSave = 'bs.table.sortOrder',
  11. idSortNameStateSave = 'bs.table.sortName',
  12. idPageNumberStateSave = 'bs.table.pageNumber',
  13. idPageListStateSave = 'bs.table.pageList',
  14. idsStateSaveList = {
  15. 'sortOrder': idSortOrderStateSave,
  16. 'sortName': idSortNameStateSave,
  17. 'pageNumber': idPageNumberStateSave,
  18. 'pageList': idPageListStateSave
  19. };
  20. // TOOLS DEFINITION
  21. // ======================
  22. // it only does '%s', and return '' when arguments are undefined
  23. var sprintf = function (str) {
  24. var args = arguments,
  25. flag = true,
  26. i = 1;
  27. str = str.replace(/%s/g, function () {
  28. var arg = args[i++];
  29. if (typeof arg === 'undefined') {
  30. flag = false;
  31. return '';
  32. }
  33. return arg;
  34. });
  35. return flag ? str : '';
  36. };
  37. var getPropertyFromOther = function (list, from, to, value) {
  38. var result = '';
  39. $.each(list, function (i, item) {
  40. if (item[from] === value) {
  41. result = item[to];
  42. return false;
  43. }
  44. return true;
  45. });
  46. return result;
  47. };
  48. var getFieldIndex = function (columns, field) {
  49. var index = -1;
  50. $.each(columns, function (i, column) {
  51. if (column.field === field) {
  52. index = i;
  53. return false;
  54. }
  55. return true;
  56. });
  57. return index;
  58. };
  59. var cachedWidth = null;
  60. var getScrollBarWidth = function () {
  61. if (cachedWidth === null) {
  62. var inner = $('<p/>').addClass('fixed-table-scroll-inner'),
  63. outer = $('<div/>').addClass('fixed-table-scroll-outer'),
  64. w1, w2;
  65. outer.append(inner);
  66. $('body').append(outer);
  67. w1 = inner[0].offsetWidth;
  68. outer.css('overflow', 'scroll');
  69. w2 = inner[0].offsetWidth;
  70. if (w1 === w2) {
  71. w2 = outer[0].clientWidth;
  72. }
  73. outer.remove();
  74. cachedWidth = w1 - w2;
  75. }
  76. return cachedWidth;
  77. };
  78. var calculateObjectValue = function (self, name, args, defaultValue) {
  79. if (typeof name === 'string') {
  80. // support obj.func1.func2
  81. var names = name.split('.');
  82. if (names.length > 1) {
  83. name = window;
  84. $.each(names, function (i, f) {
  85. name = name[f];
  86. });
  87. } else {
  88. name = window[name];
  89. }
  90. }
  91. if (typeof name === 'object') {
  92. return name;
  93. }
  94. if (typeof name === 'function') {
  95. return name.apply(self, args);
  96. }
  97. return defaultValue;
  98. };
  99. var escapeHTML = function (text) {
  100. if (typeof text === 'string') {
  101. return text
  102. .replace(/&/g, "&amp;")
  103. .replace(/</g, "&lt;")
  104. .replace(/>/g, "&gt;")
  105. .replace(/"/g, "&quot;")
  106. .replace(/'/g, "&#039;");
  107. }
  108. return text;
  109. };
  110. var cookieEnabled = function (){
  111. var cookieEnabled = (navigator.cookieEnabled) ? true : false;
  112. if (typeof navigator.cookieEnabled === undefined && !cookieEnabled)
  113. {
  114. document.cookie = 'testcookie';
  115. cookieEnabled = (document.cookie.indexOf('testcookie') !== -1) ? true : false;
  116. }
  117. return (cookieEnabled);
  118. };
  119. var setCookie = function (cookieName, sValue, vEnd, sPath, sDomain, bSecure) {
  120. cookieName = idStateSave + cookieName;
  121. if (!cookieName || /^(?:expires|max\-age|path|domain|secure)$/i.test(cookieName)) {
  122. return false;
  123. }
  124. var sExpires = '',
  125. time = '';
  126. time = vEnd.replace(/[0-9]/,''); //s,mi,h,d,m,y
  127. vEnd = vEnd.replace(/[A-Za-z]/,''); //number
  128. switch (time.toLowerCase()) {
  129. case 's':
  130. vEnd = +vEnd;
  131. break;
  132. case 'mi':
  133. vEnd = vEnd * 60;
  134. break;
  135. case 'h':
  136. vEnd = vEnd * 60 * 60;
  137. case 'd':
  138. vEnd = vEnd * 24 * 60 * 60;
  139. break;
  140. case 'm':
  141. vEnd = vEnd * 30 * 24 * 60 * 60;
  142. break;
  143. case 'y':
  144. vEnd = vEnd * 365 * 30 * 24 * 60 * 60;
  145. break;
  146. default:
  147. vEnd = undefined;
  148. break;
  149. }
  150. sExpires = vEnd === undefined ? '' : '; max-age=' + vEnd;
  151. document.cookie = encodeURIComponent(cookieName) + '=' + encodeURIComponent(sValue) + sExpires + (sDomain ? '; domain=' + sDomain : '') + (sPath ? '; path=' + sPath : '') + (bSecure ? '; secure' : '');
  152. return true;
  153. };
  154. var getCookie = function (cookieName) {
  155. cookieName = idStateSave + cookieName;
  156. if (!cookieName) {
  157. return null;
  158. }
  159. return decodeURIComponent(document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + encodeURIComponent(cookieName).replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1')) || null;
  160. };
  161. var hasCookie = function (cookieName) {
  162. if (!cookieName) {
  163. return false;
  164. }
  165. return (new RegExp('(?:^|;\\s*)' + encodeURIComponent(cookieName).replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=')).test(document.cookie);
  166. };
  167. var deleteCookie = function (cookieName, sPath, sDomain) {
  168. cookieName = idStateSave + cookieName;
  169. if (!hasCookie(cookieName)) {
  170. return false;
  171. }
  172. document.cookie = encodeURIComponent(cookieName) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT' + (sDomain ? '; domain=' + sDomain : '') + (sPath ? '; path=' + sPath : '');
  173. return true;
  174. };
  175. // BOOTSTRAP TABLE CLASS DEFINITION
  176. // ======================
  177. var BootstrapTable = function (el, options) {
  178. this.options = options;
  179. this.$el = $(el);
  180. this.$el_ = this.$el.clone();
  181. this.timeoutId_ = 0;
  182. this.timeoutFooter_ = 0;
  183. this.init();
  184. };
  185. BootstrapTable.DEFAULTS = {
  186. classes: 'table table-hover',
  187. height: undefined,
  188. undefinedText: '-',
  189. sortName: undefined,
  190. sortOrder: 'asc',
  191. striped: false,
  192. columns: [],
  193. data: [],
  194. method: 'get',
  195. url: undefined,
  196. cache: true,
  197. contentType: 'application/json',
  198. dataType: 'json',
  199. ajaxOptions: {},
  200. queryParams: function (params) {
  201. return params;
  202. },
  203. queryParamsType: 'limit', // undefined
  204. responseHandler: function (res) {
  205. return res;
  206. },
  207. pagination: false,
  208. sidePagination: 'client', // client or server
  209. totalRows: 0, // server side need to set
  210. pageNumber: 1,
  211. pageSize: 10,
  212. pageList: [10, 25, 50, 100],
  213. paginationHAlign: 'right', //right, left
  214. paginationVAlign: 'bottom', //bottom, top
  215. paginationDetailHAlign: 'left', //right, left
  216. paginationDetailVAlign: 'bottom', //bottom, top
  217. search: false,
  218. searchAlign: 'right',
  219. selectItemName: 'btSelectItem',
  220. showHeader: true,
  221. showFooter: false,
  222. showColumns: false,
  223. showPaginationSwitch: false,
  224. showRefresh: false,
  225. showToggle: false,
  226. buttonsAlign: 'right',
  227. smartDisplay: true,
  228. minimumCountColumns: 1,
  229. idField: undefined,
  230. cardView: false,
  231. trimOnSearch: true,
  232. clickToSelect: false,
  233. singleSelect: false,
  234. toolbar: undefined,
  235. toolbarAlign: 'left',
  236. checkboxHeader: true,
  237. sortable: true,
  238. maintainSelected: false,
  239. searchTimeOut: 500,
  240. keyEvents: false,
  241. searchText: '',
  242. stateSave: false,
  243. stateSaveExpire: '2h',
  244. stateSaveIdTable: '',
  245. iconSize: undefined,
  246. iconsPrefix: 'glyphicon', // glyphicon of fa (font awesome)
  247. icons: {
  248. paginationSwitchDown: 'glyphicon-collapse-down icon-chevron-down',
  249. paginationSwitchUp: 'glyphicon-collapse-up icon-chevron-up',
  250. refresh: 'glyphicon-refresh icon-refresh',
  251. toggle: 'glyphicon-list-alt icon-list-alt',
  252. columns: 'glyphicon-th icon-th'
  253. },
  254. rowStyle: function (row, index) {
  255. return {};
  256. },
  257. rowAttributes: function (row, index) {
  258. return {};
  259. },
  260. onAll: function (name, args) {
  261. return false;
  262. },
  263. onClickRow: function (item, $element) {
  264. return false;
  265. },
  266. onDblClickRow: function (item, $element) {
  267. return false;
  268. },
  269. onSort: function (name, order) {
  270. return false;
  271. },
  272. onCheck: function (row) {
  273. return false;
  274. },
  275. onUncheck: function (row) {
  276. return false;
  277. },
  278. onCheckAll: function () {
  279. return false;
  280. },
  281. onUncheckAll: function () {
  282. return false;
  283. },
  284. onLoadSuccess: function (data) {
  285. return false;
  286. },
  287. onLoadError: function (status) {
  288. return false;
  289. },
  290. onColumnSwitch: function (field, checked) {
  291. return false;
  292. },
  293. onPageChange: function (number, size) {
  294. return false;
  295. },
  296. onSearch: function (text) {
  297. return false;
  298. },
  299. onPreBody: function (data) {
  300. return false;
  301. },
  302. onPostBody: function () {
  303. return false;
  304. },
  305. onPostHeader: function () {
  306. return false;
  307. }
  308. };
  309. BootstrapTable.LOCALES = [];
  310. BootstrapTable.LOCALES['en-US'] = {
  311. formatLoadingMessage: function () {
  312. return 'Loading, please wait...';
  313. },
  314. formatRecordsPerPage: function (pageNumber) {
  315. return sprintf('%s records per page', pageNumber);
  316. },
  317. formatShowingRows: function (pageFrom, pageTo, totalRows) {
  318. return sprintf('Showing %s to %s of %s rows', pageFrom, pageTo, totalRows);
  319. },
  320. formatSearch: function () {
  321. return 'Search';
  322. },
  323. formatNoMatches: function () {
  324. return 'No matching records found';
  325. },
  326. formatPaginationSwitch: function () {
  327. return 'Hide/Show pagination';
  328. },
  329. formatRefresh: function () {
  330. return 'Refresh';
  331. },
  332. formatToggle: function () {
  333. return 'Toggle';
  334. },
  335. formatColumns: function () {
  336. return 'Columns';
  337. },
  338. formatAllRows: function () {
  339. return 'All';
  340. }
  341. };
  342. $.extend(BootstrapTable.DEFAULTS, BootstrapTable.LOCALES['en-US']);
  343. BootstrapTable.COLUMN_DEFAULTS = {
  344. radio: false,
  345. checkbox: false,
  346. checkboxEnabled: true,
  347. field: undefined,
  348. title: undefined,
  349. 'class': undefined,
  350. align: undefined, // left, right, center
  351. halign: undefined, // left, right, center
  352. falign: undefined, // left, right, center
  353. valign: undefined, // top, middle, bottom
  354. width: undefined,
  355. sortable: false,
  356. order: 'asc', // asc, desc
  357. visible: true,
  358. switchable: true,
  359. clickToSelect: true,
  360. formatter: undefined,
  361. footerFormatter: undefined,
  362. events: undefined,
  363. sorter: undefined,
  364. cellStyle: undefined,
  365. searchable: true,
  366. cardVisible: true
  367. };
  368. BootstrapTable.EVENTS = {
  369. 'all.bs.table': 'onAll',
  370. 'click-row.bs.table': 'onClickRow',
  371. 'dbl-click-row.bs.table': 'onDblClickRow',
  372. 'sort.bs.table': 'onSort',
  373. 'check.bs.table': 'onCheck',
  374. 'uncheck.bs.table': 'onUncheck',
  375. 'check-all.bs.table': 'onCheckAll',
  376. 'uncheck-all.bs.table': 'onUncheckAll',
  377. 'load-success.bs.table': 'onLoadSuccess',
  378. 'load-error.bs.table': 'onLoadError',
  379. 'column-switch.bs.table': 'onColumnSwitch',
  380. 'page-change.bs.table': 'onPageChange',
  381. 'search.bs.table': 'onSearch',
  382. 'pre-body.bs.table': 'onPreBody',
  383. 'post-body.bs.table': 'onPostBody',
  384. 'post-header.bs.table': 'onPostHeader'
  385. };
  386. BootstrapTable.prototype.init = function () {
  387. this.initStateSave();
  388. this.initContainer();
  389. this.initTable();
  390. this.initHeader();
  391. this.initData();
  392. this.initFooter();
  393. this.initToolbar();
  394. this.initPagination();
  395. this.initBody();
  396. this.initServer();
  397. this.initKeyEvents();
  398. };
  399. BootstrapTable.prototype.initContainer = function () {
  400. this.$container = $([
  401. '<div class="bootstrap-table">',
  402. '<div class="fixed-table-toolbar"></div>',
  403. '<div class="fixed-table-container">',
  404. '<div class="fixed-table-header"><table></table></div>',
  405. '<div class="fixed-table-body">',
  406. '<div class="fixed-table-loading">',
  407. this.options.formatLoadingMessage(),
  408. '</div>',
  409. '</div>',
  410. '<div class="fixed-table-footer"><table><tr></tr></table></div>',
  411. '<div class="fixed-table-pagination"></div>',
  412. '</div>',
  413. '</div>'].join(''));
  414. this.$container.insertAfter(this.$el);
  415. this.$container.find('.fixed-table-body').append(this.$el);
  416. this.$container.after('<div class="clearfix"></div>');
  417. this.$loading = this.$container.find('.fixed-table-loading');
  418. this.$el.addClass(this.options.classes);
  419. if (this.options.striped) {
  420. this.$el.addClass('table-striped');
  421. }
  422. };
  423. BootstrapTable.prototype.initTable = function () {
  424. var that = this,
  425. columns = [],
  426. data = [];
  427. this.$header = this.$el.find('thead');
  428. if (!this.$header.length) {
  429. this.$header = $('<thead></thead>').appendTo(this.$el);
  430. }
  431. if (!this.$header.find('tr').length) {
  432. this.$header.append('<tr></tr>');
  433. }
  434. this.$header.find('th').each(function () {
  435. var column = $.extend({}, {
  436. title: $(this).html(),
  437. 'class': $(this).attr('class')
  438. }, $(this).data());
  439. columns.push(column);
  440. });
  441. this.options.columns = $.extend([], columns, this.options.columns);
  442. $.each(this.options.columns, function (i, column) {
  443. that.options.columns[i] = $.extend({}, BootstrapTable.COLUMN_DEFAULTS,
  444. {field: i}, column); // when field is undefined, use index instead
  445. });
  446. // if options.data is setting, do not process tbody data
  447. if (this.options.data.length) {
  448. return;
  449. }
  450. this.$el.find('tbody tr').each(function () {
  451. var row = {};
  452. // save tr's id and class
  453. row._id = $(this).attr('id');
  454. row._class = $(this).attr('class');
  455. $(this).find('td').each(function (i) {
  456. var field = that.options.columns[i].field;
  457. row[field] = $(this).html();
  458. // save td's id and class
  459. row['_' + field + '_id'] = $(this).attr('id');
  460. row['_' + field + '_class'] = $(this).attr('class');
  461. row['_' + field + '_data'] = $(this).data();
  462. });
  463. data.push(row);
  464. });
  465. this.options.data = data;
  466. };
  467. BootstrapTable.prototype.initHeader = function () {
  468. var that = this,
  469. visibleColumns = [],
  470. html = [];
  471. this.header = {
  472. fields: [],
  473. styles: [],
  474. classes: [],
  475. formatters: [],
  476. events: [],
  477. sorters: [],
  478. cellStyles: [],
  479. clickToSelects: [],
  480. searchables: []
  481. };
  482. $.each(this.options.columns, function (i, column) {
  483. var text = '',
  484. halign = '', // header align style
  485. align = '', // body align style
  486. style = '',
  487. class_ = sprintf(' class="%s"', column['class']),
  488. order = that.options.sortOrder || column.order,
  489. searchable = true,
  490. unitWidth = 'px';
  491. if (!column.visible) {
  492. return;
  493. }
  494. if (that.options.cardView && (!column.cardVisible)) {
  495. return;
  496. }
  497. if (column.width !== undefined) {
  498. if (typeof column.width === 'string') {
  499. if (column.width.indexOf('%') > -1) {
  500. unitWidth = '%'
  501. }
  502. column.width = column.width.replace('%', '').replace('px', '');
  503. }
  504. }
  505. halign = sprintf('text-align: %s; ', column.halign ? column.halign : column.align);
  506. align = sprintf('text-align: %s; ', column.align);
  507. style = sprintf('vertical-align: %s; ', column.valign);
  508. style += sprintf('width: %s'+ unitWidth +'; ', column.checkbox || column.radio ? 36 : column.width);
  509. visibleColumns.push(column);
  510. that.header.fields.push(column.field);
  511. that.header.styles.push(align + style);
  512. that.header.classes.push(class_);
  513. that.header.formatters.push(column.formatter);
  514. that.header.events.push(column.events);
  515. that.header.sorters.push(column.sorter);
  516. that.header.cellStyles.push(column.cellStyle);
  517. that.header.clickToSelects.push(column.clickToSelect);
  518. that.header.searchables.push(column.searchable);
  519. html.push('<th',
  520. column.checkbox || column.radio ?
  521. sprintf(' class="bs-checkbox %s"', column['class'] || '') :
  522. class_,
  523. sprintf(' style="%s"', halign + style),
  524. '>');
  525. html.push(sprintf('<div class="th-inner %s">', that.options.sortable && column.sortable ?
  526. 'sortable' : ''));
  527. text = column.title;
  528. if (that.options.sortName === column.field && that.options.sortable && column.sortable) {
  529. text += that.getCaretHtml();
  530. }
  531. if (column.checkbox) {
  532. if (!that.options.singleSelect && that.options.checkboxHeader) {
  533. text = '<input name="btSelectAll" type="checkbox" />';
  534. }
  535. that.header.stateField = column.field;
  536. }
  537. if (column.radio) {
  538. text = '';
  539. that.header.stateField = column.field;
  540. that.options.singleSelect = true;
  541. }
  542. html.push(text);
  543. html.push('</div>');
  544. html.push('<div class="fht-cell"></div>');
  545. html.push('</th>');
  546. });
  547. this.$header.find('tr').html(html.join(''));
  548. this.$header.find('th').each(function (i) {
  549. $(this).data(visibleColumns[i]);
  550. });
  551. this.$container.off('click', 'th').on('click', 'th', function (event) {
  552. if (that.options.sortable && $(this).data().sortable) {
  553. that.onSort(event);
  554. }
  555. });
  556. if (!this.options.showHeader || this.options.cardView) {
  557. this.$header.hide();
  558. this.$container.find('.fixed-table-header').hide();
  559. this.$loading.css('top', 0);
  560. } else {
  561. this.$header.show();
  562. this.$container.find('.fixed-table-header').show();
  563. this.$loading.css('top', cellHeight + 'px');
  564. }
  565. this.$selectAll = this.$header.find('[name="btSelectAll"]');
  566. this.$container.off('click', '[name="btSelectAll"]')
  567. .on('click', '[name="btSelectAll"]', function () {
  568. var checked = $(this).prop('checked');
  569. that[checked ? 'checkAll' : 'uncheckAll']();
  570. });
  571. };
  572. BootstrapTable.prototype.initFooter = function () {
  573. this.$footer = this.$container.find('.fixed-table-footer');
  574. if (!this.options.showFooter || this.options.cardView) {
  575. this.$footer.hide();
  576. } else {
  577. this.$footer.show();
  578. }
  579. };
  580. BootstrapTable.prototype.resetFooter = function () {
  581. var bt = this,
  582. data = bt.getData(),
  583. html = [];
  584. if (!this.options.showFooter || this.options.cardView) { //do nothing
  585. return;
  586. }
  587. $.each(bt.options.columns, function (i, column) {
  588. var falign = '', // footer align style
  589. style = '',
  590. class_ = sprintf(' class="%s"', column['class']);
  591. if (!column.visible) {
  592. return;
  593. }
  594. if (that.options.cardView && (!column.cardVisible)) {
  595. return;
  596. }
  597. falign = sprintf('text-align: %s; ', column.falign ? column.falign : column.align);
  598. style = sprintf('vertical-align: %s; ', column.valign);
  599. html.push('<td', class_, sprintf(' style="%s"', falign + style), '>');
  600. html.push(calculateObjectValue(column, column.footerFormatter, [data], '&nbsp;') || '&nbsp;');
  601. html.push('</td>');
  602. });
  603. bt.$footer.find('tr').html(html.join(''));
  604. clearTimeout(bt.timeoutFooter_);
  605. bt.timeoutFooter_ = setTimeout($.proxy(bt.fitFooter, bt), bt.$el.is(':hidden') ? 100: 0);
  606. return;
  607. };
  608. BootstrapTable.prototype.fitFooter = function () {
  609. var bt = this,
  610. $fixedBody,
  611. $footerTd,
  612. elWidth,
  613. scrollWidth;
  614. clearTimeout(bt.timeoutFooter_);
  615. if (bt.$el.is(':hidden')) {
  616. bt.timeoutFooter_ = setTimeout($.proxy(bt.fitFooter, bt), 100);
  617. return;
  618. }
  619. $fixedBody = bt.$container.find('.fixed-table-body');
  620. elWidth = bt.$el.css('width');
  621. scrollWidth = elWidth > $fixedBody.width() ? getScrollBarWidth() : 0;
  622. bt.$footer.css({
  623. 'margin-right': scrollWidth
  624. }).find('table').css('width', elWidth)
  625. .attr('class', bt.$el.attr('class'));
  626. $footerTd = bt.$footer.find('td');
  627. $fixedBody.find('tbody tr:first-child:not(.no-records-found) > td').each(function(i) {
  628. $footerTd.eq(i).outerWidth($(this).outerWidth());
  629. });
  630. };
  631. /**
  632. * @param data
  633. * @param type: append / prepend
  634. */
  635. BootstrapTable.prototype.initData = function (data, type) {
  636. if (type === 'append') {
  637. this.data = this.data.concat(data);
  638. } else if (type === 'prepend') {
  639. this.data = [].concat(data).concat(this.data);
  640. } else {
  641. this.data = data || this.options.data;
  642. }
  643. this.options.data = this.data;
  644. if (this.options.sidePagination === 'server') {
  645. return;
  646. }
  647. this.initSort();
  648. };
  649. BootstrapTable.prototype.initSort = function () {
  650. var that = this,
  651. name = this.options.sortName,
  652. order = this.options.sortOrder === 'desc' ? -1 : 1,
  653. index = $.inArray(this.options.sortName, this.header.fields);
  654. if (index !== -1) {
  655. this.data.sort(function (a, b) {
  656. var aa = a[name],
  657. bb = b[name],
  658. value = calculateObjectValue(that.header, that.header.sorters[index], [aa, bb]);
  659. if (value !== undefined) {
  660. return order * value;
  661. }
  662. if (value !== undefined) {
  663. return order * value;
  664. }
  665. // Fix #161: undefined or null string sort bug.
  666. if (aa === undefined || aa === null) {
  667. aa = '';
  668. }
  669. if (bb === undefined || bb === null) {
  670. bb = '';
  671. }
  672. // IF both values are numeric, do a numeric comparison
  673. if ($.isNumeric(aa) && $.isNumeric(bb)) {
  674. // Convert numerical values form string to float.
  675. aa = parseFloat(aa);
  676. bb = parseFloat(bb);
  677. if (aa < bb) {
  678. return order * -1;
  679. }
  680. return order;
  681. }
  682. if (aa === bb) {
  683. return 0;
  684. }
  685. // If value is not a string, convert to string
  686. if (typeof aa !== 'string') {
  687. aa = aa.toString();
  688. }
  689. if (aa.localeCompare(bb) === -1) {
  690. return order * -1;
  691. }
  692. return order;
  693. });
  694. }
  695. };
  696. BootstrapTable.prototype.onSort = function (event) {
  697. var $this = $(event.currentTarget),
  698. $this_ = this.$header.find('th').eq($this.index());
  699. this.$header.add(this.$header_).find('span.order').remove();
  700. if (this.options.sortName === $this.data('field')) {
  701. this.options.sortOrder = this.options.sortOrder === 'asc' ? 'desc' : 'asc';
  702. } else {
  703. this.options.sortName = $this.data('field');
  704. this.options.sortOrder = $this.data('order') === 'asc' ? 'desc' : 'asc';
  705. }
  706. this.trigger('sort', this.options.sortName, this.options.sortOrder);
  707. $this.add($this_).data('order', this.options.sortOrder)
  708. .find('.th-inner').append(this.getCaretHtml());
  709. if (this.options.sidePagination === 'server') {
  710. this.initServer();
  711. return;
  712. }
  713. if (this.options.stateSave && cookieEnabled() && (this.options.stateSaveIdTable !== '')) {
  714. setCookie(idSortOrderStateSave, this.options.sortOrder, this.options.stateSaveExpire);
  715. setCookie(idSortNameStateSave, this.options.sortName, this.options.stateSaveExpire);
  716. }
  717. this.initSort();
  718. this.initBody();
  719. };
  720. BootstrapTable.prototype.initToolbar = function () {
  721. var that = this,
  722. html = [],
  723. timeoutId = 0,
  724. $keepOpen,
  725. $search,
  726. switchableCount = 0;
  727. this.$toolbar = this.$container.find('.fixed-table-toolbar').html('');
  728. if (typeof this.options.toolbar === 'string') {
  729. $(sprintf('<div class="bars pull-%s"></div>', this.options.toolbarAlign))
  730. .appendTo(this.$toolbar)
  731. .append($(this.options.toolbar));
  732. }
  733. // showColumns, showToggle, showRefresh
  734. html = [sprintf('<div class="columns columns-%s btn-group pull-%s">',
  735. this.options.buttonsAlign, this.options.buttonsAlign)];
  736. if (typeof this.options.icons === 'string') {
  737. this.options.icons = calculateObjectValue(null, this.options.icons);
  738. }
  739. if (this.options.showPaginationSwitch) {
  740. html.push(sprintf('<button class="btn btn-default" type="button" name="paginationSwitch" title="%s">',
  741. this.options.formatPaginationSwitch()),
  742. sprintf('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.paginationSwitchDown),
  743. '</button>');
  744. }
  745. if (this.options.showRefresh) {
  746. html.push(sprintf('<button class="btn btn-default' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + '" type="button" name="refresh" title="%s">',
  747. this.options.formatRefresh()),
  748. sprintf('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.refresh),
  749. '</button>');
  750. }
  751. if (this.options.showToggle) {
  752. html.push(sprintf('<button class="btn btn-default' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + '" type="button" name="toggle" title="%s">',
  753. this.options.formatToggle()),
  754. sprintf('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.toggle),
  755. '</button>');
  756. }
  757. if (this.options.showColumns) {
  758. html.push(sprintf('<div class="keep-open btn-group" title="%s">',
  759. this.options.formatColumns()),
  760. '<button type="button" class="btn btn-default' + (this.options.iconSize == undefined ? '' : ' btn-' + this.options.iconSize) + ' dropdown-toggle" data-toggle="dropdown">',
  761. sprintf('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.columns),
  762. ' <span class="caret"></span>',
  763. '</button>',
  764. '<ul class="dropdown-menu" role="menu">');
  765. $.each(this.options.columns, function (i, column) {
  766. if (column.radio || column.checkbox) {
  767. return;
  768. }
  769. if (that.options.cardView && (!column.cardVisible)) {
  770. return;
  771. }
  772. var checked = column.visible ? ' checked="checked"' : '';
  773. if (column.switchable) {
  774. html.push(sprintf('<li>' +
  775. '<label><input type="checkbox" data-field="%s" value="%s"%s> %s</label>' +
  776. '</li>', column.field, i, checked, column.title));
  777. switchableCount++;
  778. }
  779. });
  780. html.push('</ul>',
  781. '</div>');
  782. }
  783. html.push('</div>');
  784. // Fix #188: this.showToolbar is for extentions
  785. if (this.showToolbar || html.length > 2) {
  786. this.$toolbar.append(html.join(''));
  787. }
  788. if (this.options.showPaginationSwitch) {
  789. this.$toolbar.find('button[name="paginationSwitch"]')
  790. .off('click').on('click', $.proxy(this.togglePagination, this));
  791. }
  792. if (this.options.showRefresh) {
  793. this.$toolbar.find('button[name="refresh"]')
  794. .off('click').on('click', $.proxy(this.refresh, this));
  795. }
  796. if (this.options.showToggle) {
  797. this.$toolbar.find('button[name="toggle"]')
  798. .off('click').on('click', function () {
  799. that.options.cardView = !that.options.cardView;
  800. that.initHeader();
  801. that.initToolbar();
  802. that.initBody();
  803. });
  804. }
  805. if (this.options.showColumns) {
  806. $keepOpen = this.$toolbar.find('.keep-open');
  807. if (switchableCount <= this.options.minimumCountColumns) {
  808. $keepOpen.find('input').prop('disabled', true);
  809. }
  810. $keepOpen.find('li').off('click').on('click', function (event) {
  811. event.stopImmediatePropagation();
  812. });
  813. $keepOpen.find('input').off('click').on('click', function () {
  814. var $this = $(this);
  815. that.toggleColumn($this.val(), $this.prop('checked'), false);
  816. that.trigger('column-switch', $(this).data('field'), $this.prop('checked'));
  817. });
  818. }
  819. if (this.options.search) {
  820. html = [];
  821. html.push(
  822. '<div class="pull-' + this.options.searchAlign + ' search">',
  823. sprintf('<input class="form-control' + (this.options.iconSize === undefined ? '' : ' input-' + this.options.iconSize) + '" type="text" placeholder="%s">',
  824. this.options.formatSearch()),
  825. '</div>');
  826. this.$toolbar.append(html.join(''));
  827. $search = this.$toolbar.find('.search input');
  828. $search.off('keyup').on('keyup', function (event) {
  829. clearTimeout(timeoutId); // doesn't matter if it's 0
  830. timeoutId = setTimeout(function () {
  831. that.onSearch(event);
  832. }, that.options.searchTimeOut);
  833. });
  834. if (this.options.searchText !== '') {
  835. $search.val(this.options.searchText);
  836. clearTimeout(timeoutId); // doesn't matter if it's 0
  837. timeoutId = setTimeout(function () {
  838. $search.trigger('keyup');
  839. }, that.options.searchTimeOut);
  840. }
  841. }
  842. };
  843. BootstrapTable.prototype.onSearch = function (event) {
  844. var text = $.trim($(event.currentTarget).val());
  845. // trim search input
  846. if (this.options.trimOnSearch) {
  847. $(event.currentTarget).val(text);
  848. }
  849. if (text === this.searchText) {
  850. return;
  851. }
  852. this.searchText = text;
  853. this.options.pageNumber = 1;
  854. this.initSearch();
  855. this.updatePagination();
  856. this.trigger('search', text);
  857. };
  858. BootstrapTable.prototype.initSearch = function () {
  859. var that = this;
  860. if (this.options.sidePagination !== 'server') {
  861. var s = this.searchText && this.searchText.toLowerCase();
  862. var f = $.isEmptyObject(this.filterColumns) ? null : this.filterColumns;
  863. // Check filter
  864. this.data = f ? $.grep(this.options.data, function (item, i) {
  865. for (var key in f) {
  866. if (item[key] !== f[key]) {
  867. return false;
  868. }
  869. }
  870. return true;
  871. }) : this.options.data;
  872. this.data = s ? $.grep(this.data, function (item, i) {
  873. for (var key in item) {
  874. key = $.isNumeric(key) ? parseInt(key, 10) : key;
  875. var value = item[key];
  876. // Fix #142: search use formated data
  877. value = calculateObjectValue(that.header,
  878. that.header.formatters[$.inArray(key, that.header.fields)],
  879. [value, item, i], value);
  880. var index = $.inArray(key, that.header.fields);
  881. if (index !== -1 && that.header.searchables[index] &&
  882. (typeof value === 'string' ||
  883. typeof value === 'number') &&
  884. (value + '').toLowerCase().indexOf(s) !== -1) {
  885. return true;
  886. }
  887. }
  888. return false;
  889. }) : this.data;
  890. }
  891. };
  892. BootstrapTable.prototype.initPagination = function () {
  893. this.$pagination = this.$container.find('.fixed-table-pagination');
  894. if (!this.options.pagination) {
  895. this.$pagination.hide();
  896. return;
  897. } else {
  898. this.$pagination.show();
  899. }
  900. var that = this,
  901. html = [],
  902. $allSelected = false,
  903. i, from, to,
  904. $pageList,
  905. $first, $pre,
  906. $next, $last,
  907. $number,
  908. data = this.getData();
  909. if (this.options.sidePagination !== 'server') {
  910. this.options.totalRows = data.length;
  911. }
  912. this.totalPages = 0;
  913. if (this.options.totalRows) {
  914. if (this.options.pageSize === this.options.formatAllRows()) {
  915. this.options.pageSize = this.options.totalRows;
  916. $allSelected = true;
  917. }
  918. this.totalPages = ~~((this.options.totalRows - 1) / this.options.pageSize) + 1;
  919. this.options.totalPages = this.totalPages;
  920. }
  921. if (this.totalPages > 0 && this.options.pageNumber > this.totalPages) {
  922. this.options.pageNumber = this.totalPages;
  923. }
  924. this.pageFrom = (this.options.pageNumber - 1) * this.options.pageSize + 1;
  925. this.pageTo = this.options.pageNumber * this.options.pageSize;
  926. if (this.pageTo > this.options.totalRows) {
  927. this.pageTo = this.options.totalRows;
  928. }
  929. html.push(
  930. '<div class="pull-' + this.options.paginationDetailHAlign + ' pagination-detail">',
  931. '<span class="pagination-info">',
  932. this.options.formatShowingRows(this.pageFrom, this.pageTo, this.options.totalRows),
  933. '</span>');
  934. html.push('<span class="page-list">');
  935. var pageNumber = [
  936. '<span class="btn-group dropup">',
  937. '<button type="button" class="btn btn-default ' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + ' dropdown-toggle" data-toggle="dropdown">',
  938. '<span class="page-size">',
  939. $allSelected ? this.options.formatAllRows() : this.options.pageSize,
  940. '</span>',
  941. ' <span class="caret"></span>',
  942. '</button>',
  943. '<ul class="dropdown-menu" role="menu">'],
  944. pageList = this.options.pageList;
  945. if (typeof this.options.pageList === 'string') {
  946. var list = this.options.pageList.replace('[', '').replace(']', '').replace(/ /g, '').split(',');
  947. pageList = [];
  948. $.each(list, function (i, value) {
  949. pageList.push(value.toUpperCase() === that.options.formatAllRows().toUpperCase() ?
  950. that.options.formatAllRows() : +value);
  951. });
  952. }
  953. $.each(pageList, function (i, page) {
  954. if (!that.options.smartDisplay || i === 0 || pageList[i - 1] <= that.options.totalRows) {
  955. var active;
  956. if ($allSelected) {
  957. active = page === that.options.formatAllRows() ? ' class="active"' : '';
  958. } else{
  959. active = page === that.options.pageSize ? ' class="active"' : '';
  960. }
  961. pageNumber.push(sprintf('<li%s><a href="javascript:void(0)">%s</a></li>', active, page));
  962. }
  963. });
  964. pageNumber.push('</ul></span>');
  965. html.push(this.options.formatRecordsPerPage(pageNumber.join('')));
  966. html.push('</span>');
  967. html.push('</div>',
  968. '<div class="pull-' + this.options.paginationHAlign + ' pagination">',
  969. '<ul class="pagination' + (this.options.iconSize === undefined ? '' : ' pagination-' + this.options.iconSize) + '">',
  970. '<li class="page-first"><a href="javascript:void(0)">&lt;&lt;</a></li>',
  971. '<li class="page-pre"><a href="javascript:void(0)">&lt;</a></li>');
  972. if (this.totalPages < 5) {
  973. from = 1;
  974. to = this.totalPages;
  975. } else {
  976. from = this.options.pageNumber - 2;
  977. to = from + 4;
  978. if (from < 1) {
  979. from = 1;
  980. to = 5;
  981. }
  982. if (to > this.totalPages) {
  983. to = this.totalPages;
  984. from = to - 4;
  985. }
  986. }
  987. for (i = from; i <= to; i++) {
  988. html.push('<li class="page-number' + (i === this.options.pageNumber ? ' active' : '') + '">',
  989. '<a href="javascript:void(0)">', i, '</a>',
  990. '</li>');
  991. }
  992. html.push(
  993. '<li class="page-next"><a href="javascript:void(0)">&gt;</a></li>',
  994. '<li class="page-last"><a href="javascript:void(0)">&gt;&gt;</a></li>',
  995. '</ul>',
  996. '</div>');
  997. this.$pagination.html(html.join(''));
  998. $pageList = this.$pagination.find('.page-list a');
  999. $first = this.$pagination.find('.page-first');
  1000. $pre = this.$pagination.find('.page-pre');
  1001. $next = this.$pagination.find('.page-next');
  1002. $last = this.$pagination.find('.page-last');
  1003. $number = this.$pagination.find('.page-number');
  1004. if (this.options.pageNumber <= 1) {
  1005. $first.addClass('disabled');
  1006. $pre.addClass('disabled');
  1007. }
  1008. if (this.options.pageNumber >= this.totalPages) {
  1009. $next.addClass('disabled');
  1010. $last.addClass('disabled');
  1011. }
  1012. if (this.options.smartDisplay) {
  1013. if (this.totalPages <= 1) {
  1014. this.$pagination.find('div.pagination').hide();
  1015. }
  1016. if (pageList.length < 2 || this.options.totalRows <= pageList[0]) {
  1017. this.$pagination.find('span.page-list').hide();
  1018. }
  1019. // when data is empty, hide the pagination
  1020. this.$pagination[this.getData().length ? 'show' : 'hide']();
  1021. }
  1022. if ($allSelected) {
  1023. this.options.pageSize = this.options.formatAllRows();
  1024. }
  1025. $pageList.off('click').on('click', $.proxy(this.onPageListChange, this));
  1026. $first.off('click').on('click', $.proxy(this.onPageFirst, this));
  1027. $pre.off('click').on('click', $.proxy(this.onPagePre, this));
  1028. $next.off('click').on('click', $.proxy(this.onPageNext, this));
  1029. $last.off('click').on('click', $.proxy(this.onPageLast, this));
  1030. $number.off('click').on('click', $.proxy(this.onPageNumber, this));
  1031. };
  1032. BootstrapTable.prototype.updatePagination = function (event) {
  1033. // Fix #171: IE disabled button can be clicked bug.
  1034. if (event && $(event.currentTarget).hasClass('disabled')) {
  1035. return;
  1036. }
  1037. if (!this.options.maintainSelected) {
  1038. this.resetRows();
  1039. }
  1040. this.initPagination();
  1041. if (this.options.sidePagination === 'server') {
  1042. this.initServer();
  1043. } else {
  1044. this.initBody();
  1045. }
  1046. this.trigger('page-change', this.options.pageNumber, this.options.pageSize);
  1047. };
  1048. BootstrapTable.prototype.onPageListChange = function (event) {
  1049. var $this = $(event.currentTarget);
  1050. $this.parent().addClass('active').siblings().removeClass('active');
  1051. this.options.pageSize = $this.text().toUpperCase() === this.options.formatAllRows().toUpperCase() ?
  1052. this.options.formatAllRows() : +$this.text();
  1053. this.$toolbar.find('.page-size').text(this.options.pageSize);
  1054. if (this.options.stateSave && cookieEnabled() (this.options.stateSaveIdTable !== '')) {
  1055. setCookie(idPageListStateSave, this.options.pageSize, this.options.stateSaveExpire);
  1056. }
  1057. this.updatePagination(event);
  1058. };
  1059. BootstrapTable.prototype.onPageFirst = function (event) {
  1060. this.options.pageNumber = 1;
  1061. this.updatePagination(event);
  1062. };
  1063. BootstrapTable.prototype.onPagePre = function (event) {
  1064. this.options.pageNumber--;
  1065. this.updatePagination(event);
  1066. };
  1067. BootstrapTable.prototype.onPageNext = function (event) {
  1068. this.options.pageNumber++;
  1069. this.updatePagination(event);
  1070. };
  1071. BootstrapTable.prototype.onPageLast = function (event) {
  1072. this.options.pageNumber = this.totalPages;
  1073. this.updatePagination(event);
  1074. };
  1075. BootstrapTable.prototype.onPageNumber = function (event) {
  1076. if (this.options.pageNumber === +$(event.currentTarget).text()) {
  1077. return;
  1078. }
  1079. this.options.pageNumber = +$(event.currentTarget).text();
  1080. if (this.options.stateSave && cookieEnabled() (this.options.stateSaveIdTable !== '')) {
  1081. setCookie(idPageNumberStateSave, this.options.pageNumber, this.options.stateSaveExpire);
  1082. }
  1083. this.updatePagination(event);
  1084. };
  1085. BootstrapTable.prototype.initBody = function (fixedScroll) {
  1086. var that = this,
  1087. html = [],
  1088. data = this.getData();
  1089. this.trigger('pre-body', data);
  1090. this.$body = this.$el.find('tbody');
  1091. if (!this.$body.length) {
  1092. this.$body = $('<tbody></tbody>').appendTo(this.$el);
  1093. }
  1094. //Fix #389 Bootstrap-table-flatJSON is not working
  1095. if (!this.options.pagination || this.options.sidePagination === 'server') {
  1096. this.pageFrom = 1;
  1097. this.pageTo = data.length;
  1098. }
  1099. for (var i = this.pageFrom - 1; i < this.pageTo; i++) {
  1100. var key,
  1101. item = data[i],
  1102. style = {},
  1103. csses = [],
  1104. attributes = {},
  1105. htmlAttributes = [];
  1106. style = calculateObjectValue(this.options, this.options.rowStyle, [item, i], style);
  1107. if (style && style.css) {
  1108. for (key in style.css) {
  1109. csses.push(key + ': ' + style.css[key]);
  1110. }
  1111. }
  1112. attributes = calculateObjectValue(this.options,
  1113. this.options.rowAttributes, [item, i], attributes);
  1114. if (attributes) {
  1115. for (key in attributes) {
  1116. htmlAttributes.push(sprintf('%s="%s"', key, escapeHTML(attributes[key])));
  1117. }
  1118. }
  1119. html.push('<tr',
  1120. sprintf(' %s', htmlAttributes.join(' ')),
  1121. sprintf(' id="%s"', $.isArray(item) ? undefined : item._id),
  1122. sprintf(' class="%s"', style.classes || ($.isArray(item) ? undefined : item._class)),
  1123. sprintf(' data-index="%s"', i),
  1124. '>'
  1125. );
  1126. if (this.options.cardView) {
  1127. html.push(sprintf('<td colspan="%s">', this.header.fields.length));
  1128. }
  1129. $.each(this.header.fields, function (j, field) {
  1130. var text = '',
  1131. value = item[field],
  1132. type = '',
  1133. cellStyle = {},
  1134. id_ = '',
  1135. class_ = that.header.classes[j],
  1136. data_ = '',
  1137. column = that.options.columns[getFieldIndex(that.options.columns, field)];
  1138. style = sprintf('style="%s"', csses.concat(that.header.styles[j]).join('; '));
  1139. value = calculateObjectValue(that.header,
  1140. that.header.formatters[j], [value, item, i], value);
  1141. // handle td's id and class
  1142. if (item['_' + field + '_id']) {
  1143. id_ = sprintf(' id="%s"', item['_' + field + '_id']);
  1144. }
  1145. if (item['_' + field + '_class']) {
  1146. class_ = sprintf(' class="%s"', item['_' + field + '_class']);
  1147. }
  1148. cellStyle = calculateObjectValue(that.header,
  1149. that.header.cellStyles[j], [value, item, i], cellStyle);
  1150. if (cellStyle.classes) {
  1151. class_ = sprintf(' class="%s"', cellStyle.classes);
  1152. }
  1153. if (cellStyle.css) {
  1154. var csses_ = [];
  1155. for (var key in cellStyle.css) {
  1156. csses_.push(key + ': ' + cellStyle.css[key]);
  1157. }
  1158. style = sprintf('style="%s"', csses_.concat(that.header.styles[j]).join('; '));
  1159. }
  1160. if (item['_' + field + '_data'] && !$.isEmptyObject(item['_' + field + '_data'])) {
  1161. $.each(item['_' + field + '_data'], function (k, v) {
  1162. // ignore data-index
  1163. if (k === 'index') {
  1164. return;
  1165. }
  1166. data_ += sprintf(' data-%s="%s"', k, v);
  1167. });
  1168. }
  1169. if (column.checkbox || column.radio) {
  1170. type = column.checkbox ? 'checkbox' : type;
  1171. type = column.radio ? 'radio' : type;
  1172. text = [that.options.cardView ?
  1173. '<div class="card-view">' : '<td class="bs-checkbox">',
  1174. '<input' +
  1175. sprintf(' data-index="%s"', i) +
  1176. sprintf(' name="%s"', that.options.selectItemName) +
  1177. sprintf(' type="%s"', type) +
  1178. sprintf(' value="%s"', item[that.options.idField]) +
  1179. sprintf(' checked="%s"', value === true ||
  1180. (value && value.checked) ? 'checked' : undefined) +
  1181. sprintf(' disabled="%s"', !column.checkboxEnabled ||
  1182. (value && value.disabled) ? 'disabled' : undefined) +
  1183. ' />',
  1184. that.options.cardView ? '</div>' : '</td>'].join('');
  1185. } else {
  1186. value = typeof value === 'undefined' || value === null ?
  1187. that.options.undefinedText : value;
  1188. text = that.options.cardView ?
  1189. ['<div class="card-view">',
  1190. that.options.showHeader ? sprintf('<span class="title" %s>%s</span>', style,
  1191. getPropertyFromOther(that.options.columns, 'field', 'title', field)) : '',
  1192. sprintf('<span class="value">%s</span>', value),
  1193. '</div>'].join('') :
  1194. [sprintf('<td%s %s %s %s>', id_, class_, style, data_),
  1195. value,
  1196. '</td>'].join('');
  1197. // Hide empty data on Card view when smartDisplay is set to true.
  1198. if (that.options.cardView && that.options.smartDisplay && value === '') {
  1199. text = '';
  1200. }
  1201. }
  1202. html.push(text);
  1203. });
  1204. if (this.options.cardView) {
  1205. html.push('</td>');
  1206. }
  1207. html.push('</tr>');
  1208. }
  1209. // show no records
  1210. if (!html.length) {
  1211. html.push('<tr class="no-records-found">',
  1212. sprintf('<td colspan="%s">%s</td>', this.header.fields.length, this.options.formatNoMatches()),
  1213. '</tr>');
  1214. }
  1215. this.$body.html(html.join(''));
  1216. if (!fixedScroll) {
  1217. this.scrollTo(0);
  1218. }
  1219. // click to select by column
  1220. this.$body.find('> tr > td').off('click').on('click', function () {
  1221. var $tr = $(this).parent();
  1222. that.trigger('click-row', that.data[$tr.data('index')], $tr);
  1223. // if click to select - then trigger the checkbox/radio click
  1224. if (that.options.clickToSelect) {
  1225. if (that.header.clickToSelects[$tr.children().index($(this))]) {
  1226. $tr.find(sprintf('[name="%s"]',
  1227. that.options.selectItemName))[0].click(); // #144: .trigger('click') bug
  1228. }
  1229. }
  1230. });
  1231. this.$body.find('tr').off('dblclick').on('dblclick', function () {
  1232. that.trigger('dbl-click-row', that.data[$(this).data('index')], $(this));
  1233. });
  1234. this.$selectItem = this.$body.find(sprintf('[name="%s"]', this.options.selectItemName));
  1235. this.$selectItem.off('click').on('click', function (event) {
  1236. event.stopImmediatePropagation();
  1237. var checked = $(this).prop('checked'),
  1238. row = that.data[$(this).data('index')];
  1239. row[that.header.stateField] = checked;
  1240. that.trigger(checked ? 'check' : 'uncheck', row);
  1241. if (that.options.singleSelect) {
  1242. that.$selectItem.not(this).each(function () {
  1243. that.data[$(this).data('index')][that.header.stateField] = false;
  1244. });
  1245. that.$selectItem.filter(':checked').not(this).prop('checked', false);
  1246. }
  1247. that.updateSelected();
  1248. });
  1249. $.each(this.header.events, function (i, events) {
  1250. if (!events) {
  1251. return;
  1252. }
  1253. // fix bug, if events is defined with namespace
  1254. if (typeof events === 'string') {
  1255. events = calculateObjectValue(null, events);
  1256. }
  1257. for (var key in events) {
  1258. that.$body.find('tr').each(function () {
  1259. var $tr = $(this),
  1260. $td = $tr.find(that.options.cardView ? '.card-view' : 'td').eq(i),
  1261. index = key.indexOf(' '),
  1262. name = key.substring(0, index),
  1263. el = key.substring(index + 1),
  1264. func = events[key];
  1265. $td.find(el).off(name).on(name, function (e) {
  1266. var index = $tr.data('index'),
  1267. row = that.data[index],
  1268. value = row[that.header.fields[i]];
  1269. func.apply(this, [e, value, row, index]);
  1270. });
  1271. });
  1272. }
  1273. });
  1274. this.updateSelected();
  1275. this.resetView();
  1276. this.trigger('post-body');
  1277. };
  1278. BootstrapTable.prototype.initServer = function (silent, query) {
  1279. var that = this,
  1280. data = {},
  1281. params = {
  1282. pageSize: this.options.pageSize === this.options.formatAllRows() ? this.options.totalRows : this.options.pageSize,
  1283. pageNumber: this.options.pageNumber,
  1284. searchText: this.searchText,
  1285. sortName: this.options.sortName,
  1286. sortOrder: this.options.sortOrder
  1287. };
  1288. if (!this.options.url) {
  1289. return;
  1290. }
  1291. if (this.options.queryParamsType === 'limit') {
  1292. params = {
  1293. search: params.searchText,
  1294. sort: params.sortName,
  1295. order: params.sortOrder
  1296. };
  1297. if (this.options.pagination) {
  1298. params.limit = this.options.pageSize === this.options.formatAllRows() ? this.options.totalRows : this.options.pageSize;
  1299. params.offset = (this.options.pageSize === this.options.formatAllRows() ? this.options.totalRows : this.options.pageSize)
  1300. * (this.options.pageNumber - 1);
  1301. }
  1302. }
  1303. data = calculateObjectValue(this.options, this.options.queryParams, [params], data);
  1304. $.extend(data, query || {});
  1305. // false to stop request
  1306. if (data === false) {
  1307. return;
  1308. }
  1309. if (!silent) {
  1310. this.$loading.show();
  1311. }
  1312. $.ajax($.extend({}, calculateObjectValue(null, this.options.ajaxOptions), {
  1313. type: this.options.method,
  1314. url: this.options.url,
  1315. data: this.options.contentType === 'application/json' && this.options.method === 'post' ?
  1316. JSON.stringify(data) : data,
  1317. cache: this.options.cache,
  1318. contentType: this.options.contentType,
  1319. dataType: this.options.dataType,
  1320. success: function (res) {
  1321. res = calculateObjectValue(that.options, that.options.responseHandler, [res], res);
  1322. that.load(res);
  1323. that.trigger('load-success', res);
  1324. },
  1325. error: function (res) {
  1326. that.trigger('load-error', res.status);
  1327. },
  1328. complete: function () {
  1329. if (!silent) {
  1330. that.$loading.hide();
  1331. }
  1332. }
  1333. }));
  1334. };
  1335. BootstrapTable.prototype.initKeyEvents = function () {
  1336. if (this.options.keyEvents) {
  1337. var that = this;
  1338. $(document).off('keypress').on('keypress', function (e) {
  1339. if (!that.options.search) {
  1340. return;
  1341. }
  1342. switch (e.keyCode) {
  1343. case 115://s
  1344. case 83://S
  1345. var $search = that.$toolbar.find('.search input');
  1346. if(document.activeElement === $search.get(0)){
  1347. return true;
  1348. }
  1349. $search.focus();
  1350. return false;
  1351. }
  1352. });
  1353. }
  1354. };
  1355. BootstrapTable.prototype.initStateSave = function () {
  1356. if (!this.options.stateSave) {
  1357. return;
  1358. }
  1359. if (!cookieEnabled()) {
  1360. return;
  1361. }
  1362. if (this.options.stateSaveIdTable === '') {
  1363. return;
  1364. }
  1365. idStateSave = this.options.stateSaveIdTable + '.';
  1366. var sortOrderStateSave = getCookie(idSortOrderStateSave),
  1367. sortOrderStateName = getCookie(idSortNameStateSave),
  1368. pageNumberStateSave = getCookie(idPageNumberStateSave),
  1369. pageListStateSave = getCookie(idPageListStateSave);
  1370. if (sortOrderStateSave !== undefined && sortOrderStateSave !== null) {
  1371. this.options.sortOrder = sortOrderStateSave,
  1372. this.options.sortName = sortOrderStateName;
  1373. }
  1374. if (pageNumberStateSave !== undefined && pageNumberStateSave !== null) {
  1375. this.options.pageNumber = +pageNumberStateSave;
  1376. }
  1377. if (pageListStateSave !== undefined && pageListStateSave !== null) {
  1378. this.options.pageSize = pageListStateSave === this.options.formatAllRows() ? pageListStateSave : +pageListStateSave;
  1379. }
  1380. };
  1381. BootstrapTable.prototype.getCaretHtml = function () {
  1382. return ['<span class="order' + (this.options.sortOrder === 'desc' ? '' : ' dropup') + '">',
  1383. '<span class="caret" style="margin: 10px 5px;"></span>',
  1384. '</span>'].join('');
  1385. };
  1386. BootstrapTable.prototype.updateSelected = function () {
  1387. var checkAll = this.$selectItem.filter(':enabled').length ===
  1388. this.$selectItem.filter(':enabled').filter(':checked').length;
  1389. this.$selectAll.add(this.$selectAll_).prop('checked', checkAll);
  1390. this.$selectItem.each(function () {
  1391. $(this).parents('tr')[$(this).prop('checked') ? 'addClass' : 'removeClass']('selected');
  1392. });
  1393. };
  1394. BootstrapTable.prototype.updateRows = function (checked) {
  1395. var that = this;
  1396. this.$selectItem.each(function () {
  1397. that.data[$(this).data('index')][that.header.stateField] = checked;
  1398. });
  1399. };
  1400. BootstrapTable.prototype.resetRows = function () {
  1401. var that = this;
  1402. $.each(this.data, function (i, row) {
  1403. that.$selectAll.prop('checked', false);
  1404. that.$selectItem.prop('checked', false);
  1405. row[that.header.stateField] = false;
  1406. });
  1407. };
  1408. BootstrapTable.prototype.trigger = function (name) {
  1409. var args = Array.prototype.slice.call(arguments, 1);
  1410. name += '.bs.table';
  1411. this.options[BootstrapTable.EVENTS[name]].apply(this.options, args);
  1412. this.$el.trigger($.Event(name), args);
  1413. this.options.onAll(name, args);
  1414. this.$el.trigger($.Event('all.bs.table'), [name, args]);
  1415. };
  1416. BootstrapTable.prototype.resetHeader = function () {
  1417. this.$el.css('margin-top', -this.$header.height());
  1418. // fix #61: the hidden table reset header bug.
  1419. // fix bug: get $el.css('width') error sometime (height = 500)
  1420. clearTimeout(this.timeoutId_);
  1421. this.timeoutId_ = setTimeout($.proxy(this.fitHeader, this), this.$el.is(':hidden') ? 100 : 0);
  1422. return;
  1423. };
  1424. BootstrapTable.prototype.fitHeader = function () {
  1425. var that = this,
  1426. $fixedHeader,
  1427. $fixedBody,
  1428. scrollWidth;
  1429. if (that.$el.is(':hidden')) {
  1430. that.timeoutFooter_ = setTimeout($.proxy(that.fitHeader, that), 100);
  1431. return;
  1432. }
  1433. $fixedHeader = that.$container.find('.fixed-table-header'),
  1434. $fixedBody = that.$container.find('.fixed-table-body'),
  1435. scrollWidth = that.$el.width() > $fixedBody.width() ? getScrollBarWidth() : 0;
  1436. that.$header_ = that.$header.clone(true, true);
  1437. that.$selectAll_ = that.$header_.find('[name="btSelectAll"]');
  1438. $fixedHeader.css({
  1439. 'margin-right': scrollWidth
  1440. }).find('table').css('width', that.$el.css('width'))
  1441. .html('').attr('class', that.$el.attr('class'))
  1442. .append(that.$header_);
  1443. // fix bug: $.data() is not working as expected after $.append()
  1444. that.$header.find('th').each(function (i) {
  1445. that.$header_.find('th').eq(i).data($(this).data());
  1446. });
  1447. that.$body.find('tr:first-child:not(.no-records-found) > *').each(function (i) {
  1448. that.$header_.find('div.fht-cell').eq(i).width($(this).innerWidth());
  1449. });
  1450. // horizontal scroll event
  1451. // TODO: it's probably better improving the layout than binding to scroll event
  1452. $fixedBody.off('scroll').on('scroll', function () {
  1453. $fixedHeader.scrollLeft($(this).scrollLeft());
  1454. });
  1455. that.trigger('post-header');
  1456. };
  1457. BootstrapTable.prototype.toggleColumn = function (index, checked, needUpdate) {
  1458. if (index === -1) {
  1459. return;
  1460. }
  1461. this.options.columns[index].visible = checked;
  1462. this.initHeader();
  1463. this.initSearch();
  1464. this.initPagination();
  1465. this.initBody();
  1466. if (this.options.showColumns) {
  1467. var $items = this.$toolbar.find('.keep-open input').prop('disabled', false);
  1468. if (needUpdate) {
  1469. $items.filter(sprintf('[value="%s"]', index)).prop('checked', checked);
  1470. }
  1471. if ($items.filter(':checked').length <= this.options.minimumCountColumns) {
  1472. $items.filter(':checked').prop('disabled', true);
  1473. }
  1474. }
  1475. };
  1476. BootstrapTable.prototype.toggleRow = function (index, visible) {
  1477. if (index === -1) {
  1478. return;
  1479. }
  1480. this.$selectItem.filter(sprintf('[data-index="%s"]', index))
  1481. .parents('tr')[visible ? 'show' : 'hide']();
  1482. };
  1483. // PUBLIC FUNCTION DEFINITION
  1484. // =======================
  1485. BootstrapTable.prototype.resetView = function (params) {
  1486. var that = this,
  1487. padding = 0,
  1488. $tableContainer = that.$container.find('.fixed-table-container');
  1489. if (params && params.height) {
  1490. this.options.height = params.height;
  1491. }
  1492. this.$selectAll.prop('checked', this.$selectItem.length > 0 &&
  1493. this.$selectItem.length === this.$selectItem.filter(':checked').length);
  1494. if (this.options.height) {
  1495. var toolbarHeight = +this.$toolbar.children().outerHeight(true),
  1496. paginationHeight = +this.$pagination.children().outerHeight(true),
  1497. height = this.options.height - toolbarHeight - paginationHeight;
  1498. $tableContainer.css('height', height + 'px');
  1499. }
  1500. if (this.options.cardView) {
  1501. // remove the element css
  1502. that.$el.css('margin-top', '0');
  1503. $tableContainer.css('padding-bottom', '0');
  1504. return;
  1505. }
  1506. if (this.options.showHeader && this.options.height) {
  1507. this.resetHeader();
  1508. padding += cellHeight;
  1509. } else {
  1510. this.trigger('post-header');
  1511. }
  1512. if (this.options.showFooter) {
  1513. this.resetFooter();
  1514. if (this.options.height) {
  1515. padding += cellHeight;
  1516. }
  1517. }
  1518. $tableContainer.css('padding-bottom', padding + 'px');
  1519. };
  1520. BootstrapTable.prototype.getData = function () {
  1521. return (this.searchText || !$.isEmptyObject(this.filterColumns)) ? this.data : this.options.data;
  1522. };
  1523. BootstrapTable.prototype.load = function (data) {
  1524. var fixedScroll = false;
  1525. // #431: support pagination
  1526. if (this.options.sidePagination === 'server') {
  1527. this.options.totalRows = data.total;
  1528. fixedScroll = data.fixedScroll;
  1529. data = data.rows;
  1530. } else if (!$.isArray(data)) { // support fixedScroll
  1531. fixedScroll = data.fixedScroll;
  1532. data = data.data;
  1533. }
  1534. this.initData(data);
  1535. this.initSearch();
  1536. this.initPagination();
  1537. this.initBody(fixedScroll);
  1538. };
  1539. BootstrapTable.prototype.append = function (data) {
  1540. this.initData(data, 'append');
  1541. this.initSearch();
  1542. this.initPagination();
  1543. this.initBody(true);
  1544. };
  1545. BootstrapTable.prototype.prepend = function (data) {
  1546. this.initData(data, 'prepend');
  1547. this.initSearch();
  1548. this.initPagination();
  1549. this.initBody(true);
  1550. };
  1551. BootstrapTable.prototype.remove = function (params) {
  1552. var len = this.options.data.length,
  1553. i, row;
  1554. if (!params.hasOwnProperty('field') || !params.hasOwnProperty('values')) {
  1555. return;
  1556. }
  1557. for (i = len - 1; i >= 0; i--) {
  1558. row = this.options.data[i];
  1559. if (!row.hasOwnProperty(params.field)) {
  1560. continue;
  1561. }
  1562. if ($.inArray(row[params.field], params.values) !== -1) {
  1563. this.options.data.splice(i, 1);
  1564. }
  1565. }
  1566. if (len === this.options.data.length) {
  1567. return;
  1568. }
  1569. this.initSearch();
  1570. this.initPagination();
  1571. this.initBody(true);
  1572. };
  1573. BootstrapTable.prototype.insertRow = function (params) {
  1574. if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {
  1575. return;
  1576. }
  1577. this.data.splice(params.index, 0, params.row);
  1578. this.initBody(true);
  1579. };
  1580. BootstrapTable.prototype.updateRow = function (params) {
  1581. if (!params.hasOwnProperty('index') || !params.hasOwnProperty('row')) {
  1582. return;
  1583. }
  1584. $.extend(this.data[params.index], params.row);
  1585. this.initBody(true);
  1586. };
  1587. BootstrapTable.prototype.showRow = function (index) {
  1588. this.toggleRow(index, true);
  1589. };
  1590. BootstrapTable.prototype.hideRow = function (index) {
  1591. this.toggleRow(index, false);
  1592. };
  1593. BootstrapTable.prototype.mergeCells = function (options) {
  1594. var row = options.index,
  1595. col = $.inArray(options.field, this.header.fields),
  1596. rowspan = options.rowspan || 1,
  1597. colspan = options.colspan || 1,
  1598. i, j,
  1599. $tr = this.$body.find('tr'),
  1600. $td = $tr.eq(row).find('td').eq(col);
  1601. if (row < 0 || col < 0 || row >= this.data.length) {
  1602. return;
  1603. }
  1604. for (i = row; i < row + rowspan; i++) {
  1605. for (j = col; j < col + colspan; j++) {
  1606. $tr.eq(i).find('td').eq(j).hide();
  1607. }
  1608. }
  1609. $td.attr('rowspan', rowspan).attr('colspan', colspan).show();
  1610. };
  1611. BootstrapTable.prototype.getOptions = function () {
  1612. return this.options;
  1613. };
  1614. BootstrapTable.prototype.getSelections = function () {
  1615. var that = this;
  1616. return $.grep(this.data, function (row) {
  1617. return row[that.header.stateField];
  1618. });
  1619. };
  1620. BootstrapTable.prototype.checkAll = function () {
  1621. this.checkAll_(true);
  1622. };
  1623. BootstrapTable.prototype.uncheckAll = function () {
  1624. this.checkAll_(false);
  1625. };
  1626. BootstrapTable.prototype.checkAll_ = function (checked) {
  1627. var rows;
  1628. if (!checked) {
  1629. rows = this.getSelections();
  1630. }
  1631. this.$selectItem.filter(':enabled').prop('checked', checked);
  1632. this.updateRows(checked);
  1633. this.updateSelected();
  1634. if (checked) {
  1635. rows = this.getSelections();
  1636. }
  1637. this.trigger(checked ? 'check-all' : 'uncheck-all', rows);
  1638. };
  1639. BootstrapTable.prototype.check = function (index) {
  1640. this.check_(true, index);
  1641. };
  1642. BootstrapTable.prototype.uncheck = function (index) {
  1643. this.check_(false, index);
  1644. };
  1645. BootstrapTable.prototype.check_ = function (checked, index) {
  1646. this.$selectItem.filter(sprintf('[data-index="%s"]', index)).prop('checked', checked);
  1647. this.data[index][this.header.stateField] = checked;
  1648. this.updateSelected();
  1649. this.trigger(checked ? 'check' : 'uncheck', this.data[index]);
  1650. };
  1651. BootstrapTable.prototype.checkBy = function (obj) {
  1652. this.checkBy_(true, obj);
  1653. };
  1654. BootstrapTable.prototype.uncheckBy = function (obj) {
  1655. this.checkBy_(false, obj);
  1656. };
  1657. BootstrapTable.prototype.checkBy_ = function (checked, obj) {
  1658. if (!obj.hasOwnProperty('field') || !obj.hasOwnProperty('values')) {
  1659. return;
  1660. }
  1661. var that = this;
  1662. $.each(this.options.data, function (index, row) {
  1663. if (!row.hasOwnProperty(obj.field)) {
  1664. return false;
  1665. }
  1666. if ($.inArray(row[obj.field], obj.values) !== -1) {
  1667. that.$selectItem.filter(sprintf('[data-index="%s"]', index)).prop('checked', checked);
  1668. row[that.header.stateField] = checked;
  1669. that.trigger(checked ? 'check' : 'uncheck', row);
  1670. }
  1671. });
  1672. this.updateSelected();
  1673. };
  1674. BootstrapTable.prototype.destroy = function () {
  1675. this.$el.insertBefore(this.$container);
  1676. $(this.options.toolbar).insertBefore(this.$el);
  1677. this.$container.next().remove();
  1678. this.$container.remove();
  1679. this.$el.html(this.$el_.html())
  1680. .css('margin-top', '0')
  1681. .attr('class', this.$el_.attr('class') || ''); // reset the class
  1682. };
  1683. BootstrapTable.prototype.showLoading = function () {
  1684. this.$loading.show();
  1685. };
  1686. BootstrapTable.prototype.hideLoading = function () {
  1687. this.$loading.hide();
  1688. };
  1689. BootstrapTable.prototype.togglePagination = function () {
  1690. this.options.pagination = !this.options.pagination;
  1691. var button = this.$toolbar.find('button[name="paginationSwitch"] i');
  1692. if (this.options.pagination) {
  1693. button.attr("class", this.options.iconsPrefix + " " + this.options.icons.paginationSwitchDown);
  1694. } else {
  1695. button.attr("class", this.options.iconsPrefix + " " + this.options.icons.paginationSwitchUp);
  1696. }
  1697. this.updatePagination();
  1698. };
  1699. BootstrapTable.prototype.refresh = function (params) {
  1700. if (params && params.url) {
  1701. this.options.url = params.url;
  1702. this.options.pageNumber = 1;
  1703. }
  1704. this.initServer(params && params.silent, params && params.query);
  1705. };
  1706. BootstrapTable.prototype.showColumn = function (field) {
  1707. this.toggleColumn(getFieldIndex(this.options.columns, field), true, true);
  1708. };
  1709. BootstrapTable.prototype.hideColumn = function (field) {
  1710. this.toggleColumn(getFieldIndex(this.options.columns, field), false, true);
  1711. };
  1712. BootstrapTable.prototype.filterBy = function (columns) {
  1713. this.filterColumns = $.isEmptyObject(columns) ? {} : columns;
  1714. this.options.pageNumber = 1;
  1715. this.initSearch();
  1716. this.updatePagination();
  1717. };
  1718. BootstrapTable.prototype.scrollTo = function (value) {
  1719. var $tbody = this.$container.find('.fixed-table-body');
  1720. if (typeof value === 'string') {
  1721. value = value === 'bottom' ? $tbody[0].scrollHeight : 0;
  1722. }
  1723. if (typeof value === 'number') {
  1724. $tbody.scrollTop(value);
  1725. }
  1726. };
  1727. BootstrapTable.prototype.selectPage = function (page) {
  1728. if (page > 0 && page <= this.options.totalPages) {
  1729. this.options.pageNumber = page;
  1730. this.updatePagination();
  1731. }
  1732. };
  1733. BootstrapTable.prototype.prevPage = function () {
  1734. if (this.options.pageNumber > 1) {
  1735. this.options.pageNumber--;
  1736. this.updatePagination();
  1737. }
  1738. };
  1739. BootstrapTable.prototype.nextPage = function () {
  1740. if (this.options.pageNumber < this.options.totalPages) {
  1741. this.options.pageNumber++;
  1742. this.updatePagination();
  1743. }
  1744. };
  1745. BootstrapTable.prototype.toggleView = function () {
  1746. this.options.cardView = !this.options.cardView;
  1747. this.initHeader();
  1748. this.initToolbar();
  1749. this.initBody();
  1750. };
  1751. BootstrapTable.prototype.deleteCookie = function (cookieName) {
  1752. if (cookieName === '') {
  1753. return;
  1754. }
  1755. if (!cookieEnabled()) {
  1756. return;
  1757. }
  1758. deleteCookie(idsStateSaveList[cookieName]);
  1759. }
  1760. // BOOTSTRAP TABLE PLUGIN DEFINITION
  1761. // =======================
  1762. var allowedMethods = [
  1763. 'getOptions',
  1764. 'getSelections', 'getData',
  1765. 'load', 'append', 'prepend', 'remove',
  1766. 'insertRow', 'updateRow',
  1767. 'showRow', 'hideRow',
  1768. 'mergeCells',
  1769. 'checkAll', 'uncheckAll',
  1770. 'check', 'uncheck',
  1771. 'checkBy', 'uncheckBy',
  1772. 'refresh',
  1773. 'resetView',
  1774. 'destroy',
  1775. 'showLoading', 'hideLoading',
  1776. 'showColumn', 'hideColumn',
  1777. 'filterBy',
  1778. 'scrollTo',
  1779. 'selectPage', 'prevPage', 'nextPage',
  1780. 'togglePagination',
  1781. 'toggleView',
  1782. 'deleteCookie'
  1783. ];
  1784. $.fn.bootstrapTable = function (option, _relatedTarget) {
  1785. var value;
  1786. this.each(function () {
  1787. var $this = $(this),
  1788. data = $this.data('bootstrap.table'),
  1789. options = $.extend({}, BootstrapTable.DEFAULTS, $this.data(),
  1790. typeof option === 'object' && option);
  1791. if (typeof option === 'string') {
  1792. if ($.inArray(option, allowedMethods) < 0) {
  1793. throw "Unknown method: " + option;
  1794. }
  1795. if (!data) {
  1796. return;
  1797. }
  1798. value = data[option](_relatedTarget);
  1799. if (option === 'destroy') {
  1800. $this.removeData('bootstrap.table');
  1801. }
  1802. }
  1803. if (!data) {
  1804. $this.data('bootstrap.table', (data = new BootstrapTable(this, options)));
  1805. }
  1806. });
  1807. return typeof value === 'undefined' ? this : value;
  1808. };
  1809. $.fn.bootstrapTable.Constructor = BootstrapTable;
  1810. $.fn.bootstrapTable.defaults = BootstrapTable.DEFAULTS;
  1811. $.fn.bootstrapTable.columnDefaults = BootstrapTable.COLUMN_DEFAULTS;
  1812. $.fn.bootstrapTable.locales = BootstrapTable.LOCALES;
  1813. $.fn.bootstrapTable.methods = allowedMethods;
  1814. // BOOTSTRAP TABLE INIT
  1815. // =======================
  1816. $(function () {
  1817. $('[data-toggle="table"]').bootstrapTable();
  1818. });
  1819. }(jQuery);