Merge pull request #910 from SchrodingersGat/multi-level-bom

Multi level bom
This commit is contained in:
Oliver 2020-08-18 21:28:47 +10:00 committed by GitHub
commit 13b64c6a04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
116 changed files with 21705 additions and 20 deletions

View File

@ -0,0 +1,170 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @update: zhixin wen <wenzhixin2010@gmail.com>
*/
!($ => {
const diacriticsMap = {}
const defaultAccentsDiacritics = [
{base: 'A', letters: '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F'},
{base: 'AA',letters: '\uA732'},
{base: 'AE',letters: '\u00C6\u01FC\u01E2'},
{base: 'AO',letters: '\uA734'},
{base: 'AU',letters: '\uA736'},
{base: 'AV',letters: '\uA738\uA73A'},
{base: 'AY',letters: '\uA73C'},
{base: 'B', letters: '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181'},
{base: 'C', letters: '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E'},
{base: 'D', letters: '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779'},
{base: 'DZ',letters: '\u01F1\u01C4'},
{base: 'Dz',letters: '\u01F2\u01C5'},
{base: 'E', letters: '\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E'},
{base: 'F', letters: '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B'},
{base: 'G', letters: '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E'},
{base: 'H', letters: '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D'},
{base: 'I', letters: '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197'},
{base: 'J', letters: '\u004A\u24BF\uFF2A\u0134\u0248'},
{base: 'K', letters: '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2'},
{base: 'L', letters: '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780'},
{base: 'LJ',letters: '\u01C7'},
{base: 'Lj',letters: '\u01C8'},
{base: 'M', letters: '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C'},
{base: 'N', letters: '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4'},
{base: 'NJ',letters: '\u01CA'},
{base: 'Nj',letters: '\u01CB'},
{base: 'O', letters: '\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C'},
{base: 'OI',letters: '\u01A2'},
{base: 'OO',letters: '\uA74E'},
{base: 'OU',letters: '\u0222'},
{base: 'OE',letters: '\u008C\u0152'},
{base: 'oe',letters: '\u009C\u0153'},
{base: 'P', letters: '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754'},
{base: 'Q', letters: '\u0051\u24C6\uFF31\uA756\uA758\u024A'},
{base: 'R', letters: '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782'},
{base: 'S', letters: '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784'},
{base: 'T', letters: '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786'},
{base: 'TZ',letters: '\uA728'},
{base: 'U', letters: '\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244'},
{base: 'V', letters: '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245'},
{base: 'VY',letters: '\uA760'},
{base: 'W', letters: '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72'},
{base: 'X', letters: '\u0058\u24CD\uFF38\u1E8A\u1E8C'},
{base: 'Y', letters: '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE'},
{base: 'Z', letters: '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762'},
{base: 'a', letters: '\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250'},
{base: 'aa',letters: '\uA733'},
{base: 'ae',letters: '\u00E6\u01FD\u01E3'},
{base: 'ao',letters: '\uA735'},
{base: 'au',letters: '\uA737'},
{base: 'av',letters: '\uA739\uA73B'},
{base: 'ay',letters: '\uA73D'},
{base: 'b', letters: '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253'},
{base: 'c', letters: '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184'},
{base: 'd', letters: '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A'},
{base: 'dz',letters: '\u01F3\u01C6'},
{base: 'e', letters: '\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD'},
{base: 'f', letters: '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C'},
{base: 'g', letters: '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F'},
{base: 'h', letters: '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265'},
{base: 'hv',letters: '\u0195'},
{base: 'i', letters: '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131'},
{base: 'j', letters: '\u006A\u24D9\uFF4A\u0135\u01F0\u0249'},
{base: 'k', letters: '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3'},
{base: 'l', letters: '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747'},
{base: 'lj',letters: '\u01C9'},
{base: 'm', letters: '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F'},
{base: 'n', letters: '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5'},
{base: 'nj',letters: '\u01CC'},
{base: 'o', letters: '\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275'},
{base: 'oi',letters: '\u01A3'},
{base: 'ou',letters: '\u0223'},
{base: 'oo',letters: '\uA74F'},
{base: 'p',letters: '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755'},
{base: 'q',letters: '\u0071\u24E0\uFF51\u024B\uA757\uA759'},
{base: 'r',letters: '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783'},
{base: 's',letters: '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B'},
{base: 't',letters: '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787'},
{base: 'tz',letters: '\uA729'},
{base: 'u',letters: '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289'},
{base: 'v',letters: '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C'},
{base: 'vy',letters: '\uA761'},
{base: 'w',letters: '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73'},
{base: 'x',letters: '\u0078\u24E7\uFF58\u1E8B\u1E8D'},
{base: 'y',letters: '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF'},
{base: 'z',letters: '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763'}
]
const initNeutraliser = () => {
for (const diacritic of defaultAccentsDiacritics) {
const letters = diacritic.letters
for (let i = 0; i < letters.length; i++) {
diacriticsMap[letters[i]] = diacritic.base
}
}
}
/* eslint-disable no-control-regex */
const removeDiacritics = str => str.replace(/[^\u0000-\u007E]/g, a => diacriticsMap[a] || a)
$.extend($.fn.bootstrapTable.defaults, {
searchAccentNeutralise: false
})
$.BootstrapTable = class extends $.BootstrapTable {
init () {
if (this.options.searchAccentNeutralise) {
initNeutraliser()
}
super.init()
}
initSearch () {
if (this.options.sidePagination !== 'server') {
let s = this.searchText && this.searchText.toLowerCase()
const f = $.isEmptyObject(this.filterColumns) ? null : this.filterColumns
// Check filter
this.data = f ? this.options.data.filter((item, i) => {
for (const key in f) {
if (item[key] !== f[key]) {
return false
}
}
return true
}) : this.options.data
this.data = s ? this.options.data.filter((item, i) => {
for (let [key, value] of Object.entries(item)) {
key = $.isNumeric(key) ? parseInt(key, 10) : key
const column = this.columns[this.fieldsColumnsIndex[key]]
const j = this.header.fields.indexOf(key)
if (column && column.searchFormatter) {
value = $.fn.bootstrapTable.utils.calculateObjectValue(column,
this.header.formatters[j], [value, item, i], value)
}
const index = this.header.fields.indexOf(key)
if (index !== -1 && this.header.searchables[index] && typeof value === 'string') {
if (this.options.searchAccentNeutralise) {
value = removeDiacritics(value)
s = removeDiacritics(s)
}
if (this.options.strictSearch) {
if ((`${value}`).toLowerCase() === s) {
return true
}
} else {
if ((`${value}`).toLowerCase().includes(s)) {
return true
}
}
}
}
return false
}) : this.data
}
}
}
})(jQuery)

View File

@ -0,0 +1,17 @@
{
"name": "Accent Neutralise",
"version": "1.0.0",
"description": "Plugin to neutralise the words.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/accent-neutralise",
"example": "#",
"plugins": [{
"name": "bootstrap-table-accent-neutralise",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/accent-neutralise"
}],
"author": {
"name": "djhvscf",
"image": "https://avatars1.githubusercontent.com/u/4496763"
}
}

View File

@ -0,0 +1,116 @@
/**
* @author: general
* @website: note.generals.space
* @email: generals.space@gmail.com
* @github: https://github.com/generals-space/bootstrap-table-addrbar
* @update: zhixin wen <wenzhixin2010@gmail.com>
*/
($ => {
/*
* function: 获取浏览器地址栏中的指定参数.
* key: 参数名
* url: 默认为当前地址栏
*/
function _GET (key, url = window.location.search) {
/*
* 注意这里正则表达式的书写方法
* (^|&)key匹配: 直接以key开始或以&key开始的字符串
* 同理(&|$)表示以&结束或是直接结束的字符串
* ...当然, 我并不知道这种用法.
*/
const reg = new RegExp(`(^|&)${key}=([^&]*)(&|$)`)
const result = url.substr(1).match(reg)
if (result) {
return decodeURIComponent(result[2])
}
return null
}
/*
* function: 根据给定参数生成url地址
* var dic = {name: 'genreal', age: 24}
* var url = 'https://www.baidu.com?age=22';
* _buildUrl(dic, url);
* 将得到"https://www.baidu.com?age=24&name=genreal"
* , 忽略先后顺序吧...
*
* 补充: 可以参考浏览器URLSearchParams对象, 更加方便和强大.
* 考虑到兼容性, 暂时不使用这个工具.
*/
function _buildUrl (dict, url = window.location.search) {
for (const [key, val] of Object.entries(dict)) {
// 搜索name=general这种形式的字符串(&是分隔符)
const pattern = `${key}=([^&]*)`
const targetStr = `${key}=${val}`
/*
* 如果目标url中包含了key键, 我们需要将它替换成我们自己的val
* 不然就直接添加好了.
*/
if (url.match(pattern)) {
const tmp = new RegExp(`(${key}=)([^&]*)`, 'gi')
url = url.replace(tmp, targetStr)
} else {
const seperator = url.match('[?]') ? '&' : '?'
url = url + seperator + targetStr
}
}
if (location.hash) {
url += location.hash
}
return url
}
$.BootstrapTable = class extends $.BootstrapTable {
init () {
// 拥有addrbar选项并且其值为true的才会继续执行
if (this.options.addrbar) {
// 标志位, 初始加载后关闭
this.addrbarInit = true
const _prefix = this.options.addrPrefix || ''
// 优先级排序: 用户指定值最优先, 未指定时从地址栏获取, 未获取到时采用默认值
this.options.pageSize = this.options.pageSize || (
_GET(`${_prefix}limit`) ? parseInt(_GET(`${_prefix}limit`)) : $.BootstrapTable.DEFAULTS.pageSize
)
this.options.pageNumber = this.options.pageNumber || (
_GET(`${_prefix}page`) ? parseInt(_GET(`${_prefix}page`)) : $.BootstrapTable.DEFAULTS.pageNumber
)
this.options.sortOrder = this.options.sortOrder || (
_GET(`${_prefix}order`) ? _GET(`${_prefix}order`) : $.BootstrapTable.DEFAULTS.sortOrder
)
this.options.sortName = this.options.sortName || (
_GET(`${_prefix}sort`) ? _GET(`${_prefix}sort`) : 'id'
)
this.options.searchText = this.options.searchText || (
_GET(`${_prefix}search`) ? _GET(`${_prefix}search`) : $.BootstrapTable.DEFAULTS.searchText
)
const _onLoadSuccess = this.options.onLoadSuccess
this.options.onLoadSuccess = data => {
if (this.addrbarInit) {
this.addrbarInit = false
} else {
const params = {}
params[`${_prefix}page`] = this.options.pageNumber,
params[`${_prefix}limit`] = this.options.pageSize,
params[`${_prefix}order`] = this.options.sortOrder,
params[`${_prefix}sort`] = this.options.sortName,
params[`${_prefix}search`] = this.options.searchText
// h5提供的修改浏览器地址栏的方法
window.history.pushState({}, '', _buildUrl(params))
}
if (_onLoadSuccess) {
_onLoadSuccess.call(this, data)
}
}
}
super.init()
}
}
})(jQuery)

View File

@ -0,0 +1,78 @@
/**
* @author: Alec Fenichel
* @webSite: https://fenichelar.com
* @update: zhixin wen <wenzhixin2010@gmail.com>
*/
($ => {
const Utils = $.fn.bootstrapTable.utils
$.extend($.fn.bootstrapTable.defaults, {
autoRefresh: false,
autoRefreshInterval: 60,
autoRefreshSilent: true,
autoRefreshStatus: true,
autoRefreshFunction: null
})
$.extend($.fn.bootstrapTable.defaults.icons, {
autoRefresh: Utils.bootstrapVersion === 4 ? 'fa-clock' : 'glyphicon-time icon-time'
})
$.extend($.fn.bootstrapTable.locales, {
formatAutoRefresh () {
return 'Auto Refresh'
}
})
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
$.BootstrapTable = class extends $.BootstrapTable {
init (...args) {
super.init(...args)
if (this.options.autoRefresh && this.options.autoRefreshStatus) {
this.options.autoRefreshFunction = setInterval(() => {
this.refresh({silent: this.options.autoRefreshSilent})
}, this.options.autoRefreshInterval * 1000)
}
}
initToolbar (...args) {
super.initToolbar(...args)
if (this.options.autoRefresh) {
const $btnGroup = this.$toolbar.find('>.btn-group')
let $btnAutoRefresh = $btnGroup.find('.auto-refresh')
if (!$btnAutoRefresh.length) {
$btnAutoRefresh = $(`
<button class="auto-refresh btn${Utils.sprintf(' btn-%s', this.options.buttonsClass)}
${Utils.sprintf(' btn-%s', this.options.iconSize)}
${this.options.autoRefreshStatus ? 'active' : ''}"
type="button" title="${this.options.formatAutoRefresh()}">
<i class="${this.options.iconsPrefix} ${this.options.icons.autoRefresh}"></i>
</button>
`).appendTo($btnGroup)
$btnAutoRefresh.on('click', $.proxy(this.toggleAutoRefresh, this))
}
}
}
toggleAutoRefresh () {
if (this.options.autoRefresh) {
if (this.options.autoRefreshStatus) {
clearInterval(this.options.autoRefreshFunction)
this.$toolbar.find('>.btn-group').find('.auto-refresh').removeClass('active')
} else {
this.options.autoRefreshFunction = setInterval(() => {
this.refresh({silent: this.options.autoRefreshSilent})
}, this.options.autoRefreshInterval * 1000)
this.$toolbar.find('>.btn-group').find('.auto-refresh').addClass('active')
}
this.options.autoRefreshStatus = !this.options.autoRefreshStatus
}
}
}
})(jQuery)

View File

@ -0,0 +1,17 @@
{
"name": "Auto Refresh",
"version": "1.0.0",
"description": "Plugin to automatically refresh the table on an interval.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/auto-refresh",
"example": "#",
"plugins": [{
"name": "bootstrap-table-auto-refresh",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/auto-refresh"
}],
"author": {
"name": "fenichaler",
"image": "https://avatars.githubusercontent.com/u/3437075"
}
}

View File

@ -0,0 +1,401 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
($ => {
const UtilsCookie = {
cookieIds: {
sortOrder: 'bs.table.sortOrder',
sortName: 'bs.table.sortName',
pageNumber: 'bs.table.pageNumber',
pageList: 'bs.table.pageList',
columns: 'bs.table.columns',
searchText: 'bs.table.searchText',
filterControl: 'bs.table.filterControl',
filterBy: 'bs.table.filterBy'
},
getCurrentHeader (that) {
let header = that.$header
if (that.options.height) {
header = that.$tableHeader
}
return header
},
getCurrentSearchControls (that) {
let searchControls = 'select, input'
if (that.options.height) {
searchControls = 'table select, table input'
}
return searchControls
},
cookieEnabled () {
return !!(navigator.cookieEnabled)
},
inArrayCookiesEnabled (cookieName, cookiesEnabled) {
let index = -1
for (let i = 0; i < cookiesEnabled.length; i++) {
if (cookieName.toLowerCase() === cookiesEnabled[i].toLowerCase()) {
index = i
break
}
}
return index
},
setCookie (that, cookieName, cookieValue) {
if ((!that.options.cookie) || (!UtilsCookie.cookieEnabled()) || (that.options.cookieIdTable === '')) {
return
}
if (UtilsCookie.inArrayCookiesEnabled(cookieName, that.options.cookiesEnabled) === -1) {
return
}
cookieName = `${that.options.cookieIdTable}.${cookieName}`
switch (that.options.cookieStorage) {
case 'cookieStorage':
document.cookie = [
cookieName, '=', encodeURIComponent(cookieValue),
`; expires=${UtilsCookie.calculateExpiration(that.options.cookieExpire)}`,
that.options.cookiePath ? `; path=${that.options.cookiePath}` : '',
that.options.cookieDomain ? `; domain=${that.options.cookieDomain}` : '',
that.options.cookieSecure ? '; secure' : ''
].join('')
break
case 'localStorage':
localStorage.setItem(cookieName, cookieValue)
break
case 'sessionStorage':
sessionStorage.setItem(cookieName, cookieValue)
break
default:
return false
}
return true
},
getCookie (that, tableName, cookieName) {
if (!cookieName) {
return null
}
if (UtilsCookie.inArrayCookiesEnabled(cookieName, that.options.cookiesEnabled) === -1) {
return null
}
cookieName = `${tableName}.${cookieName}`
switch (that.options.cookieStorage) {
case 'cookieStorage':
const value = `; ${document.cookie}`
const parts = value.split(`; ${cookieName}=`)
return parts.length === 2 ? decodeURIComponent(parts.pop().split(';').shift()) : null
case 'localStorage':
return localStorage.getItem(cookieName)
case 'sessionStorage':
return sessionStorage.getItem(cookieName)
default:
return null
}
},
deleteCookie (that, tableName, cookieName) {
cookieName = `${tableName}.${cookieName}`
switch (that.options.cookieStorage) {
case 'cookieStorage':
document.cookie = [
encodeURIComponent(cookieName), '=',
'; expires=Thu, 01 Jan 1970 00:00:00 GMT',
that.options.cookiePath ? `; path=${that.options.cookiePath}` : '',
that.options.cookieDomain ? `; domain=${that.options.cookieDomain}` : ''
].join('')
break
case 'localStorage':
localStorage.removeItem(cookieName)
break
case 'sessionStorage':
sessionStorage.removeItem(cookieName)
break
default:
return false
}
return true
},
calculateExpiration (cookieExpire) {
const time = cookieExpire.replace(/[0-9]*/, '') // s,mi,h,d,m,y
cookieExpire = cookieExpire.replace(/[A-Za-z]{1,2}/, '') // number
switch (time.toLowerCase()) {
case 's':
cookieExpire = +cookieExpire
break
case 'mi':
cookieExpire *= 60
break
case 'h':
cookieExpire = cookieExpire * 60 * 60
break
case 'd':
cookieExpire = cookieExpire * 24 * 60 * 60
break
case 'm':
cookieExpire = cookieExpire * 30 * 24 * 60 * 60
break
case 'y':
cookieExpire = cookieExpire * 365 * 24 * 60 * 60
break
default:
cookieExpire = undefined
break
}
if (!cookieExpire) {
return ''
}
const d = new Date()
d.setTime(d.getTime() + cookieExpire * 1000)
return d.toGMTString()
},
initCookieFilters (bootstrapTable) {
setTimeout(() => {
const parsedCookieFilters = JSON.parse(UtilsCookie.getCookie(bootstrapTable, bootstrapTable.options.cookieIdTable, UtilsCookie.cookieIds.filterControl))
if (!bootstrapTable.options.filterControlValuesLoaded && parsedCookieFilters) {
const cachedFilters = {}
const header = UtilsCookie.getCurrentHeader(bootstrapTable)
const searchControls = UtilsCookie.getCurrentSearchControls(bootstrapTable)
const applyCookieFilters = (element, filteredCookies) => {
$(filteredCookies).each((i, cookie) => {
if (cookie.text !== '') {
$(element).val(cookie.text)
cachedFilters[cookie.field] = cookie.text
}
})
}
header.find(searchControls).each(function () {
const field = $(this).closest('[data-field]').data('field')
const filteredCookies = parsedCookieFilters.filter(cookie => cookie.field === field)
applyCookieFilters(this, filteredCookies)
})
bootstrapTable.initColumnSearch(cachedFilters)
bootstrapTable.options.filterControlValuesLoaded = true
bootstrapTable.initServer()
}
}, 250)
}
}
$.extend($.fn.bootstrapTable.defaults, {
cookie: false,
cookieExpire: '2h',
cookiePath: null,
cookieDomain: null,
cookieSecure: null,
cookieIdTable: '',
cookiesEnabled: [
'bs.table.sortOrder', 'bs.table.sortName',
'bs.table.pageNumber', 'bs.table.pageList',
'bs.table.columns', 'bs.table.searchText',
'bs.table.filterControl', 'bs.table.filterBy'
],
cookieStorage: 'cookieStorage', // localStorage, sessionStorage
// internal variable
filterControls: [],
filterControlValuesLoaded: false
})
$.fn.bootstrapTable.methods.push('getCookies')
$.fn.bootstrapTable.methods.push('deleteCookie')
$.extend($.fn.bootstrapTable.utils, {
setCookie: UtilsCookie.setCookie,
getCookie: UtilsCookie.getCookie
})
$.BootstrapTable = class extends $.BootstrapTable {
init () {
// FilterBy logic
const filterByCookie = JSON.parse(UtilsCookie.getCookie(this, this.options.cookieIdTable, UtilsCookie.cookieIds.filterBy))
this.filterColumns = filterByCookie ? filterByCookie : {}
// FilterControl logic
this.options.filterControls = []
this.options.filterControlValuesLoaded = false
this.options.cookiesEnabled = typeof this.options.cookiesEnabled === 'string' ?
this.options.cookiesEnabled.replace('[', '').replace(']', '')
.replace(/ /g, '').toLowerCase().split(',') :
this.options.cookiesEnabled
if (this.options.filterControl) {
const that = this
this.$el.on('column-search.bs.table', (e, field, text) => {
let isNewField = true
for (let i = 0; i < that.options.filterControls.length; i++) {
if (that.options.filterControls[i].field === field) {
that.options.filterControls[i].text = text
isNewField = false
break
}
}
if (isNewField) {
that.options.filterControls.push({
field,
text
})
}
UtilsCookie.setCookie(that, UtilsCookie.cookieIds.filterControl, JSON.stringify(that.options.filterControls))
}).on('created-controls.bs.table', UtilsCookie.initCookieFilters(that))
}
super.init()
}
initServer (...args) {
if (
this.options.cookie &&
this.options.filterControl &&
!this.options.filterControlValuesLoaded
) {
const cookie = JSON.parse(UtilsCookie.getCookie(this, this.options.cookieIdTable, UtilsCookie.cookieIds.filterControl))
if (cookie) {
return
}
}
super.initServer(...args)
}
initTable (...args) {
super.initTable(...args)
this.initCookie()
}
onSort (...args) {
super.onSort(...args)
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortOrder, this.options.sortOrder)
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortName, this.options.sortName)
}
onPageNumber (...args) {
super.onPageNumber(...args)
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
}
onPageListChange (...args) {
super.onPageListChange(...args)
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageList, this.options.pageSize)
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
}
onPagePre (...args) {
super.onPagePre(...args)
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
}
onPageNext (...args) {
super.onPageNext(...args)
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
}
toggleColumn (...args) {
super.toggleColumn(...args)
const visibleColumns = []
$.each(this.columns, (i, column) => {
if (column.visible) {
visibleColumns.push(column.field)
}
})
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.columns, JSON.stringify(visibleColumns))
}
selectPage (page) {
super.selectPage(page)
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, page)
}
onSearch (event) {
super.onSearch(event)
if ($(event.currentTarget).parent().hasClass('search')) {
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.searchText, this.searchText)
}
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
}
filterBy (...args) {
super.filterBy(...args)
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.filterBy, JSON.stringify(this.filterColumns))
}
initCookie () {
if (!this.options.cookie) {
return
}
if ((this.options.cookieIdTable === '') || (this.options.cookieExpire === '') || (!UtilsCookie.cookieEnabled())) {
console.error('Configuration error. Please review the cookieIdTable and the cookieExpire property. If the properties are correct, then this browser does not support cookies.')
this.options.cookie = false // Make sure that the cookie extension is disabled
return
}
const sortOrderCookie = UtilsCookie.getCookie(this, this.options.cookieIdTable, UtilsCookie.cookieIds.sortOrder)
const sortOrderNameCookie = UtilsCookie.getCookie(this, this.options.cookieIdTable, UtilsCookie.cookieIds.sortName)
const pageNumberCookie = UtilsCookie.getCookie(this, this.options.cookieIdTable, UtilsCookie.cookieIds.pageNumber)
const pageListCookie = UtilsCookie.getCookie(this, this.options.cookieIdTable, UtilsCookie.cookieIds.pageList)
const columnsCookie = JSON.parse(UtilsCookie.getCookie(this, this.options.cookieIdTable, UtilsCookie.cookieIds.columns))
const searchTextCookie = UtilsCookie.getCookie(this, this.options.cookieIdTable, UtilsCookie.cookieIds.searchText)
// sortOrder
this.options.sortOrder = sortOrderCookie ? sortOrderCookie : this.options.sortOrder
// sortName
this.options.sortName = sortOrderNameCookie ? sortOrderNameCookie : this.options.sortName
// pageNumber
this.options.pageNumber = pageNumberCookie ? +pageNumberCookie : this.options.pageNumber
// pageSize
this.options.pageSize = pageListCookie ? pageListCookie === this.options.formatAllRows() ? pageListCookie : +pageListCookie : this.options.pageSize
// searchText
this.options.searchText = searchTextCookie ? searchTextCookie : ''
if (columnsCookie) {
$.each(this.columns, (i, column) => {
column.visible = $.inArray(column.field, columnsCookie) !== -1
})
}
}
getCookies () {
const bootstrapTable = this
const cookies = {}
$.each(UtilsCookie.cookieIds, (key, value) => {
cookies[key] = UtilsCookie.getCookie(bootstrapTable, bootstrapTable.options.cookieIdTable, value)
if (key === 'columns') {
cookies[key] = JSON.parse(cookies[key])
}
})
return cookies
}
deleteCookie (cookieName) {
if ((cookieName === '') || (!UtilsCookie.cookieEnabled())) {
return
}
UtilsCookie.deleteCookie(this, this.options.cookieIdTable, UtilsCookie.cookieIds[cookieName])
}
}
})(jQuery)

View File

@ -0,0 +1,17 @@
{
"name": "Cookie",
"version": "1.2.1",
"description": "Plugin to use the cookie of the browser.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/cookie",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/cookie.html",
"plugins": [{
"name": "bootstrap-table-cookie",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/cookie"
}],
"author": {
"name": "djhvscf",
"image": "https://avatars1.githubusercontent.com/u/4496763"
}
}

View File

@ -0,0 +1,102 @@
/**
* @author Homer Glascock <HopGlascock@gmail.com>
* @version: v1.0.0
*/
!function ($) {
"use strict";
var calculateObjectValue = $.fn.bootstrapTable.utils.calculateObjectValue,
sprintf = $.fn.bootstrapTable.utils.sprintf;
var copytext = function (text) {
var textField = document.createElement('textarea');
$(textField).html(text);
document.body.appendChild(textField);
textField.select();
try {
document.execCommand('copy');
}
catch (e) {
console.log("Oops, unable to copy");
}
$(textField).remove();
};
$.extend($.fn.bootstrapTable.defaults, {
copyBtn: false,
copyWHiddenBtn: false,
copyDelemeter: ", "
});
$.fn.bootstrapTable.methods.push('copyColumnsToClipboard', 'copyColumnsToClipboardWithHidden');
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_initToolbar = BootstrapTable.prototype.initToolbar;
BootstrapTable.prototype.initToolbar = function () {
_initToolbar.apply(this, Array.prototype.slice.apply(arguments));
var that = this,
$btnGroup = this.$toolbar.find('>.btn-group');
if (this.options.clickToSelect || this.options.singleSelect) {
if (this.options.copyBtn) {
var copybtn = "<button class='btn btn-default' id='copyBtn'><span class='glyphicon glyphicon-copy icon-pencil'></span></button>";
$btnGroup.append(copybtn);
$btnGroup.find('#copyBtn').click(function () { that.copyColumnsToClipboard(); });
}
if (this.options.copyWHiddenBtn) {
var copyhiddenbtn = "<button class='btn btn-default' id='copyWHiddenBtn'><span class='badge'><span class='glyphicon glyphicon-copy icon-pencil'></span></span></button>";
$btnGroup.append(copyhiddenbtn);
$btnGroup.find('#copyWHiddenBtn').click(function () { that.copyColumnsToClipboardWithHidden(); });
}
}
};
BootstrapTable.prototype.copyColumnsToClipboard = function () {
var that = this,
ret = "",
delimet = this.options.copyDelemeter;
$.each(that.getSelections(), function (index, row) {
$.each(that.options.columns[0], function (indy, column) {
if (column.field !== "state" && column.field !== "RowNumber" && column.visible) {
if (row[column.field] !== null) {
ret += calculateObjectValue(column, that.header.formatters[indy], [row[column.field], row, index], row[column.field]);
}
ret += delimet;
}
});
ret += "\r\n";
});
copytext(ret);
};
BootstrapTable.prototype.copyColumnsToClipboardWithHidden = function () {
var that = this,
ret = "",
delimet = this.options.copyDelemeter;
$.each(that.getSelections(), function (index, row) {
$.each(that.options.columns[0], function (indy, column) {
if (column.field != "state" && column.field !== "RowNumber") {
if (row[column.field] !== null) {
ret += calculateObjectValue(column, that.header.formatters[indy], [row[column.field], row, index], row[column.field]);
}
ret += delimet;
}
});
ret += "\r\n";
});
copytext(ret);
};
}(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "Copy Rows",
"version": "1.0.0",
"description": "Allows pushing of selected column data to the clipboard.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/copy-rows",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/copy-rows.html",
"plugins": [{
"name": "copy-rows",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/copy-rows"
}],
"author": {
"name": "Homer Glascock",
"image": "https://avatars1.githubusercontent.com/u/5546710"
}
}

View File

@ -0,0 +1,32 @@
/**
* When using server-side processing, the default mode of operation for
* bootstrap-table is to simply throw away any data that currently exists in the
* table and make a request to the server to get the first page of data to
* display. This is fine for an empty table, but if you already have the first
* page of data displayed in the plain HTML, it is a waste of resources. As
* such, you can use data-defer-url instead of data-url to allow you to instruct
* bootstrap-table to not make that initial request, rather it will use the data
* already on the page.
*
* @author: Ruben Suarez
* @webSite: http://rubensa.eu.org
* @version: v1.0.0
*/
(function($) {
'use strict';
$.extend($.fn.bootstrapTable.defaults, {
deferUrl : undefined
});
var BootstrapTable = $.fn.bootstrapTable.Constructor, _init = BootstrapTable.prototype.init;
BootstrapTable.prototype.init = function() {
_init.apply(this, Array.prototype.slice.apply(arguments));
if (this.options.deferUrl) {
this.options.url = this.options.deferUrl;
}
}
})(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "DeferURL",
"version": "1.0.0",
"description": "Plugin to defer server side processing.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/defer-url",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/defer-url.html",
"plugins": [{
"name": "bootstrap-table-defer-url",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/defer-url"
}],
"author": {
"name": "rubensa",
"image": "https://avatars1.githubusercontent.com/u/1469340"
}
}

View File

@ -0,0 +1,149 @@
/**
* @author zhixin wen <wenzhixin2010@gmail.com>
* extensions: https://github.com/vitalets/x-editable
*/
($ => {
const Utils = $.fn.bootstrapTable.utils
$.extend($.fn.bootstrapTable.defaults, {
editable: true,
onEditableInit () {
return false
},
onEditableSave (field, row, oldValue, $el) {
return false
},
onEditableShown (field, row, $el, editable) {
return false
},
onEditableHidden (field, row, $el, reason) {
return false
}
})
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
'editable-init.bs.table': 'onEditableInit',
'editable-save.bs.table': 'onEditableSave',
'editable-shown.bs.table': 'onEditableShown',
'editable-hidden.bs.table': 'onEditableHidden'
})
$.BootstrapTable = class extends $.BootstrapTable {
initTable () {
super.initTable()
if (!this.options.editable) {
return
}
$.each(this.columns, (i, column) => {
if (!column.editable) {
return
}
const editableOptions = {}
const editableDataMarkup = []
const editableDataPrefix = 'editable-'
const processDataOptions = (key, value) => {
// Replace camel case with dashes.
const dashKey = key.replace(/([A-Z])/g, $1 => `-${$1.toLowerCase()}`)
if (dashKey.indexOf(editableDataPrefix) === 0) {
editableOptions[dashKey.replace(editableDataPrefix, 'data-')] = value
}
}
$.each(this.options, processDataOptions)
column.formatter = column.formatter || (value => value)
column._formatter = column._formatter ? column._formatter : column.formatter
column.formatter = (value, row, index) => {
const result = Utils.calculateObjectValue(column,
column._formatter, [value, row, index], value)
$.each(column, processDataOptions)
$.each(editableOptions, (key, value) => {
editableDataMarkup.push(` ${key}="${value}"`)
})
let _dont_edit_formatter = false
if (column.editable.hasOwnProperty('noeditFormatter')) {
_dont_edit_formatter = column.editable.noeditFormatter(value, row, index)
}
if (_dont_edit_formatter === false) {
return `<a href="javascript:void(0)"
data-name="${column.field}"
data-pk="${row[this.options.idField]}"
data-value="${result}"
${editableDataMarkup.join('')}></a>`
}
return _dont_edit_formatter
}
})
}
initBody (fixedScroll) {
super.initBody(fixedScroll)
if (!this.options.editable) {
return
}
$.each(this.columns, (i, column) => {
if (!column.editable) {
return
}
const data = this.getData()
const $field = this.$body.find(`a[data-name="${column.field}"]`)
$field.each((i, element) => {
const $element = $(element)
const $tr = $element.closest('tr')
const index = $tr.data('index')
const row = data[index]
const editableOpts = Utils.calculateObjectValue(column,
column.editable, [index, row, $element], {})
$element.editable(editableOpts)
})
$field.off('save').on('save', ({currentTarget}, {submitValue}) => {
const $this = $(currentTarget)
const data = this.getData()
const index = $this.parents('tr[data-index]').data('index')
const row = data[index]
const oldValue = row[column.field]
$this.data('value', submitValue)
row[column.field] = submitValue
this.trigger('editable-save', column.field, row, oldValue, $this)
this.resetFooter()
})
$field.off('shown').on('shown', ({currentTarget}, editable) => {
const $this = $(currentTarget)
const data = this.getData()
const index = $this.parents('tr[data-index]').data('index')
const row = data[index]
this.trigger('editable-shown', column.field, row, $this, editable)
})
$field.off('hidden').on('hidden', ({currentTarget}, reason) => {
const $this = $(currentTarget)
const data = this.getData()
const index = $this.parents('tr[data-index]').data('index')
const row = data[index]
this.trigger('editable-hidden', column.field, row, $this, reason)
})
})
this.trigger('editable-init')
}
}
})(jQuery)

View File

@ -0,0 +1,17 @@
{
"name": "Table Editable",
"version": "1.1.0",
"description": "Use the x-editable to in-place editing your table.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/editable",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/editable.html",
"plugins": [{
"name": "x-editable",
"url": "https://github.com/vitalets/x-editable"
}],
"author": {
"name": "wenzhixin",
"image": "https://avatars1.githubusercontent.com/u/2117018"
}
}

View File

@ -0,0 +1,225 @@
/**
* @author zhixin wen <wenzhixin2010@gmail.com>
* extensions: https://github.com/hhurz/tableExport.jquery.plugin
*/
($ => {
const Utils = $.fn.bootstrapTable.utils
const bootstrap = {
3: {
icons: {
export: 'glyphicon-export icon-share'
},
html: {
dropmenu: '<ul class="dropdown-menu" role="menu"></ul>',
dropitem: '<li role="menuitem" data-type="%s"><a href="javascript:">%s</a></li>'
}
},
4: {
icons: {
export: 'fa-download'
},
html: {
dropmenu: '<div class="dropdown-menu dropdown-menu-right"></div>',
dropitem: '<a class="dropdown-item" data-type="%s" href="javascript:">%s</a>'
}
}
}[Utils.bootstrapVersion]
const TYPE_NAME = {
json: 'JSON',
xml: 'XML',
png: 'PNG',
csv: 'CSV',
txt: 'TXT',
sql: 'SQL',
doc: 'MS-Word',
excel: 'MS-Excel',
xlsx: 'MS-Excel (OpenXML)',
powerpoint: 'MS-Powerpoint',
pdf: 'PDF'
}
$.extend($.fn.bootstrapTable.defaults, {
showExport: false,
exportDataType: 'basic', // basic, all, selected
exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'],
exportOptions: {},
exportFooter: false
})
$.extend($.fn.bootstrapTable.defaults.icons, {
export: bootstrap.icons.export
})
$.extend($.fn.bootstrapTable.locales, {
formatExport () {
return 'Export data'
}
})
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
$.fn.bootstrapTable.methods.push('exportTable')
$.BootstrapTable = class extends $.BootstrapTable {
initToolbar () {
const o = this.options
this.showToolbar = this.showToolbar || o.showExport
super.initToolbar()
if (!this.options.showExport) {
return
}
const $btnGroup = this.$toolbar.find('>.btn-group')
this.$export = $btnGroup.find('div.export')
if (this.$export.length) {
this.updateExportButton()
return
}
this.$export = $(`
<div class="export btn-group">
<button class="btn btn-${o.buttonsClass} btn-${o.iconSize} dropdown-toggle"
aria-label="export type"
title="${o.formatExport()}"
data-toggle="dropdown"
type="button">
<i class="${o.iconsPrefix} ${o.icons.export}"></i>
<span class="caret"></span>
</button>
${bootstrap.html.dropmenu}
</div>
`).appendTo($btnGroup)
this.updateExportButton()
const $menu = this.$export.find('.dropdown-menu')
let exportTypes = o.exportTypes
if (typeof exportTypes === 'string') {
const types = exportTypes.slice(1, -1).replace(/ /g, '').split(',')
exportTypes = types.map(t => t.slice(1, -1))
}
for (const type of exportTypes) {
if (TYPE_NAME.hasOwnProperty(type)) {
$menu.append(Utils.sprintf(bootstrap.html.dropitem, type, TYPE_NAME[type]))
}
}
$menu.find('>li, >a').click(({currentTarget}) => {
const type = $(currentTarget).data('type')
const exportOptions = {
type,
escape: false
}
this.exportTable(exportOptions)
})
}
exportTable (options) {
const o = this.options
const stateField = this.header.stateField
const isCardView = o.cardView
const doExport = callback => {
if (stateField) {
this.hideColumn(stateField)
}
if (isCardView) {
this.toggleView()
}
const data = this.getData()
if (o.exportFooter) {
const $footerRow = this.$tableFooter.find('tr').first()
const footerData = {}
const footerHtml = []
$.each($footerRow.children(), (index, footerCell) => {
const footerCellHtml = $(footerCell).children('.th-inner').first().html()
footerData[this.columns[index].field] = footerCellHtml === '&nbsp;' ? null : footerCellHtml
// grab footer cell text into cell index-based array
footerHtml.push(footerCellHtml)
})
this.append(footerData)
const $lastTableRow = this.$body.children().last()
$.each($lastTableRow.children(), (index, lastTableRowCell) => {
$(lastTableRowCell).html(footerHtml[index])
})
}
this.$el.tableExport($.extend({
onAfterSaveToFile: () => {
if (o.exportFooter) {
this.load(data)
}
if (stateField) {
this.showColumn(stateField)
}
if (isCardView) {
this.toggleView()
}
callback()
}
}, o.exportOptions, options))
}
if (o.exportDataType === 'all' && o.pagination) {
const eventName = o.sidePagination === 'server'
? 'post-body.bs.table' : 'page-change.bs.table'
this.$el.one(eventName, () => {
doExport(() => {
this.togglePagination()
})
})
this.togglePagination()
} else if (o.exportDataType === 'selected') {
let data = this.getData()
let selectedData = this.getSelections()
if (!selectedData.length) {
return
}
if (o.sidePagination === 'server') {
data = {
total: o.totalRows,
[this.options.dataField]: data
}
selectedData = {
total: selectedData.length,
[this.options.dataField]: selectedData
}
}
this.load(selectedData)
doExport(() => {
this.load(data)
})
} else {
doExport()
}
}
updateSelected () {
super.updateSelected()
this.updateExportButton()
}
updateExportButton () {
if (this.options.exportDataType === 'selected') {
this.$export.find('> button')
.prop('disabled', !this.getSelections().length)
}
}
}
})(jQuery)

View File

@ -0,0 +1,17 @@
{
"name": "Table Export",
"version": "1.1.0",
"description": "Export your table data to JSON, XML, CSV, TXT, SQL, Word, Excel, PNG, PDF.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/export",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/export.html",
"plugins": [{
"name": "tableExport.jquery.plugin",
"url": "https://github.com/hhurz/tableExport.jquery.plugin"
}],
"author": {
"name": "wenzhixin",
"image": "https://avatars1.githubusercontent.com/u/2117018"
}
}

View File

@ -0,0 +1,13 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @version: v2.1.1
*/
.no-filter-control {
height: 34px;
}
.filter-control {
margin: 0 2px 2px 2px;
}

View File

@ -0,0 +1,917 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @version: v2.2.0
*/
($ => {
const Utils = $.fn.bootstrapTable.utils
const UtilsFilterControl = {
getOptionsFromSelectControl (selectControl) {
return selectControl.get(selectControl.length - 1).options
},
hideUnusedSelectOptions (selectControl, uniqueValues) {
const options = UtilsFilterControl.getOptionsFromSelectControl(
selectControl
)
for (let i = 0; i < options.length; i++) {
if (options[i].value !== '') {
if (!uniqueValues.hasOwnProperty(options[i].value)) {
selectControl
.find(Utils.sprintf('option[value=\'%s\']', options[i].value))
.hide()
} else {
selectControl
.find(Utils.sprintf('option[value=\'%s\']', options[i].value))
.show()
}
}
}
},
addOptionToSelectControl (selectControl, _value, text) {
const value = $.trim(_value)
const $selectControl = $(selectControl.get(selectControl.length - 1))
if (
!UtilsFilterControl.existOptionInSelectControl(selectControl, value)
) {
$selectControl.append(
$('<option></option>')
.attr('value', value)
.text(
$('<div />')
.html(text)
.text()
)
)
}
},
sortSelectControl (selectControl) {
const $selectControl = $(selectControl.get(selectControl.length - 1))
const $opts = $selectControl.find('option:gt(0)')
$opts.sort((a, b) => {
let aa = $(a).text().toLowerCase()
let bb = $(b).text().toLowerCase()
if ($.isNumeric(a) && $.isNumeric(b)) {
// Convert numerical values from string to float.
aa = parseFloat(aa)
bb = parseFloat(bb)
}
return aa > bb ? 1 : aa < bb ? -1 : 0
})
$selectControl.find('option:gt(0)').remove()
$selectControl.append($opts)
},
existOptionInSelectControl (selectControl, value) {
const options = UtilsFilterControl.getOptionsFromSelectControl(
selectControl
)
for (let i = 0; i < options.length; i++) {
if (options[i].value === value.toString()) {
// The value is not valid to add
return true
}
}
// If we get here, the value is valid to add
return false
},
fixHeaderCSS ({ $tableHeader }) {
$tableHeader.css('height', '77px')
},
getCurrentHeader ({ $header, options, $tableHeader }) {
let header = $header
if (options.height) {
header = $tableHeader
}
return header
},
getCurrentSearchControls ({ options }) {
let searchControls = 'select, input'
if (options.height) {
searchControls = 'table select, table input'
}
return searchControls
},
getCursorPosition (el) {
if (Utils.isIEBrowser()) {
if ($(el).is('input[type=text]')) {
let pos = 0
if ('selectionStart' in el) {
pos = el.selectionStart
} else if ('selection' in document) {
el.focus()
const Sel = document.selection.createRange()
const SelLength = document.selection.createRange().text.length
Sel.moveStart('character', -el.value.length)
pos = Sel.text.length - SelLength
}
return pos
}
return -1
}
return -1
},
setCursorPosition (el) {
$(el).val(el.value)
},
copyValues (that) {
const header = UtilsFilterControl.getCurrentHeader(that)
const searchControls = UtilsFilterControl.getCurrentSearchControls(that)
that.options.valuesFilterControl = []
header.find(searchControls).each(function () {
that.options.valuesFilterControl.push({
field: $(this)
.closest('[data-field]')
.data('field'),
value: $(this).val(),
position: UtilsFilterControl.getCursorPosition($(this).get(0)),
hasFocus: $(this).is(':focus')
})
})
},
setValues (that) {
let field = null
let result = []
const header = UtilsFilterControl.getCurrentHeader(that)
const searchControls = UtilsFilterControl.getCurrentSearchControls(that)
if (that.options.valuesFilterControl.length > 0) {
// Callback to apply after settings fields values
let fieldToFocusCallback = null
header.find(searchControls).each(function (index, ele) {
field = $(this)
.closest('[data-field]')
.data('field')
result = that.options.valuesFilterControl.filter(valueObj => valueObj.field === field)
if (result.length > 0) {
$(this).val(result[0].value)
if (result[0].hasFocus) {
// set callback if the field had the focus.
fieldToFocusCallback = ((fieldToFocus, carretPosition) => {
// Closure here to capture the field and cursor position
const closedCallback = () => {
fieldToFocus.focus()
UtilsFilterControl.setCursorPosition(fieldToFocus, carretPosition)
}
return closedCallback
})($(this).get(0), result[0].position)
}
}
})
// Callback call.
if (fieldToFocusCallback !== null) {
fieldToFocusCallback()
}
}
},
collectBootstrapCookies () {
const cookies = []
const foundCookies = document.cookie.match(/(?:bs.table.)(\w*)/g)
if (foundCookies) {
$.each(foundCookies, (i, _cookie) => {
let cookie = _cookie
if (/./.test(cookie)) {
cookie = cookie.split('.').pop()
}
if ($.inArray(cookie, cookies) === -1) {
cookies.push(cookie)
}
})
return cookies
}
},
escapeID (id) {
return String(id).replace(/(:|\.|\[|\]|,)/g, '\\$1')
},
isColumnSearchableViaSelect ({ filterControl, searchable }) {
return filterControl &&
filterControl.toLowerCase() === 'select' &&
searchable
},
isFilterDataNotGiven ({ filterData }) {
return filterData === undefined ||
filterData.toLowerCase() === 'column'
},
hasSelectControlElement (selectControl) {
return selectControl && selectControl.length > 0
},
initFilterSelectControls (that) {
const data = that.data
const itemsPerPage = that.pageTo < that.options.data.length ? that.options.data.length : that.pageTo
const z = that.options.pagination
? that.options.sidePagination === 'server'
? that.pageTo
: that.options.totalRows
: that.pageTo
$.each(that.header.fields, (j, field) => {
const column = that.columns[that.fieldsColumnsIndex[field]]
const selectControl = $(`.bootstrap-table-filter-control-${UtilsFilterControl.escapeID(column.field)}`)
if (
UtilsFilterControl.isColumnSearchableViaSelect(column) &&
UtilsFilterControl.isFilterDataNotGiven(column) &&
UtilsFilterControl.hasSelectControlElement(selectControl)
) {
if (selectControl.get(selectControl.length - 1).options.length === 0) {
// Added the default option
UtilsFilterControl.addOptionToSelectControl(selectControl, '', column.filterControlPlaceholder)
}
const uniqueValues = {}
for (let i = 0; i < z; i++) {
// Added a new value
const fieldValue = data[i][field]
const formattedValue = Utils.calculateObjectValue(that.header, that.header.formatters[j], [fieldValue, data[i], i], fieldValue)
uniqueValues[formattedValue] = fieldValue
}
// eslint-disable-next-line guard-for-in
for (const key in uniqueValues) {
UtilsFilterControl.addOptionToSelectControl(selectControl, uniqueValues[key], key)
}
UtilsFilterControl.sortSelectControl(selectControl)
if (that.options.hideUnusedSelectOptions) {
UtilsFilterControl.hideUnusedSelectOptions(selectControl, uniqueValues)
}
}
})
that.trigger('created-controls')
},
getFilterDataMethod (objFilterDataMethod, searchTerm) {
const keys = Object.keys(objFilterDataMethod)
for (let i = 0; i < keys.length; i++) {
if (keys[i] === searchTerm) {
return objFilterDataMethod[searchTerm]
}
}
return null
},
createControls (that, header) {
let addedFilterControl = false
let isVisible
let html
$.each(that.columns, (i, column) => {
isVisible = 'hidden'
html = []
if (!column.visible) {
return
}
if (!column.filterControl) {
html.push('<div class="no-filter-control"></div>')
} else {
html.push('<div class="filter-control">')
const nameControl = column.filterControl.toLowerCase()
if (column.searchable && that.options.filterTemplate[nameControl]) {
addedFilterControl = true
isVisible = 'visible'
html.push(
that.options.filterTemplate[nameControl](
that,
column.field,
isVisible,
column.filterControlPlaceholder
? column.filterControlPlaceholder
: '',
`filter-control-${i}`
)
)
}
}
$.each(header.children().children(), (i, tr) => {
const $tr = $(tr)
if ($tr.data('field') === column.field) {
$tr.find('.fht-cell').append(html.join(''))
return false
}
})
if (
column.filterData !== undefined &&
column.filterData.toLowerCase() !== 'column'
) {
const filterDataType = UtilsFilterControl.getFilterDataMethod(
/* eslint-disable no-use-before-define */
filterDataMethods,
column.filterData.substring(0, column.filterData.indexOf(':'))
)
let filterDataSource
let selectControl
if (filterDataType !== null) {
filterDataSource = column.filterData.substring(
column.filterData.indexOf(':') + 1,
column.filterData.length
)
selectControl = $(
`.bootstrap-table-filter-control-${UtilsFilterControl.escapeID(column.field)}`
)
UtilsFilterControl.addOptionToSelectControl(selectControl, '', column.filterControlPlaceholder)
filterDataType(filterDataSource, selectControl)
} else {
throw new SyntaxError(
'Error. You should use any of these allowed filter data methods: var, json, url.' +
' Use like this: var: {key: "value"}'
)
}
let variableValues
let key
// eslint-disable-next-line default-case
switch (filterDataType) {
case 'url':
$.ajax({
url: filterDataSource,
dataType: 'json',
success (data) {
// eslint-disable-next-line guard-for-in
for (const key in data) {
UtilsFilterControl.addOptionToSelectControl(selectControl, key, data[key])
}
UtilsFilterControl.sortSelectControl(selectControl)
}
})
break
case 'var':
variableValues = window[filterDataSource]
// eslint-disable-next-line guard-for-in
for (key in variableValues) {
UtilsFilterControl.addOptionToSelectControl(selectControl, key, variableValues[key])
}
UtilsFilterControl.sortSelectControl(selectControl)
break
case 'jso':
variableValues = JSON.parse(filterDataSource)
// eslint-disable-next-line guard-for-in
for (key in variableValues) {
UtilsFilterControl.addOptionToSelectControl(selectControl, key, variableValues[key])
}
UtilsFilterControl.sortSelectControl(selectControl)
break
}
}
})
if (addedFilterControl) {
header.off('keyup', 'input').on('keyup', 'input', (event, obj) => {
// Simulate enter key action from clear button
event.keyCode = obj ? obj.keyCode : event.keyCode
if (that.options.searchOnEnterKey && event.keyCode !== 13) {
return
}
if ($.inArray(event.keyCode, [37, 38, 39, 40]) > -1) {
return
}
const $currentTarget = $(event.currentTarget)
if ($currentTarget.is(':checkbox') || $currentTarget.is(':radio')) {
return
}
clearTimeout(event.currentTarget.timeoutId || 0)
event.currentTarget.timeoutId = setTimeout(() => {
that.onColumnSearch(event)
}, that.options.searchTimeOut)
})
header.off('change', 'select').on('change', 'select', event => {
if (that.options.searchOnEnterKey && event.keyCode !== 13) {
return
}
if ($.inArray(event.keyCode, [37, 38, 39, 40]) > -1) {
return
}
clearTimeout(event.currentTarget.timeoutId || 0)
event.currentTarget.timeoutId = setTimeout(() => {
that.onColumnSearch(event)
}, that.options.searchTimeOut)
})
header.off('mouseup', 'input').on('mouseup', 'input', function (event) {
const $input = $(this)
const oldValue = $input.val()
if (oldValue === '') {
return
}
setTimeout(() => {
const newValue = $input.val()
if (newValue === '') {
clearTimeout(event.currentTarget.timeoutId || 0)
event.currentTarget.timeoutId = setTimeout(() => {
that.onColumnSearch(event)
}, that.options.searchTimeOut)
}
}, 1)
})
if (header.find('.date-filter-control').length > 0) {
$.each(that.columns, (i, { filterControl, field, filterDatepickerOptions }) => {
if (
filterControl !== undefined &&
filterControl.toLowerCase() === 'datepicker'
) {
header
.find(
`.date-filter-control.bootstrap-table-filter-control-${field}`
)
.datepicker(filterDatepickerOptions)
.on('changeDate', ({ currentTarget }) => {
$(currentTarget).val(
currentTarget.value
)
// Fired the keyup event
$(currentTarget).keyup()
})
}
})
}
} else {
header.find('.filterControl').hide()
}
},
getDirectionOfSelectOptions (_alignment) {
const alignment = _alignment === undefined ? 'left' : _alignment.toLowerCase()
switch (alignment) {
case 'left':
return 'ltr'
case 'right':
return 'rtl'
case 'auto':
return 'auto'
default:
return 'ltr'
}
}
}
const filterDataMethods = {
var (filterDataSource, selectControl) {
const variableValues = window[filterDataSource]
// eslint-disable-next-line guard-for-in
for (const key in variableValues) {
UtilsFilterControl.addOptionToSelectControl(selectControl, key, variableValues[key])
}
UtilsFilterControl.sortSelectControl(selectControl)
},
url (filterDataSource, selectControl) {
$.ajax({
url: filterDataSource,
dataType: 'json',
success (data) {
// eslint-disable-next-line guard-for-in
for (const key in data) {
UtilsFilterControl.addOptionToSelectControl(selectControl, key, data[key])
}
UtilsFilterControl.sortSelectControl(selectControl)
}
})
},
json (filterDataSource, selectControl) {
const variableValues = JSON.parse(filterDataSource)
// eslint-disable-next-line guard-for-in
for (const key in variableValues) {
UtilsFilterControl.addOptionToSelectControl(selectControl, key, variableValues[key])
}
UtilsFilterControl.sortSelectControl(selectControl)
}
}
const bootstrap = {
3: {
icons: {
clear: 'glyphicon-trash icon-clear'
}
},
4: {
icons: {
clear: 'fa-trash icon-clear'
}
}
}[Utils.bootstrapVersion]
$.extend($.fn.bootstrapTable.defaults, {
filterControl: false,
onColumnSearch (field, text) {
return false
},
onCreatedControls () {
return true
},
filterShowClear: false,
alignmentSelectControlOptions: undefined,
filterTemplate: {
input (that, field, isVisible, placeholder) {
return Utils.sprintf(
'<input type="text" class="form-control bootstrap-table-filter-control-%s" style="width: 100%; visibility: %s" placeholder="%s">',
field,
isVisible,
placeholder
)
},
select ({ options }, field, isVisible) {
return Utils.sprintf(
'<select class="form-control bootstrap-table-filter-control-%s" style="width: 100%; visibility: %s" dir="%s"></select>',
field,
isVisible,
UtilsFilterControl.getDirectionOfSelectOptions(
options.alignmentSelectControlOptions
)
)
},
datepicker (that, field, isVisible) {
return Utils.sprintf(
'<input type="text" class="form-control date-filter-control bootstrap-table-filter-control-%s" style="width: 100%; visibility: %s">',
field,
isVisible
)
}
},
disableControlWhenSearch: false,
searchOnEnterKey: false,
// internal variables
valuesFilterControl: []
})
$.extend($.fn.bootstrapTable.columnDefaults, {
filterControl: undefined,
filterData: undefined,
filterDatepickerOptions: undefined,
filterStrictSearch: false,
filterStartsWithSearch: false,
filterControlPlaceholder: ''
})
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
'column-search.bs.table': 'onColumnSearch',
'created-controls.bs.table': 'onCreatedControls'
})
$.extend($.fn.bootstrapTable.defaults.icons, {
clear: bootstrap.icons.clear
})
$.extend($.fn.bootstrapTable.locales, {
formatClearFilters () {
return 'Clear Filters'
}
})
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
$.fn.bootstrapTable.methods.push('triggerSearch')
$.fn.bootstrapTable.methods.push('clearFilterControl')
$.BootstrapTable = class extends $.BootstrapTable {
init () {
// Make sure that the filterControl option is set
if (this.options.filterControl) {
const that = this
// Make sure that the internal variables are set correctly
this.options.valuesFilterControl = []
this.$el
.on('reset-view.bs.table', () => {
// Create controls on $tableHeader if the height is set
if (!that.options.height) {
return
}
// Avoid recreate the controls
if (
that.$tableHeader.find('select').length > 0 ||
that.$tableHeader.find('input').length > 0
) {
return
}
UtilsFilterControl.createControls(that, that.$tableHeader)
})
.on('post-header.bs.table', () => {
UtilsFilterControl.setValues(that)
})
.on('post-body.bs.table', () => {
if (that.options.height) {
UtilsFilterControl.fixHeaderCSS(that)
}
})
.on('column-switch.bs.table', () => {
UtilsFilterControl.setValues(that)
})
.on('load-success.bs.table', () => {
that.EnableControls(true)
})
.on('load-error.bs.table', () => {
that.EnableControls(true)
})
}
super.init()
}
initToolbar () {
this.showToolbar =
this.showToolbar ||
(this.options.filterControl && this.options.filterShowClear)
super.initToolbar()
if (this.options.filterControl && this.options.filterShowClear) {
const $btnGroup = this.$toolbar.find('>.btn-group')
let $btnClear = $btnGroup.find('.filter-show-clear')
if (!$btnClear.length) {
$btnClear = $(
[
Utils.sprintf(
'<button class="btn btn-%s filter-show-clear" ',
this.options.buttonsClass
),
Utils.sprintf(
'type="button" title="%s">',
this.options.formatClearFilters()
),
Utils.sprintf(
'<i class="%s %s"></i> ',
this.options.iconsPrefix,
this.options.icons.clear
),
'</button>'
].join('')
).appendTo($btnGroup)
$btnClear
.off('click')
.on('click', $.proxy(this.clearFilterControl, this))
}
}
}
initHeader () {
super.initHeader()
if (!this.options.filterControl) {
return
}
UtilsFilterControl.createControls(this, this.$header)
}
initBody () {
super.initBody()
UtilsFilterControl.initFilterSelectControls(this)
}
initSearch () {
const that = this
const fp = $.isEmptyObject(that.filterColumnsPartial)
? null
: that.filterColumnsPartial
if (fp === null || Object.keys(fp).length <= 1) {
super.initSearch()
}
if (this.options.sidePagination === 'server') {
return
}
if (fp === null) {
return
}
// Check partial column filter
that.data = fp
? that.options.data.filter((item, i) => {
const itemIsExpected = []
Object.keys(item).forEach((key, index) => {
const thisColumn = that.columns[that.fieldsColumnsIndex[key]]
const fval = (fp[key] || '').toLowerCase()
let value = item[key]
if (fval === '') {
itemIsExpected.push(true)
} else {
// Fix #142: search use formated data
if (thisColumn && thisColumn.searchFormatter) {
value = $.fn.bootstrapTable.utils.calculateObjectValue(
that.header,
that.header.formatters[$.inArray(key, that.header.fields)],
[value, item, i],
value
)
}
if ($.inArray(key, that.header.fields) !== -1) {
if (typeof value === 'string' || typeof value === 'number') {
if (thisColumn.filterStrictSearch) {
if (value.toString().toLowerCase() === fval.toString().toLowerCase()) {
itemIsExpected.push(true)
} else {
itemIsExpected.push(false)
}
} else if (thisColumn.filterStartsWithSearch) {
if ((`${value}`).toLowerCase().indexOf(fval) === 0) {
itemIsExpected.push(true)
} else {
itemIsExpected.push(false)
}
} else {
if ((`${value}`).toLowerCase().includes(fval)) {
itemIsExpected.push(true)
} else {
itemIsExpected.push(false)
}
}
}
}
}
})
return !itemIsExpected.includes(false)
})
: that.data
}
initColumnSearch (filterColumnsDefaults) {
UtilsFilterControl.copyValues(this)
if (filterColumnsDefaults) {
this.filterColumnsPartial = filterColumnsDefaults
this.updatePagination()
// eslint-disable-next-line guard-for-in
for (const filter in filterColumnsDefaults) {
this.trigger('column-search', filter, filterColumnsDefaults[filter])
}
}
}
onColumnSearch (event) {
if ($.inArray(event.keyCode, [37, 38, 39, 40]) > -1) {
return
}
UtilsFilterControl.copyValues(this)
const text = $.trim($(event.currentTarget).val())
const $field = $(event.currentTarget)
.closest('[data-field]')
.data('field')
if ($.isEmptyObject(this.filterColumnsPartial)) {
this.filterColumnsPartial = {}
}
if (text) {
this.filterColumnsPartial[$field] = text
} else {
delete this.filterColumnsPartial[$field]
}
// if the searchText is the same as the previously selected column value,
// bootstrapTable will not try searching again (even though the selected column
// may be different from the previous search). As a work around
// we're manually appending some text to bootrap's searchText field
// to guarantee that it will perform a search again when we call this.onSearch(event)
this.searchText += 'randomText'
this.options.pageNumber = 1
this.EnableControls(false)
this.onSearch(event)
this.trigger('column-search', $field, text)
}
clearFilterControl () {
if (this.options.filterControl && this.options.filterShowClear) {
const that = this
const cookies = UtilsFilterControl.collectBootstrapCookies()
const header = UtilsFilterControl.getCurrentHeader(that)
const table = header.closest('table')
const controls = header.find(UtilsFilterControl.getCurrentSearchControls(that))
const search = that.$toolbar.find('.search input')
let hasValues = false
let timeoutId = 0
$.each(that.options.valuesFilterControl, (i, item) => {
hasValues = hasValues ? true : item.value !== ''
item.value = ''
})
UtilsFilterControl.setValues(that)
// clear cookies once the filters are clean
clearTimeout(timeoutId)
timeoutId = setTimeout(() => {
if (cookies && cookies.length > 0) {
$.each(cookies, (i, item) => {
if (that.deleteCookie !== undefined) {
that.deleteCookie(item)
}
})
}
}, that.options.searchTimeOut)
// If there is not any value in the controls exit this method
if (!hasValues) {
return
}
// Clear each type of filter if it exists.
// Requires the body to reload each time a type of filter is found because we never know
// which ones are going to be present.
if (controls.length > 0) {
this.filterColumnsPartial = {}
$(controls[0]).trigger(
controls[0].tagName === 'INPUT' ? 'keyup' : 'change', { keyCode: 13 }
)
} else {
return
}
if (search.length > 0) {
that.resetSearch()
}
// use the default sort order if it exists. do nothing if it does not
if (
that.options.sortName !== table.data('sortName') ||
that.options.sortOrder !== table.data('sortOrder')
) {
const sorter = header.find(
Utils.sprintf(
'[data-field="%s"]',
$(controls[0])
.closest('table')
.data('sortName')
)
)
if (sorter.length > 0) {
that.onSort({ type: 'keypress', currentTarget: sorter })
$(sorter)
.find('.sortable')
.trigger('click')
}
}
}
}
triggerSearch () {
const header = UtilsFilterControl.getCurrentHeader(this)
const searchControls = UtilsFilterControl.getCurrentSearchControls(this)
header.find(searchControls).each(function () {
const el = $(this)
if (el.is('select')) {
el.change()
} else {
el.keyup()
}
})
}
EnableControls (enable) {
if (
this.options.disableControlWhenSearch &&
this.options.sidePagination === 'server'
) {
const header = UtilsFilterControl.getCurrentHeader(this)
const searchControls = UtilsFilterControl.getCurrentSearchControls(this)
if (!enable) {
header.find(searchControls).prop('disabled', 'disabled')
} else {
header.find(searchControls).removeProp('disabled')
}
}
}
}
})(jQuery)

View File

@ -0,0 +1,17 @@
{
"name": "Filter Control",
"version": "2.1.0",
"description": "Plugin to add input/select element on the top of the columns in order to filter the data.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/filter-control",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/filter-control.html",
"plugins": [{
"name": "bootstrap-table-filter-control",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/filter-control"
}],
"author": {
"name": "djhvscf",
"image": "https://avatars1.githubusercontent.com/u/4496763"
}
}

View File

@ -0,0 +1,27 @@
.fixed-table-header-columns,
.fixed-table-body-columns {
position: absolute;
background-color: #fff;
box-sizing: border-box;
overflow: hidden;
z-index: 1;
}
.fixed-table-header-columns {
z-index: 2;
}
.fixed-table-header-columns .table,
.fixed-table-body-columns .table {
border-right: 1px solid #ddd;
}
.fixed-table-header-columns .table.table-no-bordered,
.fixed-table-body-columns .table.table-no-bordered {
border-right: 1px solid transparent;
}
.fixed-table-body-columns table {
position: absolute;
animation: none;
}

View File

@ -0,0 +1,115 @@
/**
* @author zhixin wen <wenzhixin2010@gmail.com>
*/
($ => {
$.extend($.fn.bootstrapTable.defaults, {
fixedColumns: false,
fixedNumber: 1
})
$.BootstrapTable = class extends $.BootstrapTable {
fitHeader (...args) {
super.fitHeader(...args)
if (!this.options.fixedColumns) {
return
}
if (this.$el.is(':hidden')) {
return
}
this.$container.find('.fixed-table-header-columns').remove()
this.$fixedHeader = $('<div class="fixed-table-header-columns"></div>')
this.$fixedHeader.append(this.$tableHeader.find('>table').clone(true))
this.$tableHeader.after(this.$fixedHeader)
const width = this.getFixedColumnsWidth()
this.$fixedHeader.css({
top: 0,
width,
height: this.$tableHeader.outerHeight(true)
})
this.initFixedColumnsBody()
this.$fixedBody.css({
top: this.$tableHeader.outerHeight(true),
width,
height: this.$tableBody.outerHeight(true) - 1
})
this.initFixedColumnsEvents()
}
initBody (...args) {
super.initBody(...args)
if (!this.options.fixedColumns) {
return
}
if (this.options.showHeader && this.options.height) {
return
}
this.initFixedColumnsBody()
this.$fixedBody.css({
top: 0,
width: this.getFixedColumnsWidth(),
height: this.$tableHeader.outerHeight(true) + this.$tableBody.outerHeight(true)
})
this.initFixedColumnsEvents()
}
initFixedColumnsBody () {
this.$container.find('.fixed-table-body-columns').remove()
this.$fixedBody = $('<div class="fixed-table-body-columns"></div>')
this.$fixedBody.append(this.$tableBody.find('>table').clone(true))
this.$tableBody.after(this.$fixedBody)
}
getFixedColumnsWidth () {
const visibleFields = this.getVisibleFields()
let width = 0
for (let i = 0; i < this.options.fixedNumber; i++) {
width += this.$header.find(`th[data-field="${visibleFields[i]}"]`).outerWidth(true)
}
return width + 1
}
initFixedColumnsEvents () {
// events
this.$tableBody.off('scroll.fixed-columns').on('scroll.fixed-columns', e => {
this.$fixedBody.find('table').css('top', -$(e.currentTarget).scrollTop())
})
this.$body.find('> tr[data-index]').off('hover').hover(e => {
const index = $(e.currentTarget).data('index')
this.$fixedBody.find(`tr[data-index="${index}"]`)
.css('background-color', $(e.currentTarget).css('background-color'))
}, e => {
const index = $(e.currentTarget).data('index')
const $tr = this.$fixedBody.find(`tr[data-index="${index}"]`)
$tr.attr('style', $tr.attr('style').replace(/background-color:.*;/, ''))
})
this.$fixedBody.find('tr[data-index]').off('hover').hover(e => {
const index = $(e.currentTarget).data('index')
this.$body.find(`tr[data-index="${index}"]`)
.css('background-color', $(e.currentTarget).css('background-color'))
}, e => {
const index = $(e.currentTarget).data('index')
const $tr = this.$body.find(`> tr[data-index="${index}"]`)
$tr.attr('style', $tr.attr('style').replace(/background-color:.*;/, ''))
})
}
}
})(jQuery)

View File

@ -0,0 +1,11 @@
.bootstrap-table .table > tbody > tr.groupBy {
cursor: pointer;
}
.bootstrap-table .table > tbody > tr.groupBy.expanded {
}
.bootstrap-table .table > tbody > tr.hidden + tr.detail-view {
display: none;
}

View File

@ -0,0 +1,230 @@
/**
* @author: Yura Knoxville
* @version: v1.1.0
*/
(function ($) {
'use strict';
var initBodyCaller,
tableGroups;
// 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 groupBy = function (array , f) {
var groups = {};
array.forEach(function(o) {
var group = f(o);
groups[group] = groups[group] || [];
groups[group].push(o);
});
return groups;
};
$.extend($.fn.bootstrapTable.defaults, {
groupBy: false,
groupByField: '',
groupByFormatter: undefined
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_initSort = BootstrapTable.prototype.initSort,
_initBody = BootstrapTable.prototype.initBody,
_updateSelected = BootstrapTable.prototype.updateSelected;
BootstrapTable.prototype.initSort = function () {
_initSort.apply(this, Array.prototype.slice.apply(arguments));
var that = this;
tableGroups = [];
if ((this.options.groupBy) && (this.options.groupByField !== '')) {
if ((this.options.sortName != this.options.groupByField)) {
this.data.sort(function(a, b) {
return a[that.options.groupByField].localeCompare(b[that.options.groupByField]);
});
}
var that = this;
var groups = groupBy(that.data, function (item) {
return [item[that.options.groupByField]];
});
var index = 0;
$.each(groups, function(key, value) {
tableGroups.push({
id: index,
name: key,
data: value
});
value.forEach(function(item) {
if (!item._data) {
item._data = {};
}
item._data['parent-index'] = index;
});
index++;
});
}
}
BootstrapTable.prototype.initBody = function () {
initBodyCaller = true;
_initBody.apply(this, Array.prototype.slice.apply(arguments));
if ((this.options.groupBy) && (this.options.groupByField !== '')) {
var that = this,
checkBox = false,
visibleColumns = 0;
this.columns.forEach(function(column) {
if (column.checkbox) {
checkBox = true;
} else {
if (column.visible) {
visibleColumns += 1;
}
}
});
if (this.options.detailView && !this.options.cardView) {
visibleColumns += 1;
}
tableGroups.forEach(function(item){
var html = [];
html.push(sprintf('<tr class="info groupBy expanded" data-group-index="%s">', item.id));
if (that.options.detailView && !that.options.cardView) {
html.push('<td class="detail"></td>');
}
if (checkBox) {
html.push('<td class="bs-checkbox">',
'<input name="btSelectGroup" type="checkbox" />',
'</td>'
);
}
var formattedValue = item.name;
if (typeof(that.options.groupByFormatter) == "function") {
formattedValue = that.options.groupByFormatter(item.name, item.id, item.data);
}
html.push('<td',
sprintf(' colspan="%s"', visibleColumns),
'>', formattedValue, '</td>'
);
html.push('</tr>');
that.$body.find('tr[data-parent-index='+item.id+']:first').before($(html.join('')));
});
this.$selectGroup = [];
this.$body.find('[name="btSelectGroup"]').each(function() {
var self = $(this);
that.$selectGroup.push({
group: self,
item: that.$selectItem.filter(function () {
return ($(this).closest('tr').data('parent-index') ===
self.closest('tr').data('group-index'));
})
});
});
this.$container.off('click', '.groupBy')
.on('click', '.groupBy', function() {
$(this).toggleClass('expanded');
that.$body.find('tr[data-parent-index='+$(this).closest('tr').data('group-index')+']').toggleClass('hidden');
});
this.$container.off('click', '[name="btSelectGroup"]')
.on('click', '[name="btSelectGroup"]', function (event) {
event.stopImmediatePropagation();
var self = $(this);
var checked = self.prop('checked');
that[checked ? 'checkGroup' : 'uncheckGroup']($(this).closest('tr').data('group-index'));
});
}
initBodyCaller = false;
this.updateSelected();
};
BootstrapTable.prototype.updateSelected = function () {
if (!initBodyCaller) {
_updateSelected.apply(this, Array.prototype.slice.apply(arguments));
if ((this.options.groupBy) && (this.options.groupByField !== '')) {
this.$selectGroup.forEach(function (item) {
var checkGroup = item.item.filter(':enabled').length ===
item.item.filter(':enabled').filter(':checked').length;
item.group.prop('checked', checkGroup);
});
}
}
};
BootstrapTable.prototype.getGroupSelections = function (index) {
var that = this;
return $.grep(this.data, function (row) {
return (row[that.header.stateField] && (row._data['parent-index'] === index));
});
};
BootstrapTable.prototype.checkGroup = function (index) {
this.checkGroup_(index, true);
};
BootstrapTable.prototype.uncheckGroup = function (index) {
this.checkGroup_(index, false);
};
BootstrapTable.prototype.checkGroup_ = function (index, checked) {
var rows;
var filter = function() {
return ($(this).closest('tr').data('parent-index') === index);
};
if (!checked) {
rows = this.getGroupSelections(index);
}
this.$selectItem.filter(filter).prop('checked', checked);
this.updateRows();
this.updateSelected();
if (checked) {
rows = this.getGroupSelections(index);
}
this.trigger(checked ? 'check-all' : 'uncheck-all', rows);
};
})(jQuery);

View File

@ -0,0 +1,12 @@
{
"name": "Group By V2",
"version": "1.0.0",
"description": "Group the data by field",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/group-by-v2",
"example": "",
"plugins": [],
"author": {
"name": "Knoxvillekm",
"image": "https://avatars3.githubusercontent.com/u/11072464"
}
}

View File

@ -0,0 +1,53 @@
table.treetable tbody tr td {
cursor: default;
}
table.treetable span {
background-position: center left;
background-repeat: no-repeat;
padding: .2em 0 .2em 1.5em;
}
table.treetable tr.collapsed span.indenter a {
background-image: url(data:image/png;base64,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);
padding-right: 12px;
}
table.treetable tr.expanded span.indenter a {
background-image: url(data:image/png;base64,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);
padding-right: 12px;
}
table.treetable tr.branch {
background-color: #f9f9f9;
}
table.treetable tr.selected {
background-color: #3875d7;
color: #fff;
}
table.treetable tr span.indenter a {
outline: none; /* Expander shows outline after upgrading to 3.0 (#141) */
}
table.treetable tr.collapsed.selected span.indenter a {
background-image: url(data:image/png;base64,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);
}
table.treetable tr.expanded.selected span.indenter a {
background-image: url(data:image/png;base64,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);
}
table.treetable tr.accept {
background-color: #a3bce4;
color: #fff
}
table.treetable tr.collapsed.accept td span.indenter a {
background-image: url(data:image/x-png;base64,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);
}
table.treetable tr.expanded.accept td span.indenter a {
background-image: url(data:image/x-png;base64,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);
}

View File

@ -0,0 +1,243 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @version: v1.1.0
*/
!function ($) {
'use strict';
var originalRowAttr,
dataTTId = 'data-tt-id',
dataTTParentId = 'data-tt-parent-id',
obj = {},
parentId = undefined;
var getParentRowId = function (that, id) {
var parentRows = that.$body.find('tr').not('[' + 'data-tt-parent-id]');
for (var i = 0; i < parentRows.length; i++) {
if (i === id) {
return $(parentRows[i]).attr('data-tt-id');
}
}
return undefined;
};
var sumData = function (that, data) {
var sumRow = {};
$.each(data, function (i, row) {
if (!row.IsParent) {
for (var prop in row) {
if (!isNaN(parseFloat(row[prop]))) {
if (that.columns[that.fieldsColumnsIndex[prop]].groupBySumGroup) {
if (sumRow[prop] === undefined) {
sumRow[prop] = 0;
}
sumRow[prop] += +row[prop];
}
}
}
}
});
return sumRow;
};
var rowAttr = function (row, index) {
//Call the User Defined Function
originalRowAttr.apply([row, index]);
obj[dataTTId.toString()] = index;
if (!row.IsParent) {
obj[dataTTParentId.toString()] = parentId === undefined ? index : parentId;
} else {
parentId = index;
delete obj[dataTTParentId.toString()];
}
return obj;
};
var setObjectKeys = function () {
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
Object.keys = function (o) {
if (o !== Object(o)) {
throw new TypeError('Object.keys called on a non-object');
}
var k = [],
p;
for (p in o) {
if (Object.prototype.hasOwnProperty.call(o, p)) {
k.push(p);
}
}
return k;
}
};
var getDataArrayFromItem = function (that, item) {
var itemDataArray = [];
for (var i = 0; i < that.options.groupByField.length; i++) {
itemDataArray.push(item[that.options.groupByField[i]]);
}
return itemDataArray;
};
var getNewRow = function (that, result, index) {
var newRow = {};
for (var i = 0; i < that.options.groupByField.length; i++) {
newRow[that.options.groupByField[i].toString()] = result[index][0][that.options.groupByField[i]];
}
newRow.IsParent = true;
return newRow;
};
var groupBy = function (array, f) {
var groups = {};
$.each(array, function (i, o) {
var group = JSON.stringify(f(o));
groups[group] = groups[group] || [];
groups[group].push(o);
});
return Object.keys(groups).map(function (group) {
return groups[group];
});
};
var makeGrouped = function (that, data) {
var newData = [],
sumRow = {};
var result = groupBy(data, function (item) {
return getDataArrayFromItem(that, item);
});
for (var i = 0; i < result.length; i++) {
result[i].unshift(getNewRow(that, result, i));
if (that.options.groupBySumGroup) {
sumRow = sumData(that, result[i]);
if (!$.isEmptyObject(sumRow)) {
result[i].push(sumRow);
}
}
}
newData = newData.concat.apply(newData, result);
if (!that.options.loaded && newData.length > 0) {
that.options.loaded = true;
that.options.originalData = that.options.data;
that.options.data = newData;
}
return newData;
};
$.extend($.fn.bootstrapTable.defaults, {
groupBy: false,
groupByField: [],
groupBySumGroup: false,
groupByInitExpanded: undefined, //node, 'all'
//internal variables
loaded: false,
originalData: undefined
});
$.fn.bootstrapTable.methods.push('collapseAll', 'expandAll', 'refreshGroupByField');
$.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {
groupBySumGroup: false
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_init = BootstrapTable.prototype.init,
_initData = BootstrapTable.prototype.initData;
BootstrapTable.prototype.init = function () {
//Temporal validation
if (!this.options.sortName) {
if ((this.options.groupBy) && (this.options.groupByField.length > 0)) {
var that = this;
// Compatibility: IE < 9 and old browsers
if (!Object.keys) {
$.fn.bootstrapTable.utils.objectKeys();
}
//Make sure that the internal variables are set correctly
this.options.loaded = false;
this.options.originalData = undefined;
originalRowAttr = this.options.rowAttributes;
this.options.rowAttributes = rowAttr;
this.$el.off('post-body.bs.table').on('post-body.bs.table', function () {
that.$el.treetable({
expandable: true,
onNodeExpand: function () {
if (that.options.height) {
that.resetHeader();
}
},
onNodeCollapse: function () {
if (that.options.height) {
that.resetHeader();
}
}
}, true);
if (that.options.groupByInitExpanded !== undefined) {
if (typeof that.options.groupByInitExpanded === 'number') {
that.expandNode(that.options.groupByInitExpanded);
} else if (that.options.groupByInitExpanded.toLowerCase() === 'all') {
that.expandAll();
}
}
});
}
}
_init.apply(this, Array.prototype.slice.apply(arguments));
};
BootstrapTable.prototype.initData = function (data, type) {
//Temporal validation
if (!this.options.sortName) {
if ((this.options.groupBy) && (this.options.groupByField.length > 0)) {
this.options.groupByField = typeof this.options.groupByField === 'string' ?
this.options.groupByField.replace('[', '').replace(']', '')
.replace(/ /g, '').toLowerCase().split(',') : this.options.groupByField;
data = makeGrouped(this, data ? data : this.options.data);
}
}
_initData.apply(this, [data, type]);
};
BootstrapTable.prototype.expandAll = function () {
this.$el.treetable('expandAll');
};
BootstrapTable.prototype.collapseAll = function () {
this.$el.treetable('collapseAll');
};
BootstrapTable.prototype.expandNode = function (id) {
id = getParentRowId(this, id);
if (id !== undefined) {
this.$el.treetable('expandNode', id);
}
};
BootstrapTable.prototype.refreshGroupByField = function (groupByFields) {
if (!$.fn.bootstrapTable.utils.compareObjects(this.options.groupByField, groupByFields)) {
this.options.groupByField = groupByFields;
this.load(this.options.originalData);
}
};
}(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "Group By",
"version": "1.1.0",
"description": "Plugin to group the data by fields.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/group-by",
"example": "#",
"plugins": [{
"name": "bootstrap-table-group-by",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/group-by"
}],
"author": {
"name": "djhvscf",
"image": "https://avatars1.githubusercontent.com/u/4496763"
}
}

View File

@ -0,0 +1,35 @@
/**
* @author: Jewway
* @version: v1.0.0
*/
!function ($) {
'use strict';
var BootstrapTable = $.fn.bootstrapTable.Constructor;
BootstrapTable.prototype.changeTitle = function (locale) {
$.each(this.options.columns, function (idx, columnList) {
$.each(columnList, function (idx, column) {
if (column.field) {
column.title = locale[column.field];
}
});
});
this.initHeader();
this.initBody();
this.initToolbar();
};
BootstrapTable.prototype.changeLocale = function (localeId) {
this.options.locale = localeId;
this.initLocale();
this.initPagination();
this.initBody();
this.initToolbar();
};
$.fn.bootstrapTable.methods.push('changeTitle');
$.fn.bootstrapTable.methods.push('changeLocale');
}(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "i18n Enhance",
"version": "1.0.0",
"description": "Plugin to add i18n API in order to change column's title and table locale.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/i18n-enhance",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/i18n-enhance.html",
"plugins": [{
"name": "bootstrap-table-i18n-enhance",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/i18n-enhance"
}],
"author": {
"name": "Jewway",
"image": "https://avatars0.githubusercontent.com/u/3501899"
}
}

View File

@ -0,0 +1,80 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @version: v1.0.0
*
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
!function ($) {
'use strict';
$.extend($.fn.bootstrapTable.defaults, {
keyEvents: false
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_init = BootstrapTable.prototype.init;
BootstrapTable.prototype.init = function () {
_init.apply(this, Array.prototype.slice.apply(arguments));
this.initKeyEvents();
};
BootstrapTable.prototype.initKeyEvents = function () {
if (this.options.keyEvents) {
var that = this;
$(document).off('keydown').on('keydown', function (e) {
var $search = that.$toolbar.find('.search input'),
$refresh = that.$toolbar.find('button[name="refresh"]'),
$toggle = that.$toolbar.find('button[name="toggle"]'),
$paginationSwitch = that.$toolbar.find('button[name="paginationSwitch"]');
if (document.activeElement === $search.get(0) || !$.contains(document.activeElement ,that.$toolbar.get(0))) {
return true;
}
switch (e.keyCode) {
case 83: //s
if (!that.options.search) {
return;
}
$search.focus();
return false;
case 82: //r
if (!that.options.showRefresh) {
return;
}
$refresh.click();
return false;
case 84: //t
if (!that.options.showToggle) {
return;
}
$toggle.click();
return false;
case 80: //p
if (!that.options.showPaginationSwitch) {
return;
}
$paginationSwitch.click();
return false;
case 37: // left
if (!that.options.pagination) {
return;
}
that.prevPage();
return false;
case 39: // right
if (!that.options.pagination) {
return;
}
that.nextPage();
return;
}
});
}
};
}(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "Key Events",
"version": "1.0.0",
"description": "Plugin to support the key events in the bootstrap table.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/key-events",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/key-events.html",
"plugins": [{
"name": "bootstrap-table-key-events",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/key-events"
}],
"author": {
"name": "djhvscf",
"image": "https://avatars1.githubusercontent.com/u/4496763"
}
}

View File

@ -0,0 +1,136 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @version: v1.1.0
*/
!function ($) {
'use strict';
var showHideColumns = function (that, checked) {
if (that.options.columnsHidden.length > 0 ) {
$.each(that.columns, function (i, column) {
if (that.options.columnsHidden.indexOf(column.field) !== -1) {
if (column.visible !== checked) {
that.toggleColumn(that.fieldsColumnsIndex[column.field], checked, true);
}
}
});
}
};
var resetView = function (that) {
if (that.options.height || that.options.showFooter) {
setTimeout(function(){
that.resetView.call(that);
}, 1);
}
};
var changeView = function (that, width, height) {
if (that.options.minHeight) {
if ((width <= that.options.minWidth) && (height <= that.options.minHeight)) {
conditionCardView(that);
} else if ((width > that.options.minWidth) && (height > that.options.minHeight)) {
conditionFullView(that);
}
} else {
if (width <= that.options.minWidth) {
conditionCardView(that);
} else if (width > that.options.minWidth) {
conditionFullView(that);
}
}
resetView(that);
};
var conditionCardView = function (that) {
changeTableView(that, false);
showHideColumns(that, false);
};
var conditionFullView = function (that) {
changeTableView(that, true);
showHideColumns(that, true);
};
var changeTableView = function (that, cardViewState) {
that.options.cardView = cardViewState;
that.toggleView();
};
var debounce = function(func,wait) {
var timeout;
return function() {
var context = this,
args = arguments;
var later = function() {
timeout = null;
func.apply(context,args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};
$.extend($.fn.bootstrapTable.defaults, {
mobileResponsive: false,
minWidth: 562,
minHeight: undefined,
heightThreshold: 100, // just slightly larger than mobile chrome's auto-hiding toolbar
checkOnInit: true,
columnsHidden: []
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_init = BootstrapTable.prototype.init;
BootstrapTable.prototype.init = function () {
_init.apply(this, Array.prototype.slice.apply(arguments));
if (!this.options.mobileResponsive) {
return;
}
if (!this.options.minWidth) {
return;
}
if (this.options.minWidth < 100 && this.options.resizable) {
console.log("The minWidth when the resizable extension is active should be greater or equal than 100");
this.options.minWidth = 100;
}
var that = this,
old = {
width: $(window).width(),
height: $(window).height()
};
$(window).on('resize orientationchange',debounce(function (evt) {
// reset view if height has only changed by at least the threshold.
var height = $(this).height(),
width = $(this).width();
if (Math.abs(old.height - height) > that.options.heightThreshold || old.width != width) {
changeView(that, width, height);
old = {
width: width,
height: height
};
}
},200));
if (this.options.checkOnInit) {
var height = $(window).height(),
width = $(window).width();
changeView(this, width, height);
old = {
width: width,
height: height
};
}
};
}(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "Mobile",
"version": "1.1.0",
"description": "Plugin to support the responsive feature.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/mobile",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/mobile.html",
"plugins": [{
"name": "bootstrap-table-mobile",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/mobile"
}],
"author": {
"name": "djhvscf",
"image": "https://avatars1.githubusercontent.com/u/4496763"
}
}

View File

@ -0,0 +1,88 @@
/**
* @author Homer Glascock <HopGlascock@gmail.com>
* @version: v1.0.0
*/
!function ($) {
"use strict";
var sprintf = $.fn.bootstrapTable.utils.sprintf;
var reInit = function (self) {
self.initHeader();
self.initSearch();
self.initPagination();
self.initBody();
};
$.extend($.fn.bootstrapTable.defaults, {
showToggleBtn: false,
multiToggleDefaults: [], //column names go here
});
$.fn.bootstrapTable.methods.push('hideAllColumns', 'showAllColumns');
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_initToolbar = BootstrapTable.prototype.initToolbar;
BootstrapTable.prototype.initToolbar = function () {
_initToolbar.apply(this, Array.prototype.slice.apply(arguments));
var that = this,
$btnGroup = this.$toolbar.find('>.btn-group');
if (typeof this.options.multiToggleDefaults === 'string') {
this.options.multiToggleDefaults = JSON.parse(this.options.multiToggleDefaults);
}
if (this.options.showToggleBtn && this.options.showColumns) {
var showbtn = "<button class='btn btn-default hidden' id='showAllBtn'><span class='glyphicon glyphicon-resize-full icon-zoom-in'></span></button>",
hidebtn = "<button class='btn btn-default' id='hideAllBtn'><span class='glyphicon glyphicon-resize-small icon-zoom-out'></span></button>";
$btnGroup.append(showbtn + hidebtn);
$btnGroup.find('#showAllBtn').click(function () { that.showAllColumns();
$btnGroup.find('#hideAllBtn').toggleClass('hidden');
$btnGroup.find('#showAllBtn').toggleClass('hidden');
});
$btnGroup.find('#hideAllBtn').click(function () { that.hideAllColumns();
$btnGroup.find('#hideAllBtn').toggleClass('hidden');
$btnGroup.find('#showAllBtn').toggleClass('hidden');
});
}
};
BootstrapTable.prototype.hideAllColumns = function () {
var that = this,
defaults = that.options.multiToggleDefaults;
$.each(this.columns, function (index, column) {
//if its one of the defaults dont touch it
if (defaults.indexOf(column.field) == -1 && column.switchable) {
column.visible = false;
var $items = that.$toolbar.find('.keep-open input').prop('disabled', false);
$items.filter(sprintf('[value="%s"]', index)).prop('checked', false);
}
});
reInit(that);
};
BootstrapTable.prototype.showAllColumns = function () {
var that = this;
$.each(this.columns, function (index, column) {
if (column.switchable) {
column.visible = true;
}
var $items = that.$toolbar.find('.keep-open input').prop('disabled', false);
$items.filter(sprintf('[value="%s"]', index)).prop('checked', true);
});
reInit(that);
that.toggleColumn(0, that.columns[0].visible, false);
};
}(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "Multi Column Toggle",
"version": "1.0.0",
"description": "Allows hiding and showing of multiple columns at once.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/multi-column-toggle",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/multi-column-toggle.html",
"plugins": [{
"name": "multi-column-toggle",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/multi-column-toggle"
}],
"author": {
"name": "Homer Glascock",
"image": "https://avatars1.githubusercontent.com/u/5546710"
}
}

View File

@ -0,0 +1,71 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @version: v1.0.0
*/
!function ($) {
'use strict';
$.extend($.fn.bootstrapTable.defaults, {
multipleSearch: false,
delimeter: " "
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_initSearch = BootstrapTable.prototype.initSearch;
BootstrapTable.prototype.initSearch = function () {
if (this.options.multipleSearch) {
if (this.searchText === undefined) {
return;
}
var strArray = this.searchText.split(this.options.delimeter),
that = this,
f = $.isEmptyObject(this.filterColumns) ? null : this.filterColumns,
dataFiltered = [];
if (strArray.length === 1) {
_initSearch.apply(this, Array.prototype.slice.apply(arguments));
} else {
for (var i = 0; i < strArray.length; i++) {
var str = strArray[i].trim();
dataFiltered = str ? $.grep(dataFiltered.length === 0 ? this.options.data : dataFiltered, function (item, i) {
for (var key in item) {
key = $.isNumeric(key) ? parseInt(key, 10) : key;
var value = item[key],
column = that.columns[that.fieldsColumnsIndex[key]],
j = $.inArray(key, that.header.fields);
// Fix #142: search use formated data
if (column && column.searchFormatter) {
value = $.fn.bootstrapTable.utils.calculateObjectValue(column,
that.header.formatters[j], [value, item, i], value);
}
var index = $.inArray(key, that.header.fields);
if (index !== -1 && that.header.searchables[index] && (typeof value === 'string' || typeof value === 'number')) {
if (that.options.strictSearch) {
if ((value + '').toLowerCase() === str) {
return true;
}
} else {
if ((value + '').toLowerCase().indexOf(str) !== -1) {
return true;
}
}
}
}
return false;
}) : this.data;
}
this.data = dataFiltered;
}
} else {
_initSearch.apply(this, Array.prototype.slice.apply(arguments));
}
};
}(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "Multiple Search",
"version": "1.0.0",
"description": "Plugin to support the multiple search.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/multiple-search",
"example": "#",
"plugins": [{
"name": "bootstrap-table-multiple-search",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/multiple-search"
}],
"author": {
"name": "djhvscf",
"image": "https://avatars1.githubusercontent.com/u/4496763"
}
}

View File

@ -0,0 +1,17 @@
.multiple-select-row-selected {
background: lightBlue
}
.table tbody tr:hover td,
.table tbody tr:hover th {
background-color: transparent;
}
.table-striped tbody tr:nth-child(odd):hover td {
background-color: #F9F9F9;
}
.fixed-table-container tbody .selected td {
background: lightBlue;
}

View File

@ -0,0 +1,127 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @version: v1.0.0
*/
!function ($) {
'use strict';
document.onselectstart = function() {
return false;
};
var getTableObjectFromCurrentTarget = function (currentTarget) {
currentTarget = $(currentTarget);
return currentTarget.is("table") ? currentTarget : currentTarget.parents().find(".table");
};
var getRow = function (target) {
target = $(target);
return target.parent().parent();
};
var onRowClick = function (e) {
var that = getTableObjectFromCurrentTarget(e.currentTarget);
if (window.event.ctrlKey) {
toggleRow(e.currentTarget, that, false, false);
}
if (window.event.button === 0) {
if (!window.event.ctrlKey && !window.event.shiftKey) {
clearAll(that);
toggleRow(e.currentTarget, that, false, false);
}
if (window.event.shiftKey) {
selectRowsBetweenIndexes([that.bootstrapTable("getOptions").multipleSelectRowLastSelectedRow.rowIndex, e.currentTarget.rowIndex], that)
}
}
};
var onCheckboxChange = function (e) {
var that = getTableObjectFromCurrentTarget(e.currentTarget);
clearAll(that);
toggleRow(getRow(e.currentTarget), that, false, false);
};
var toggleRow = function (row, that, clearAll, useShift) {
if (clearAll) {
row = $(row);
that.bootstrapTable("getOptions").multipleSelectRowLastSelectedRow = undefined;
row.removeClass(that.bootstrapTable("getOptions").multipleSelectRowCssClass);
that.bootstrapTable("uncheck", row.data("index"));
} else {
that.bootstrapTable("getOptions").multipleSelectRowLastSelectedRow = row;
row = $(row);
if (useShift) {
row.addClass(that.bootstrapTable("getOptions").multipleSelectRowCssClass);
that.bootstrapTable("check", row.data("index"));
} else {
if(row.hasClass(that.bootstrapTable("getOptions").multipleSelectRowCssClass)) {
row.removeClass(that.bootstrapTable("getOptions").multipleSelectRowCssClass)
that.bootstrapTable("uncheck", row.data("index"));
} else {
row.addClass(that.bootstrapTable("getOptions").multipleSelectRowCssClass);
that.bootstrapTable("check", row.data("index"));
}
}
}
};
var selectRowsBetweenIndexes = function (indexes, that) {
indexes.sort(function(a, b) {
return a - b;
});
for (var i = indexes[0]; i <= indexes[1]; i++) {
toggleRow(that.bootstrapTable("getOptions").multipleSelectRowRows[i-1], that, false, true);
}
};
var clearAll = function (that) {
for (var i = 0; i < that.bootstrapTable("getOptions").multipleSelectRowRows.length; i++) {
toggleRow(that.bootstrapTable("getOptions").multipleSelectRowRows[i], that, true, false);
}
};
$.extend($.fn.bootstrapTable.defaults, {
multipleSelectRow: false,
multipleSelectRowCssClass: 'multiple-select-row-selected',
//internal variables used by the extension
multipleSelectRowLastSelectedRow: undefined,
multipleSelectRowRows: []
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_init = BootstrapTable.prototype.init,
_initBody = BootstrapTable.prototype.initBody;
BootstrapTable.prototype.init = function () {
if (this.options.multipleSelectRow) {
var that = this;
//Make sure that the internal variables have the correct value
this.options.multipleSelectRowLastSelectedRow = undefined;
this.options.multipleSelectRowRows = [];
this.$el.on("post-body.bs.table", function (e) {
setTimeout(function () {
that.options.multipleSelectRowRows = that.$body.children();
that.options.multipleSelectRowRows.click(onRowClick);
that.options.multipleSelectRowRows.find("input[type=checkbox]").change(onCheckboxChange);
}, 1);
});
}
_init.apply(this, Array.prototype.slice.apply(arguments));
};
BootstrapTable.prototype.clearAllMultipleSelectionRow = function () {
clearAll(this);
};
$.fn.bootstrapTable.methods.push('clearAllMultipleSelectionRow');
}(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "Multiple Selection Row",
"version": "1.0.0",
"description": "Plugin to enable the multiple selection row. You can use the ctrl+click to select one row or use ctrl+shift+click to select a range of rows.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/multiple-selection-row",
"example": "",
"plugins": [{
"name": "bootstrap-table-multiple-selection-row",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/multiple-selection-row"
}],
"author": {
"name": "djhvscf",
"image": "https://avatars1.githubusercontent.com/u/4496763"
}
}

View File

@ -0,0 +1,412 @@
/**
* @author Nadim Basalamah <dimbslmh@gmail.com>
* @version: v1.1.0
* https://github.com/dimbslmh/bootstrap-table/tree/master/src/extensions/multiple-sort/bootstrap-table-multiple-sort.js
* Modification: ErwannNevou <https://github.com/ErwannNevou>
*/
(function($) {
'use strict';
var isSingleSort = false;
var showSortModal = function(that) {
var _selector = that.sortModalSelector,
_id = '#' + _selector;
if (!$(_id).hasClass("modal")) {
var sModal = ' <div class="modal fade" id="' + _selector + '" tabindex="-1" role="dialog" aria-labelledby="' + _selector + 'Label" aria-hidden="true">';
sModal += ' <div class="modal-dialog">';
sModal += ' <div class="modal-content">';
sModal += ' <div class="modal-header">';
sModal += ' <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>';
sModal += ' <h4 class="modal-title" id="' + _selector + 'Label">' + that.options.formatMultipleSort() + '</h4>';
sModal += ' </div>';
sModal += ' <div class="modal-body">';
sModal += ' <div class="bootstrap-table">';
sModal += ' <div class="fixed-table-toolbar">';
sModal += ' <div class="bars">';
sModal += ' <div id="toolbar">';
sModal += ' <button id="add" type="button" class="btn btn-default"><i class="' + that.options.iconsPrefix + ' ' + that.options.icons.plus + '"></i> ' + that.options.formatAddLevel() + '</button>';
sModal += ' <button id="delete" type="button" class="btn btn-default" disabled><i class="' + that.options.iconsPrefix + ' ' + that.options.icons.minus + '"></i> ' + that.options.formatDeleteLevel() + '</button>';
sModal += ' </div>';
sModal += ' </div>';
sModal += ' </div>';
sModal += ' <div class="fixed-table-container">';
sModal += ' <table id="multi-sort" class="table">';
sModal += ' <thead>';
sModal += ' <tr>';
sModal += ' <th></th>';
sModal += ' <th><div class="th-inner">' + that.options.formatColumn() + '</div></th>';
sModal += ' <th><div class="th-inner">' + that.options.formatOrder() + '</div></th>';
sModal += ' </tr>';
sModal += ' </thead>';
sModal += ' <tbody></tbody>';
sModal += ' </table>';
sModal += ' </div>';
sModal += ' </div>';
sModal += ' </div>';
sModal += ' <div class="modal-footer">';
sModal += ' <button type="button" class="btn btn-default" data-dismiss="modal">' + that.options.formatCancel() + '</button>';
sModal += ' <button type="button" class="btn btn-primary">' + that.options.formatSort() + '</button>';
sModal += ' </div>';
sModal += ' </div>';
sModal += ' </div>';
sModal += ' </div>';
$('body').append($(sModal));
that.$sortModal = $(_id);
var $rows = that.$sortModal.find('tbody > tr');
that.$sortModal.off('click', '#add').on('click', '#add', function() {
var total = that.$sortModal.find('.multi-sort-name:first option').length,
current = that.$sortModal.find('tbody tr').length;
if (current < total) {
current++;
that.addLevel();
that.setButtonStates();
}
});
that.$sortModal.off('click', '#delete').on('click', '#delete', function() {
var total = that.$sortModal.find('.multi-sort-name:first option').length,
current = that.$sortModal.find('tbody tr').length;
if (current > 1 && current <= total) {
current--;
that.$sortModal.find('tbody tr:last').remove();
that.setButtonStates();
}
});
that.$sortModal.off('click', '.btn-primary').on('click', '.btn-primary', function() {
var $rows = that.$sortModal.find('tbody > tr'),
$alert = that.$sortModal.find('div.alert'),
fields = [],
results = [];
that.options.sortPriority = $.map($rows, function(row) {
var $row = $(row),
name = $row.find('.multi-sort-name').val(),
order = $row.find('.multi-sort-order').val();
fields.push(name);
return {
sortName: name,
sortOrder: order
};
});
var sorted_fields = fields.sort();
for (var i = 0; i < fields.length - 1; i++) {
if (sorted_fields[i + 1] == sorted_fields[i]) {
results.push(sorted_fields[i]);
}
}
if (results.length > 0) {
if ($alert.length === 0) {
$alert = '<div class="alert alert-danger" role="alert"><strong>' + that.options.formatDuplicateAlertTitle() + '</strong> ' + that.options.formatDuplicateAlertDescription() + '</div>';
$($alert).insertBefore(that.$sortModal.find('.bars'));
}
} else {
if ($alert.length === 1) {
$($alert).remove();
}
that.$sortModal.modal('hide');
that.options.sortName = '';
if (that.options.sidePagination === 'server') {
var t = that.options.queryParams;
that.options.queryParams = function(params) {
params.multiSort = that.options.sortPriority;
return t(params);
};
isSingleSort=false;
that.initServer(that.options.silentSort);
return;
}
that.onMultipleSort();
}
});
if (that.options.sortPriority === null || that.options.sortPriority.length === 0) {
if (that.options.sortName) {
that.options.sortPriority = [{
sortName: that.options.sortName,
sortOrder: that.options.sortOrder
}];
}
}
if (that.options.sortPriority !== null && that.options.sortPriority.length > 0) {
if ($rows.length < that.options.sortPriority.length && typeof that.options.sortPriority === 'object') {
for (var i = 0; i < that.options.sortPriority.length; i++) {
that.addLevel(i, that.options.sortPriority[i]);
}
}
} else {
that.addLevel(0);
}
that.setButtonStates();
}
};
$.fn.bootstrapTable.methods.push('multipleSort');
$.extend($.fn.bootstrapTable.defaults, {
showMultiSort: false,
showMultiSortButton: true,
sortPriority: null,
onMultipleSort: function() {
return false;
}
});
$.extend($.fn.bootstrapTable.defaults.icons, {
sort: 'glyphicon-sort',
plus: 'glyphicon-plus',
minus: 'glyphicon-minus'
});
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
'multiple-sort.bs.table': 'onMultipleSort'
});
$.extend($.fn.bootstrapTable.locales, {
formatMultipleSort: function() {
return 'Multiple Sort';
},
formatAddLevel: function() {
return 'Add Level';
},
formatDeleteLevel: function() {
return 'Delete Level';
},
formatColumn: function() {
return 'Column';
},
formatOrder: function() {
return 'Order';
},
formatSortBy: function() {
return 'Sort by';
},
formatThenBy: function() {
return 'Then by';
},
formatSort: function() {
return 'Sort';
},
formatCancel: function() {
return 'Cancel';
},
formatDuplicateAlertTitle: function() {
return 'Duplicate(s) detected!';
},
formatDuplicateAlertDescription: function() {
return 'Please remove or change any duplicate column.';
},
formatSortOrders: function() {
return {
asc: 'Ascending',
desc: 'Descending'
};
}
});
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_initToolbar = BootstrapTable.prototype.initToolbar;
BootstrapTable.prototype.initToolbar = function() {
this.showToolbar = this.showToolbar || this.options.showMultiSort;
var that = this,
sortModalSelector = 'sortModal_' + this.$el.attr('id'),
sortModalId = '#' + sortModalSelector;
this.$sortModal = $(sortModalId);
this.sortModalSelector = sortModalSelector;
_initToolbar.apply(this, Array.prototype.slice.apply(arguments));
if (that.options.sidePagination === 'server' && !isSingleSort && that.options.sortPriority !== null){
var t = that.options.queryParams;
that.options.queryParams = function(params) {
params.multiSort = that.options.sortPriority;
return t(params);
};
}
if (this.options.showMultiSort) {
var $btnGroup = this.$toolbar.find('>.btn-group').first(),
$multiSortBtn = this.$toolbar.find('div.multi-sort');
if (!$multiSortBtn.length && this.options.showMultiSortButton) {
$multiSortBtn = ' <button class="multi-sort btn btn-default' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + '" type="button" data-toggle="modal" data-target="' + sortModalId + '" title="' + this.options.formatMultipleSort() + '">';
$multiSortBtn += ' <i class="' + this.options.iconsPrefix + ' ' + this.options.icons.sort + '"></i>';
$multiSortBtn += '</button>';
$btnGroup.append($multiSortBtn);
showSortModal(that);
}
this.$el.on('sort.bs.table', function() {
isSingleSort = true;
});
this.$el.on('multiple-sort.bs.table', function() {
isSingleSort = false;
});
this.$el.on('load-success.bs.table', function() {
if (!isSingleSort && that.options.sortPriority !== null && typeof that.options.sortPriority === 'object' && that.options.sidePagination !== 'server') {
that.onMultipleSort();
}
});
this.$el.on('column-switch.bs.table', function(field, checked) {
for (var i = 0; i < that.options.sortPriority.length; i++) {
if (that.options.sortPriority[i].sortName === checked) {
that.options.sortPriority.splice(i, 1);
}
}
that.assignSortableArrows();
that.$sortModal.remove();
showSortModal(that);
});
this.$el.on('reset-view.bs.table', function() {
if (!isSingleSort && that.options.sortPriority !== null && typeof that.options.sortPriority === 'object') {
that.assignSortableArrows();
}
});
}
};
BootstrapTable.prototype.multipleSort = function() {
var that = this;
if (!isSingleSort && that.options.sortPriority !== null && typeof that.options.sortPriority === 'object' && that.options.sidePagination !== 'server') {
that.onMultipleSort();
}
};
BootstrapTable.prototype.onMultipleSort = function() {
var that = this;
var cmp = function(x, y) {
return x > y ? 1 : x < y ? -1 : 0;
};
var arrayCmp = function(a, b) {
var arr1 = [],
arr2 = [];
for (var i = 0; i < that.options.sortPriority.length; i++) {
var order = that.options.sortPriority[i].sortOrder === 'desc' ? -1 : 1,
aa = a[that.options.sortPriority[i].sortName],
bb = b[that.options.sortPriority[i].sortName];
if (aa === undefined || aa === null) {
aa = '';
}
if (bb === undefined || bb === null) {
bb = '';
}
if ($.isNumeric(aa) && $.isNumeric(bb)) {
aa = parseFloat(aa);
bb = parseFloat(bb);
}
if (typeof aa !== 'string') {
aa = aa.toString();
}
arr1.push(
order * cmp(aa, bb));
arr2.push(
order * cmp(bb, aa));
}
return cmp(arr1, arr2);
};
this.data.sort(function(a, b) {
return arrayCmp(a, b);
});
this.initBody();
this.assignSortableArrows();
this.trigger('multiple-sort');
};
BootstrapTable.prototype.addLevel = function(index, sortPriority) {
var text = index === 0 ? this.options.formatSortBy() : this.options.formatThenBy();
this.$sortModal.find('tbody')
.append($('<tr>')
.append($('<td>').text(text))
.append($('<td>').append($('<select class="form-control multi-sort-name">')))
.append($('<td>').append($('<select class="form-control multi-sort-order">')))
);
var $multiSortName = this.$sortModal.find('.multi-sort-name').last(),
$multiSortOrder = this.$sortModal.find('.multi-sort-order').last();
$.each(this.columns, function(i, column) {
if (column.sortable === false || column.visible === false) {
return true;
}
$multiSortName.append('<option value="' + column.field + '">' + column.title + '</option>');
});
$.each(this.options.formatSortOrders(), function(value, order) {
$multiSortOrder.append('<option value="' + value + '">' + order + '</option>');
});
if (sortPriority !== undefined) {
$multiSortName.find('option[value="' + sortPriority.sortName + '"]').attr("selected", true);
$multiSortOrder.find('option[value="' + sortPriority.sortOrder + '"]').attr("selected", true);
}
};
BootstrapTable.prototype.assignSortableArrows = function() {
var that = this,
headers = that.$header.find('th');
for (var i = 0; i < headers.length; i++) {
for (var c = 0; c < that.options.sortPriority.length; c++) {
if ($(headers[i]).data('field') === that.options.sortPriority[c].sortName) {
$(headers[i]).find('.sortable').removeClass('desc asc').addClass(that.options.sortPriority[c].sortOrder);
}
}
}
};
BootstrapTable.prototype.setButtonStates = function() {
var total = this.$sortModal.find('.multi-sort-name:first option').length,
current = this.$sortModal.find('tbody tr').length;
if (current == total) {
this.$sortModal.find('#add').attr('disabled', 'disabled');
}
if (current > 1) {
this.$sortModal.find('#delete').removeAttr('disabled');
}
if (current < total) {
this.$sortModal.find('#add').removeAttr('disabled');
}
if (current == 1) {
this.$sortModal.find('#delete').attr('disabled', 'disabled');
}
};
})(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "Multiple Sort",
"version": "1.1.0",
"description": "Plugin to support the multiple sort.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/multiple-sort",
"example": "#",
"plugins": [{
"name": "bootstrap-table-multiple-sort",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/multiple-sort"
}],
"author": {
"name": "dimbslmh",
"image": "https://avatars1.githubusercontent.com/u/745635"
}
}

View File

@ -0,0 +1,67 @@
/**
* @author: Brian Huisman
* @webSite: http://www.greywyvern.com
* @version: v1.0.0
* JS functions to allow natural sorting on bootstrap-table columns
* add data-sorter="alphanum" or data-sorter="numericOnly" to any th
*
* @update Dennis Hernández <http://djhvscf.github.io/Blog>
* @update Duane May
*/
function alphanum(a, b) {
function chunkify(t) {
var tz = [],
x = 0,
y = -1,
n = 0,
i,
j;
while (i = (j = t.charAt(x++)).charCodeAt(0)) {
var m = (i === 46 || (i >= 48 && i <= 57));
if (m !== n) {
tz[++y] = "";
n = m;
}
tz[y] += j;
}
return tz;
}
function stringfy(v) {
if (typeof(v) === "number") {
v = "" + v;
}
if (!v) {
v = "";
}
return v;
}
var aa = chunkify(stringfy(a));
var bb = chunkify(stringfy(b));
for (x = 0; aa[x] && bb[x]; x++) {
if (aa[x] !== bb[x]) {
var c = Number(aa[x]),
d = Number(bb[x]);
if (c == aa[x] && d == bb[x]) {
return c - d;
} else {
return (aa[x] > bb[x]) ? 1 : -1;
}
}
}
return aa.length - bb.length;
}
function numericOnly(a, b) {
function stripNonNumber(s) {
s = s.replace(new RegExp(/[^0-9]/g), "");
return parseInt(s, 10);
}
return stripNonNumber(a) - stripNonNumber(b);
}

View File

@ -0,0 +1,17 @@
{
"name": "Natural Sorting",
"version": "1.0.0",
"description": "Plugin to support the natural sorting.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/natural-sorting",
"example": "#",
"plugins": [{
"name": "bootstrap-table-natural-sorting",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/natural-sorting"
}],
"author": {
"name": "GreyWyvern",
"image": "https://avatars1.githubusercontent.com/u/137631"
}
}

View File

@ -0,0 +1,8 @@
.jumpto input {
height: 31px;
width: 50px;
margin-left: 5px;
margin-right: 5px;
text-align: center;
display: inline-block;
}

View File

@ -0,0 +1,50 @@
/**
* @author Jay <jwang@dizsoft.com>
*/
(function ($) {
'use strict';
var sprintf = $.fn.bootstrapTable.utils.sprintf;
$.extend($.fn.bootstrapTable.defaults, {
showJumpto: false,
exportOptions: {}
});
$.extend($.fn.bootstrapTable.locales, {
formatJumpto: function () {
return 'GO';
}
});
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_initPagination = BootstrapTable.prototype.initPagination;
BootstrapTable.prototype.initPagination = function () {
_initPagination.apply(this, Array.prototype.slice.apply(arguments));
if (this.options.showJumpto) {
var that = this,
$pageGroup = this.$pagination.find('ul.pagination'),
$jumpto = $pageGroup.find('li.jumpto');
if (!$jumpto.length) {
$jumpto = $([
'<li class="jumpto">',
'<input type="text" class="form-control">',
'<button class="btn' +
sprintf(' btn-%s', this.options.buttonsClass) +
sprintf(' btn-%s', this.options.iconSize) +
'" title="' + this.options.formatJumpto() + '" ' +
' type="button">'+this.options.formatJumpto(),
'</button>',
'</li>'].join('')).appendTo($pageGroup);
$jumpto.find('button').click(function () {
that.selectPage(parseInt($jumpto.find('input').val()));
});
}
}
};
})(jQuery);

View File

@ -0,0 +1,21 @@
(The MIT License)
Copyright (c) 2019 doug-the-guy <badlydrawnsun@yahoo.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,92 @@
# Bootstrap Table Pipelining
Use Plugin: [bootstrap-table-pipeline]
This plugin enables client side data caching for server side requests which will
eliminate the need to issue a new request every page change. This will allow
for a performance balance for a large data set between returning all data at once
(client side paging) and a new server side request (server side paging).
There are two new options:
- usePipeline: enables this feature
- pipelineSize: the size of each cache window
The size of the pipeline must be evenly divisible by the current page size. This is
assured by rounding up to the nearest evenly divisible value. For example, if
the pipeline size is 4990 and the current page size is 25, then pipeline size will
be dynamically set to 5000.
The cache windows are computed based on the pipeline size and the total number of rows
returned by the server side query. For example, with pipeline size 500 and total rows
1300, the cache windows will be:
[{'lower': 0, 'upper': 499}, {'lower': 500, 'upper': 999}, {'lower': 1000, 'upper': 1499}]
Using the limit (i.e. the pipelineSize) and offset parameters, the server side request
**MUST** return only the data in the requested cache window **AND** the total number of rows.
To wit, the server side code must use the offset and limit parameters to prepare the response
data.
On a page change, the new offset is checked if it is within the current cache window. If so,
the requested page data is returned from the cached data set. Otherwise, a new server side
request will be issued for the new cache window.
The current cached data is only invalidated on these events:
- sorting
- searching
- page size change
- page change moves into a new cache window
There are two new events:
- cached-data-hit.bs.table: issued when cached data is used on a page change
- cached-data-reset.bs.table: issued when the cached data is invalidated and new server side request is issued
## Features
* Created with Bootstrap 4
## Usage
```
# assumed import of bootstrap and bootstrap-table assets
<script src="/path/to/bootstrap-table-pipeline.js"></script>
...
<table id="pipeline_table"
class="table table-striped"
data-method='post'
data-use-pipeline="true"
data-pipeline-size="5000"
data-pagination="true"
data-side-pagination="server"
data-page-size="50">
<thead><tr>
<th data-field="type" data-sortable="true">Type</th>
<th data-field="value" data-sortable="true">Value</th>
<th data-field="date" data-sortable="true">Date</th>
</tr></thead>
</table>
```
## Options
### usePipeline
* type: Boolean
* description: Set true to enable pipelining
* default: `false`
## pipelineSize
* type: Integer
* description: Size of each cache window. Must be greater than 0
* default: `1000`
## Events
### onCachedDataHit(cached-data-hit.bs.table)
* Fires when paging was able to use the locally cached data.
### onCachedDataReset(cached-data-reset.bs.table)
* Fires when the locally cached data needed to be reset (i.e. on sorting, searching, page size change or paged out of current cache window)

View File

@ -0,0 +1,330 @@
/**
* @author doug-the-guy
* @version v1.0.0
*
* Boostrap Table Pipeline
* -----------------------
*
* This plugin enables client side data caching for server side requests which will
* eliminate the need to issue a new request every page change. This will allow
* for a performance balance for a large data set between returning all data at once
* (client side paging) and a new server side request (server side paging).
*
* There are two new options:
* - usePipeline: enables this feature
* - pipelineSize: the size of each cache window
*
* The size of the pipeline must be evenly divisible by the current page size. This is
* assured by rounding up to the nearest evenly divisible value. For example, if
* the pipeline size is 4990 and the current page size is 25, then pipeline size will
* be dynamically set to 5000.
*
* The cache windows are computed based on the pipeline size and the total number of rows
* returned by the server side query. For example, with pipeline size 500 and total rows
* 1300, the cache windows will be:
*
* [{'lower': 0, 'upper': 499}, {'lower': 500, 'upper': 999}, {'lower': 1000, 'upper': 1499}]
*
* Using the limit (i.e. the pipelineSize) and offset parameters, the server side request
* **MUST** return only the data in the requested cache window **AND** the total number of rows.
* To wit, the server side code must use the offset and limit parameters to prepare the response
* data.
*
* On a page change, the new offset is checked if it is within the current cache window. If so,
* the requested page data is returned from the cached data set. Otherwise, a new server side
* request will be issued for the new cache window.
*
* The current cached data is only invalidated on these events:
* * sorting
* * searching
* * page size change
* * page change moves into a new cache window
*
* There are two new events:
* - cached-data-hit.bs.table: issued when cached data is used on a page change
* - cached-data-reset.bs.table: issued when the cached data is invalidated and a
* new server side request is issued
*
**/
(function ($) {
'use strict';
var Utils = $.fn.bootstrapTable.utils;
$.extend($.fn.bootstrapTable.defaults, {
usePipeline: false,
pipelineSize: 1000,
onCachedDataHit: function(data) {
return false;
},
onCachedDataReset: function(data){
return false;
}
});
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
'cached-data-hit.bs.table': 'onCachedDataHit',
'cached-data-reset.bs.table': 'onCachedDataReset'
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_init = BootstrapTable.prototype.init,
_initServer = BootstrapTable.prototype.initServer,
_onSearch = BootstrapTable.prototype.onSearch,
_onSort = BootstrapTable.prototype.onSort,
_onPageListChange = BootstrapTable.prototype.onPageListChange;
BootstrapTable.prototype.init = function () {
// needs to be called before initServer()
this.initPipeline();
_init.apply(this, Array.prototype.slice.apply(arguments));
};
BootstrapTable.prototype.initPipeline = function() {
this.cacheRequestJSON = {};
this.cacheWindows = [];
this.currWindow = 0;
this.resetCache = true;
};
BootstrapTable.prototype.onSearch = function(event) {
/* force a cache reset on search */
if (this.options.usePipeline) {
this.resetCache = true;
}
_onSearch.apply(this, Array.prototype.slice.apply(arguments));
};
BootstrapTable.prototype.onSort = function(event) {
/* force a cache reset on sort */
if (this.options.usePipeline) {
this.resetCache = true;
}
_onSort.apply(this, Array.prototype.slice.apply(arguments));
};
BootstrapTable.prototype.onPageListChange = function (event) {
/* rebuild cache window on page size change */
var target = $(event.currentTarget);
var newPageSize = parseInt(target.text());
this.options.pipelineSize = this.calculatePipelineSize(this.options.pipelineSize, newPageSize);
this.resetCache = true;
_onPageListChange.apply(this, Array.prototype.slice.apply(arguments));
};
BootstrapTable.prototype.calculatePipelineSize = function(pipelineSize, pageSize) {
/* calculate pipeline size by rounding up to the nearest value evenly divisible
* by the pageSize */
if(pageSize == 0) return 0;
return Math.ceil(pipelineSize/pageSize) * pageSize;
};
BootstrapTable.prototype.setCacheWindows = function() {
/* set cache windows based on the total number of rows returned by server side
* request and the pipelineSize */
this.cacheWindows = [];
var numWindows = this.options.totalRows / this.options.pipelineSize;
for(var i = 0; i <= numWindows; i++){
var b = i * this.options.pipelineSize;
this.cacheWindows[i] = {'lower': b, 'upper': b + this.options.pipelineSize - 1};
}
};
BootstrapTable.prototype.setCurrWindow = function(offset) {
/* set the current cache window index, based on where the current offset falls */
this.currWindow = 0;
for(var i = 0; i < this.cacheWindows.length; i++){
if(this.cacheWindows[i].lower <= offset && offset <= this.cacheWindows[i].upper){
this.currWindow = i;
break;
}
}
};
BootstrapTable.prototype.drawFromCache = function(offset, limit) {
/* draw rows from the cache using offset and limit */
var res = $.extend(true, {}, this.cacheRequestJSON);
var drawStart = offset - this.cacheWindows[this.currWindow].lower;
var drawEnd = drawStart + limit;
res.rows = res.rows.slice(drawStart, drawEnd);
return res;
};
BootstrapTable.prototype.initServer = function(silent, query, url){
/* determine if requested data is in cache (on paging) or if
* a new ajax request needs to be issued (sorting, searching, paging
* moving outside of cached data, page size change)
* initial version of this extension will entirely override base initServer
**/
var data = {};
var index = this.header.fields.indexOf(this.options.sortName);
var params = {
searchText: this.searchText,
sortName: this.options.sortName,
sortOrder: this.options.sortOrder
};
var request = null;
if (this.header.sortNames[index]) {
params.sortName = this.header.sortNames[index];
}
if (this.options.pagination && this.options.sidePagination === 'server') {
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;
}
var useAjax = true;
if (this.options.queryParamsType === 'limit') {
params = {
searchText: params.searchText,
sortName: params.sortName,
sortOrder: params.sortOrder
}
if (this.options.pagination && this.options.sidePagination === 'server') {
params.limit = this.options.pageSize === this.options.formatAllRows() ? this.options.totalRows : this.options.pageSize;
params.offset = (this.options.pageSize === this.options.formatAllRows() ? this.options.totalRows : this.options.pageSize) * (this.options.pageNumber - 1);
if (this.options.usePipeline) {
// if cacheWindows is empty, this is the initial request
if(!this.cacheWindows.length){
useAjax = true;
params.drawOffset = params.offset;
// cache exists: determine if the page request is entirely within the current cached window
} else {
var w = this.cacheWindows[this.currWindow];
// case 1: reset cache but stay within current window (e.g. column sort)
// case 2: move outside of the current window (e.g. search or paging)
// since each cache window is aligned with the current page size
// checking if params.offset is outside the current window is sufficient.
// need to requery for preceding or succeeding cache window
// also handle case
if(this.resetCache || (params.offset < w.lower || params.offset > w.upper)){
useAjax = true;
this.setCurrWindow(params.offset);
// store the relative offset for drawing the page data afterwards
params.drawOffset = params.offset;
// now set params.offset to the lower bound of the new cache window
// the server will return that whole cache window
params.offset = this.cacheWindows[this.currWindow].lower;
// within current cache window
} else {
useAjax = false;
}
}
} else {
if (params.limit === 0) {
delete params.limit;
}
}
}
}
// force an ajax call - this is on search, sort or page size change
if (this.resetCache) {
useAjax = true;
this.resetCache = false;
}
if(this.options.usePipeline && useAjax) {
/* in this scenario limit is used on the server to get the cache window
* and drawLimit is used to get the page data afterwards */
params.drawLimit = params.limit;
params.limit = this.options.pipelineSize;
}
// cached results can be used
if(!useAjax) {
var res = this.drawFromCache(params.offset, params.limit);
this.load(res);
this.trigger('load-success', res);
this.trigger('cached-data-hit', res);
return;
}
// cached results can't be used
// continue base initServer code
if (!($.isEmptyObject(this.filterColumnsPartial))) {
params.filter = JSON.stringify(this.filterColumnsPartial, null);
}
data = Utils.calculateObjectValue(this.options, this.options.queryParams, [params], data);
$.extend(data, query || {});
// false to stop request
if (data === false) {
return;
}
if (!silent) {
this.$tableLoading.show();
}
var self = this;
request = $.extend({}, Utils.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 = Utils.calculateObjectValue(self.options, self.options.responseHandler, [res], res);
// cache results if using pipelining
if(self.options.usePipeline){
// store entire request in cache
self.cacheRequestJSON = $.extend(true, {}, res);
// this gets set in load() also but needs to be set before
// setting cacheWindows
self.options.totalRows = res[self.options.totalField];
// if this is a search, potentially less results will be returned
// so cache windows need to be rebuilt. Otherwise it
// will come out the same
self.setCacheWindows();
self.setCurrWindow(params.drawOffset);
// just load data for the page
res = self.drawFromCache(params.drawOffset, params.drawLimit);
self.trigger('cached-data-reset', res);
}
self.load(res);
self.trigger('load-success', res);
if (!silent) self.$tableLoading.hide();
},
error: function(res){
var data = [];
if (self.options.sidePagination === 'server') {
data = {};
data[self.options.totalField] = 0;
data[self.options.dataField] = [];
}
self.load(data);
self.trigger('load-error', res.status, res);
if (!silent) self.$tableLoading.hide();
}
});
if (this.options.ajax) {
Utils.calculateObjectValue(this, this.options.ajax, [request], null);
} else {
if (this._xhr && this._xhr.readyState !== 4) {
this._xhr.abort();
}
this._xhr = $.ajax(request);
}
}
$.fn.bootstrapTable.methods.push();
})(jQuery);

View File

@ -0,0 +1,18 @@
{
"name": "Pipeline",
"version": "1.0.0",
"description": "Plugin to support a hybrid approach to server/client side paging.",
"url": "",
"example": "#",
"plugins": [{
"name": "bootstrap-table-pipeline",
"url": ""
}],
"author": {
"name": "doug-the-guy",
"image": ""
}
}

View File

@ -0,0 +1,149 @@
(function ($) {
'use strict';
var sprintf = $.fn.bootstrapTable.utils.sprintf;
function printPageBuilderDefault(table) {
return '<html><head>' +
'<style type="text/css" media="print">' +
' @page { size: auto; margin: 25px 0 25px 0; }' +
'</style>' +
'<style type="text/css" media="all">' +
'table{border-collapse: collapse; font-size: 12px; }\n' +
'table, th, td {border: 1px solid grey}\n' +
'th, td {text-align: center; vertical-align: middle;}\n' +
'p {font-weight: bold; margin-left:20px }\n' +
'table { width:94%; margin-left:3%; margin-right:3%}\n' +
'div.bs-table-print { text-align:center;}\n' +
'</style></head><title>Print Table</title><body>' +
'<p>Printed on: ' + new Date + ' </p>' +
'<div class="bs-table-print">' + table + "</div></body></html>";
}
$.extend($.fn.bootstrapTable.defaults, {
showPrint: false,
printAsFilteredAndSortedOnUI: true, //boolean, when true - print table as sorted and filtered on UI.
//Please note that if true is set, along with explicit predefined print options for filtering and sorting (printFilter, printSortOrder, printSortColumn)- then they will be applied on data already filtered and sorted by UI controls.
//For printing data as filtered and sorted on UI - do not set these 3 options:printFilter, printSortOrder, printSortColumn
printSortColumn: undefined , //String, set column field name to be sorted by
printSortOrder: 'asc', //String: 'asc' , 'desc' - relevant only if printSortColumn is set
printPageBuilder: function(table){return printPageBuilderDefault(table)} // function, receive html <table> element as string, returns html string for printing. by default delegates to function printPageBuilderDefault(table). used for styling and adding header or footer
});
$.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {
printFilter: undefined, //set value to filter by in print page
printIgnore: false, //boolean, set true to ignore this column in the print page
printFormatter:undefined //function(value, row, index), formats the cell value for this column in the printed table. Function behaviour is similar to the 'formatter' column option
});
$.extend($.fn.bootstrapTable.defaults.icons, {
print: 'glyphicon-print icon-share'
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_initToolbar = BootstrapTable.prototype.initToolbar;
BootstrapTable.prototype.initToolbar = function () {
this.showToolbar = this.showToolbar || this.options.showPrint;
_initToolbar.apply(this, Array.prototype.slice.apply(arguments));
if (this.options.showPrint) {
var that = this,
$btnGroup = this.$toolbar.find('>.btn-group'),
$print = $btnGroup.find('button.bs-print');
if (!$print.length) {
$print = $([
'<button class="bs-print btn btn-default' + sprintf(' btn-%s"', this.options.iconSize) + ' name="print" title="print" type="button">',
sprintf('<i class="%s %s"></i> ', this.options.iconsPrefix, this.options.icons.print),
'</button>'].join('')).appendTo($btnGroup);
$print.click(function () {
function formatValue(row, i, column ) {
var value = row[column.field];
if (typeof column.printFormatter === 'function') {
return column.printFormatter.apply(column, [value, row, i]);
}
else {
return typeof value === 'undefined' ? "-" : value;
}
}
function buildTable(data, columnsArray) {
var html = ['<table><thead>'];
for (var k = 0; k < columnsArray.length; k++) {
var columns = columnsArray[k];
html.push('<tr>');
for (var h = 0; h < columns.length; h++) {
if (!columns[h].printIgnore) {
html.push(
'<th',
sprintf(' rowspan="%s"', columns[h].rowspan),
sprintf(' colspan="%s"', columns[h].colspan),
sprintf('>%s</th>', columns[h].title)
);
}
}
html.push('</tr>');
}
html.push('</thead><tbody>');
for (var i = 0; i < data.length; i++) {
html.push('<tr>');
for(var l = 0; l < columnsArray.length; l++) {
var columns = columnsArray[l];
for(var j = 0; j < columns.length; j++) {
if (!columns[j].printIgnore && columns[j].field) {
html.push('<td>', formatValue(data[i], i, columns[j]), '</td>');
}
}
}
html.push('</tr>');
}
html.push('</tbody></table>');
return html.join('');
}
function sortRows(data,colName,sortOrder) {
if(!colName){
return data;
}
var reverse = sortOrder != 'asc';
reverse = -((+reverse) || -1);
return data.sort(function (a, b) {
return reverse * (a[colName].localeCompare(b[colName]));
});
}
function filterRow(row,filters) {
for (var index = 0; index < filters.length; ++index) {
if(row[filters[index].colName]!=filters[index].value) {
return false;
}
}
return true;
}
function filterRows(data,filters) {
return data.filter(function (row) {
return filterRow(row,filters)
});
}
function getColumnFilters(columns) {
return !columns || !columns[0] ? [] : columns[0].filter(function (col) {
return col.printFilter;
}).map(function (col) {
return {colName:col.field, value:col.printFilter};
});
}
var doPrint = function (data) {
data=filterRows(data,getColumnFilters(that.options.columns));
data=sortRows(data,that.options.printSortColumn,that.options.printSortOrder);
var table=buildTable(data,that.options.columns);
var newWin = window.open("");
newWin.document.write(that.options.printPageBuilder.call(this, table));
newWin.print();
newWin.close();
};
doPrint(that.options.printAsFilteredAndSortedOnUI? that.getData() : that.options.data.slice(0));
});
}
}
};
})(jQuery);

View File

@ -0,0 +1,181 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @version: v1.1.0
*/
!function ($) {
'use strict';
//From MDN site, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
var filterFn = function () {
if (!Array.prototype.filter) {
Array.prototype.filter = function(fun/*, thisArg*/) {
'use strict';
if (this === void 0 || this === null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function') {
throw new TypeError();
}
var res = [];
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) {
if (i in t) {
var val = t[i];
// NOTE: Technically this should Object.defineProperty at
// the next index, as push can be affected by
// properties on Object.prototype and Array.prototype.
// But that method's new, and collisions should be
// rare, so use the more-compatible alternative.
if (fun.call(thisArg, val, i, t)) {
res.push(val);
}
}
}
return res;
};
}
};
$.extend($.fn.bootstrapTable.defaults, {
reorderableColumns: false,
maxMovingRows: 10,
onReorderColumn: function (headerFields) {
return false;
},
dragaccept: null
});
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
'reorder-column.bs.table': 'onReorderColumn'
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_initHeader = BootstrapTable.prototype.initHeader,
_toggleColumn = BootstrapTable.prototype.toggleColumn,
_toggleView = BootstrapTable.prototype.toggleView,
_resetView = BootstrapTable.prototype.resetView;
BootstrapTable.prototype.initHeader = function () {
_initHeader.apply(this, Array.prototype.slice.apply(arguments));
if (!this.options.reorderableColumns) {
return;
}
this.makeRowsReorderable();
};
BootstrapTable.prototype.toggleColumn = function () {
_toggleColumn.apply(this, Array.prototype.slice.apply(arguments));
if (!this.options.reorderableColumns) {
return;
}
this.makeRowsReorderable();
};
BootstrapTable.prototype.toggleView = function () {
_toggleView.apply(this, Array.prototype.slice.apply(arguments));
if (!this.options.reorderableColumns) {
return;
}
if (this.options.cardView) {
return;
}
this.makeRowsReorderable();
};
BootstrapTable.prototype.resetView = function () {
_resetView.apply(this, Array.prototype.slice.apply(arguments));
if (!this.options.reorderableColumns) {
return;
}
this.makeRowsReorderable();
};
BootstrapTable.prototype.makeRowsReorderable = function () {
var that = this;
try {
$(this.$el).dragtable('destroy');
} catch (e) {}
$(this.$el).dragtable({
maxMovingRows: that.options.maxMovingRows,
dragaccept: that.options.dragaccept,
clickDelay:200,
beforeStop: function() {
var ths = [],
formatters = [],
columns = [],
columnsHidden = [],
columnIndex = -1,
optionsColumns = [];
that.$header.find('th').each(function (i) {
ths.push($(this).data('field'));
formatters.push($(this).data('formatter'));
});
//Exist columns not shown
if (ths.length < that.columns.length) {
columnsHidden = $.grep(that.columns, function (column) {
return !column.visible;
});
for (var i = 0; i < columnsHidden.length; i++) {
ths.push(columnsHidden[i].field);
formatters.push(columnsHidden[i].formatter);
}
}
for (var i = 0; i < this.length; i++ ) {
columnIndex = that.fieldsColumnsIndex[ths[i]];
if (columnIndex !== -1) {
that.columns[columnIndex].fieldIndex = i;
columns.push(that.columns[columnIndex]);
that.columns.splice(columnIndex, 1);
}
}
that.columns = that.columns.concat(columns);
filterFn(); //Support <IE9
$.each(that.columns, function(i, column) {
var found = false,
field = column.field;
that.options.columns[0].filter(function(item) {
if(!found && item["field"] == field) {
optionsColumns.push(item);
found = true;
return false;
} else
return true;
})
});
that.options.columns[0] = optionsColumns;
that.header.fields = ths;
that.header.formatters = formatters;
that.initHeader();
that.initToolbar();
that.initBody();
that.resetView();
that.trigger('reorder-column', ths);
}
});
};
}(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "Reorder Columns",
"version": "1.1.0",
"description": "Plugin to support the reordering columns feature.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/reorder-columns",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/reorder-columns.html",
"plugins": [{
"name": "bootstrap-table-reorder-columns",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/reorder-columns"
}],
"author": {
"name": "djhvscf",
"image": "https://avatars1.githubusercontent.com/u/4496763"
}
}

View File

@ -0,0 +1,14 @@
.reorder_rows_onDragClass td {
background-color: #eee;
-webkit-box-shadow: 11px 5px 12px 2px #333, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;
-webkit-box-shadow: 6px 3px 5px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;
-moz-box-shadow: 6px 4px 5px 1px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;
-box-shadow: 6px 4px 5px 1px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;
}
.reorder_rows_onDragClass td:last-child {
-webkit-box-shadow: 8px 7px 12px 0 #333, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;
-webkit-box-shadow: 1px 8px 6px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset;
-moz-box-shadow: 0 9px 4px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset, -1px 0 0 #ccc inset;
-box-shadow: 0 9px 4px -4px #555, 0 1px 0 #ccc inset, 0 -1px 0 #ccc inset, -1px 0 0 #ccc inset;
}

View File

@ -0,0 +1,118 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @version: v1.0.1
*/
(function ($) {
'use strict';
var isSearch = false;
var rowAttr = function (row, index) {
return {
id: 'customId_' + index
};
};
$.extend($.fn.bootstrapTable.defaults, {
reorderableRows: false,
onDragStyle: null,
onDropStyle: null,
onDragClass: "reorder_rows_onDragClass",
dragHandle: null,
useRowAttrFunc: false,
onReorderRowsDrag: function (table, row) {
return false;
},
onReorderRowsDrop: function (table, row) {
return false;
},
onReorderRow: function (newData) {
return false;
}
});
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
'reorder-row.bs.table': 'onReorderRow'
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_init = BootstrapTable.prototype.init,
_initSearch = BootstrapTable.prototype.initSearch;
BootstrapTable.prototype.init = function () {
if (!this.options.reorderableRows) {
_init.apply(this, Array.prototype.slice.apply(arguments));
return;
}
var that = this;
if (this.options.useRowAttrFunc) {
this.options.rowAttributes = rowAttr;
}
var onPostBody = this.options.onPostBody;
this.options.onPostBody = function () {
setTimeout(function () {
that.makeRowsReorderable();
onPostBody.apply();
}, 1);
};
_init.apply(this, Array.prototype.slice.apply(arguments));
};
BootstrapTable.prototype.initSearch = function () {
_initSearch.apply(this, Array.prototype.slice.apply(arguments));
if (!this.options.reorderableRows) {
return;
}
//Known issue after search if you reorder the rows the data is not display properly
//isSearch = true;
};
BootstrapTable.prototype.makeRowsReorderable = function () {
if (this.options.cardView) {
return;
}
var that = this;
this.$el.tableDnD({
onDragStyle: that.options.onDragStyle,
onDropStyle: that.options.onDropStyle,
onDragClass: that.options.onDragClass,
onDrop: that.onDrop,
onDragStart: that.options.onReorderRowsDrag,
dragHandle: that.options.dragHandle
});
};
BootstrapTable.prototype.onDrop = function (table, droppedRow) {
var tableBs = $(table),
tableBsData = tableBs.data('bootstrap.table'),
tableBsOptions = tableBs.data('bootstrap.table').options,
row = null,
newData = [];
for (var i = 0; i < table.tBodies[0].rows.length; i++) {
row = $(table.tBodies[0].rows[i]);
newData.push(tableBsOptions.data[row.data('index')]);
row.data('index', i).attr('data-index', i);
}
tableBsOptions.data = tableBsOptions.data.slice(0, tableBsData.pageFrom - 1)
.concat(newData)
.concat(tableBsOptions.data.slice(tableBsData.pageTo));
//Call the user defined function
tableBsOptions.onReorderRowsDrop.apply(table, [table, droppedRow]);
//Call the event reorder-row
tableBsData.trigger('reorder-row', newData);
};
})(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "Reorder Rows",
"version": "1.0.0",
"description": "Plugin to support the reordering rows feature.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/reorder-rows",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/reorder-rows.html",
"plugins": [{
"name": "bootstrap-table-reorder-rows",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/reorder-rows"
}],
"author": {
"name": "djhvscf",
"image": "https://avatars1.githubusercontent.com/u/4496763"
}
}

View File

@ -0,0 +1,72 @@
/**
* @author: Dennis Hernández
* @webSite: http://djhvscf.github.io/Blog
* @version: v2.0.0
*/
(function($) {
"use strict";
var initResizable = function(that) {
if (that.options.resizable && !that.options.cardView && !isInit(that)) {
that.$el.resizableColumns();
}
};
var reInitResizable = function(that) {
destroy(that);
initResizable(that);
};
var destroy = function(that) {
if (isInit(that)) {
that.$el.data("resizableColumns").destroy();
}
};
var isInit = function(that) {
return that.$el.data("resizableColumns") !== undefined;
};
$.extend($.fn.bootstrapTable.defaults, {
resizable: false
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_initBody = BootstrapTable.prototype.initBody,
_toggleView = BootstrapTable.prototype.toggleView,
_resetView = BootstrapTable.prototype.resetView;
BootstrapTable.prototype.initBody = function() {
var that = this;
_initBody.apply(this, Array.prototype.slice.apply(arguments));
that.$el
.off("column-switch.bs.table, page-change.bs.table")
.on("column-switch.bs.table, page-change.bs.table", function() {
reInitResizable(that);
});
};
BootstrapTable.prototype.toggleView = function() {
_toggleView.apply(this, Array.prototype.slice.apply(arguments));
if (this.options.resizable && this.options.cardView) {
//Destroy the plugin
destroy(this);
}
};
BootstrapTable.prototype.resetView = function() {
var that = this;
_resetView.apply(this, Array.prototype.slice.apply(arguments));
if (this.options.resizable) {
// because in fitHeader function, we use setTimeout(func, 100);
setTimeout(function() {
initResizable(that);
}, 100);
}
};
})(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "Resizable",
"version": "1.1.0",
"description": "Plugin to support the resizable feature.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/resizable",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/resizable.html",
"plugins": [{
"name": "bootstrap-table-resizable",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/resizable"
}],
"author": {
"name": "djhvscf",
"image": "https://avatars1.githubusercontent.com/u/4496763"
}
}

View File

@ -0,0 +1,332 @@
/**
* @author: Jewway
* @version: v1.1.1
*/
! function ($) {
'use strict';
function getCurrentHeader(that) {
var header = that.$header;
if (that.options.height) {
header = that.$tableHeader;
}
return header;
}
function initFilterValues(that) {
if (!$.isEmptyObject(that.filterColumnsPartial)) {
var $header = getCurrentHeader(that);
$.each(that.columns, function (idx, column) {
var value = that.filterColumnsPartial[column.field];
if (column.filter) {
if (column.filter.setFilterValue) {
var $filter = $header.find('[data-field=' + column.field + '] .filter');
column.filter.setFilterValue($filter, column.field, value);
} else {
var $ele = $header.find('[data-filter-field=' + column.field + ']');
switch (column.filter.type) {
case 'input':
$ele.val(value);
case 'select':
$ele.val(value).trigger('change');
}
}
}
});
}
}
function createFilter(that, header) {
var enableFilter = false,
isVisible,
html,
timeoutId = 0;
$.each(that.columns, function (i, column) {
isVisible = 'hidden';
html = null;
if (!column.visible) {
return;
}
if (!column.filter) {
html = $('<div class="no-filter"></div>');
} else {
var filterClass = column.filter.class ? ' ' + column.filter.class : '';
html = $('<div style="margin: 0px 2px 2px 2px;" class="filter' + filterClass + '">');
if (column.searchable) {
enableFilter = true;
isVisible = 'visible'
}
if (column.filter.template) {
html.append(column.filter.template(that, column, isVisible));
} else {
var $filter = $(that.options.filterTemplate[column.filter.type.toLowerCase()](that, column, isVisible));
switch (column.filter.type) {
case 'input':
var cpLock = true;
$filter.off('compositionstart').on('compositionstart', function (event) {
cpLock = false;
});
$filter.off('compositionend').on('compositionend', function (event) {
cpLock = true;
var $input = $(this);
clearTimeout(timeoutId);
timeoutId = setTimeout(function () {
that.onColumnSearch(event, column.field, $input.val());
}, that.options.searchTimeOut);
});
$filter.off('keyup').on('keyup', function (event) {
if (cpLock) {
var $input = $(this);
clearTimeout(timeoutId);
timeoutId = setTimeout(function () {
that.onColumnSearch(event, column.field, $input.val());
}, that.options.searchTimeOut);
}
});
$filter.off('mouseup').on('mouseup', function (event) {
var $input = $(this),
oldValue = $input.val();
if (oldValue === "") {
return;
}
setTimeout(function () {
var newValue = $input.val();
if (newValue === "") {
clearTimeout(timeoutId);
timeoutId = setTimeout(function () {
that.onColumnSearch(event, column.field, newValue);
}, that.options.searchTimeOut);
}
}, 1);
});
break;
case 'select':
$filter.on('select2:select', function (event) {
that.onColumnSearch(event, column.field, $(this).val());
});
$filter.on("select2:unselecting", function (event) {
var $select2 = $(this);
event.preventDefault();
$select2.val(null).trigger('change');
that.searchText = undefined;
that.onColumnSearch(event, column.field, $select2.val());
});
break;
}
html.append($filter);
}
}
$.each(header.children().children(), function (i, tr) {
tr = $(tr);
if (tr.data('field') === column.field) {
tr.find('.fht-cell').append(html);
return false;
}
});
});
if (!enableFilter) {
header.find('.filter').hide();
}
}
function initSelect2(that) {
var $header = getCurrentHeader(that);
$.each(that.columns, function (idx, column) {
if (column.filter && column.filter.type === 'select') {
var $selectEle = $header.find('select[data-filter-field="' + column.field + '"]');
if ($selectEle.length > 0 && !$selectEle.data().select2) {
var select2Opts = {
placeholder: "",
allowClear: true,
data: column.filter.data,
dropdownParent: that.$el.closest(".bootstrap-table")
};
$selectEle.select2(select2Opts);
}
}
});
}
$.extend($.fn.bootstrapTable.defaults, {
filter: false,
filterValues: {},
filterTemplate: {
input: function (instance, column, isVisible) {
return '<input type="text" class="form-control" data-filter-field="' + column.field + '" style="width: 100%; visibility:' + isVisible + '">';
},
select: function (instance, column, isVisible) {
return '<select data-filter-field="' + column.field + '" style="width: 100%; visibility:' + isVisible + '"></select>';
}
},
onColumnSearch: function (field, text) {
return false;
}
});
$.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {
filter: undefined
});
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
'column-search.bs.table': 'onColumnSearch'
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_init = BootstrapTable.prototype.init,
_initHeader = BootstrapTable.prototype.initHeader,
_initSearch = BootstrapTable.prototype.initSearch;
BootstrapTable.prototype.init = function () {
//Make sure that the filtercontrol option is set
if (this.options.filter) {
var that = this;
if (that.options.filterTemplate) {
that.options.filterTemplate = $.extend({}, $.fn.bootstrapTable.defaults.filterTemplate, that.options.filterTemplate);
}
if (!$.isEmptyObject(that.options.filterValues)) {
that.filterColumnsPartial = that.options.filterValues;
that.options.filterValues = {};
}
this.$el.on('reset-view.bs.table', function () {
//Create controls on $tableHeader if the height is set
if (!that.options.height) {
return;
}
//Avoid recreate the controls
if (that.$tableHeader.find('select').length > 0 || that.$tableHeader.find('input').length > 0) {
return;
}
createFilter(that, that.$tableHeader);
}).on('post-header.bs.table', function () {
var timeoutId = 0;
initSelect2(that);
clearTimeout(timeoutId);
timeoutId = setTimeout(function () {
initFilterValues(that);
}, that.options.searchTimeOut - 1000);
}).on('column-switch.bs.table', function (field, checked) {
initFilterValues(that);
});
}
_init.apply(this, Array.prototype.slice.apply(arguments));
};
BootstrapTable.prototype.initHeader = function () {
_initHeader.apply(this, Array.prototype.slice.apply(arguments));
if (this.options.filter) {
createFilter(this, this.$header);
}
};
BootstrapTable.prototype.initSearch = function () {
var that = this,
filterValues = that.filterColumnsPartial;
// Filter for client
if (that.options.sidePagination === 'client') {
this.data = $.grep(this.data, function (row, idx) {
for (var field in filterValues) {
var column = that.columns[that.fieldsColumnsIndex[field]],
filterValue = filterValues[field].toLowerCase(),
rowValue = row[field];
rowValue = $.fn.bootstrapTable.utils.calculateObjectValue(
that.header,
that.header.formatters[$.inArray(field, that.header.fields)], [rowValue, row, idx], rowValue);
if (column.filterStrictSearch) {
if (!($.inArray(field, that.header.fields) !== -1 &&
(typeof rowValue === 'string' || typeof rowValue === 'number') &&
rowValue.toString().toLowerCase() === filterValue.toString().toLowerCase())) {
return false;
}
} else {
if (!($.inArray(field, that.header.fields) !== -1 &&
(typeof rowValue === 'string' || typeof rowValue === 'number') &&
(rowValue + '').toLowerCase().indexOf(filterValue) !== -1)) {
return false;
}
}
}
return true;
});
}
_initSearch.apply(this, Array.prototype.slice.apply(arguments));
};
BootstrapTable.prototype.onColumnSearch = function (event, field, value) {
if ($.isEmptyObject(this.filterColumnsPartial)) {
this.filterColumnsPartial = {};
}
if (value) {
this.filterColumnsPartial[field] = value;
} else {
delete this.filterColumnsPartial[field];
}
this.options.pageNumber = 1;
this.onSearch(event);
this.trigger('column-search', field, value);
};
BootstrapTable.prototype.setSelect2Data = function (field, data) {
var that = this,
$header = getCurrentHeader(that),
$selectEle = $header.find('select[data-filter-field=\"' + field + '\"]');
$selectEle.empty();
$selectEle.select2({
data: data,
placeholder: "",
allowClear: true,
dropdownParent: that.$el.closest(".bootstrap-table")
});
$.each(this.columns, function (idx, column) {
if (column.field === field) {
column.filter.data = data;
return false;
}
});
};
BootstrapTable.prototype.setFilterValues = function (values) {
this.filterColumnsPartial = values;
};
$.fn.bootstrapTable.methods.push('setSelect2Data');
$.fn.bootstrapTable.methods.push('setFilterValues');
}(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "Select2 Filter",
"version": "1.1.0",
"description": "Plugin to add select2 filter on the top of the columns in order to filter the data.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/select2-filter",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/select2-filter.html",
"plugins": [{
"name": "bootstrap-table-select2-filter",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/select2-filter"
}],
"author": {
"name": "Jewway",
"image": "https://avatars0.githubusercontent.com/u/3501899"
}
}

View File

@ -0,0 +1,22 @@
/**
* @author vincent loh <vincent.ml@gmail.com>
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
.fix-sticky {
position: fixed !important;
overflow: hidden;
z-index: 100;
}
.fix-sticky table thead {
background: #fff;
}
.fix-sticky table thead.thead-light {
background: #e9ecef;
}
.fix-sticky table thead.thead-light {
background: #212529;
}

View File

@ -0,0 +1,76 @@
/**
* @author vincent loh <vincent.ml@gmail.com>
* @update J Manuel Corona <jmcg92@gmail.com>
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
($ => {
const Utils = $.fn.bootstrapTable.utils
$.extend($.fn.bootstrapTable.defaults, {
stickyHeader: false,
stickyHeaderOffsetY: 0
})
const hiddenClass = Utils.bootstrapVersion === 4 ? 'd-none' : 'hidden'
$.BootstrapTable = class extends $.BootstrapTable {
initHeader (...args) {
super.initHeader(...args)
if (!this.options.stickyHeader) {
return
}
this.$el.before('<div class="sticky-header-container"></div>')
this.$el.before('<div class="sticky_anchor_begin"></div>')
this.$el.after('<div class="sticky_anchor_end"></div>')
this.$header.addClass('sticky-header')
// clone header just once, to be used as sticky header
// deep clone header, using source header affects tbody>td width
this.$stickyContainer = this.$tableBody.find('.sticky-header-container')
this.$stickyBegin = this.$tableBody.find('.sticky_anchor_begin')
this.$stickyEnd = this.$tableBody.find('.sticky_anchor_end')
this.$stickyHeader = this.$header.clone(true, true)
// render sticky on window scroll or resize
$(window).on('resize.sticky-header-table', () => this.renderStickyHeader())
$(window).on('scroll.sticky-header-table', () => this.renderStickyHeader())
this.$tableBody.off('scroll').on('scroll', () => this.matchPositionX())
}
renderStickyHeader () {
const top = $(window).scrollTop()
// top anchor scroll position, minus header height
const start = this.$stickyBegin.offset().top - this.options.stickyHeaderOffsetY
// bottom anchor scroll position, minus header height, minus sticky height
const end = this.$stickyEnd.offset().top - this.options.stickyHeaderOffsetY - this.$header.height()
// show sticky when top anchor touches header, and when bottom anchor not exceeded
if (top > start && top <= end) {
// ensure clone and source column widths are the same
this.$stickyHeader.find('tr:eq(0)').find('th').each((index, el) => {
$(el).css('min-width', this.$header.find('tr:eq(0)').find('th').eq(index).css('width'))
})
// match bootstrap table style
this.$stickyContainer.removeClass(hiddenClass).addClass('fix-sticky fixed-table-container')
// stick it in position
this.$stickyContainer.css('top', `${this.options.stickyHeaderOffsetY}px`)
// create scrollable container for header
this.$stickyTable = $('<table/>')
this.$stickyTable.addClass(this.options.classes)
// append cloned header to dom
this.$stickyContainer.html(this.$stickyTable.append(this.$stickyHeader))
// match clone and source header positions when left-right scroll
this.matchPositionX()
} else {
this.$stickyContainer.removeClass('fix-sticky').addClass(hiddenClass)
}
}
matchPositionX () {
this.$stickyContainer.scrollLeft(this.$tableBody.scrollLeft())
}
}
})(jQuery)

View File

@ -0,0 +1,17 @@
{
"name": "Sticky Header",
"version": "1.0.0",
"description": "An extension which provides a sticky header for table columns when scrolling on a long page and / or table. Works for tables with many columns and narrow width with horizontal scrollbars too.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/sticky-header",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/sticky-header.html",
"plugins": [{
"name": "bootstrap-table-sticky-header",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/sticky-header"
}],
"author": {
"name": "vinzloh",
"image": "https://avatars0.githubusercontent.com/u/5501845"
}
}

View File

@ -0,0 +1,228 @@
/**
* @author: aperez <aperez@datadec.es>
* @version: v2.0.0
*
* @update Dennis Hernández <http://djhvscf.github.io/Blog>
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
($ => {
const Utils = $.fn.bootstrapTable.utils
const bootstrap = {
3: {
icons: {
advancedSearchIcon: 'glyphicon-chevron-down'
},
html: {
modalHeader: `
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">%s</h4>
</div>
`
}
},
4: {
icons: {
advancedSearchIcon: 'fa-chevron-down'
},
html: {
modalHeader: `
<div class="modal-header">
<h4 class="modal-title">%s</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
`
}
}
}[Utils.bootstrapVersion]
$.extend($.fn.bootstrapTable.defaults, {
advancedSearch: false,
idForm: 'advancedSearch',
actionForm: '',
idTable: undefined,
onColumnAdvancedSearch (field, text) {
return false
}
})
$.extend($.fn.bootstrapTable.defaults.icons, {
advancedSearchIcon: bootstrap.icons.advancedSearchIcon
})
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
'column-advanced-search.bs.table': 'onColumnAdvancedSearch'
})
$.extend($.fn.bootstrapTable.locales, {
formatAdvancedSearch () {
return 'Advanced search'
},
formatAdvancedCloseButton () {
return 'Close'
}
})
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
$.BootstrapTable = class extends $.BootstrapTable {
initToolbar () {
const o = this.options
this.showToolbar = this.showToolbar ||
(o.search &&
o.advancedSearch &&
o.idTable)
super.initToolbar()
if (!o.search || !o.advancedSearch || !o.idTable) {
return
}
this.$toolbar.find('>.btn-group').append(`
<button class="btn btn-default${Utils.sprintf(' btn-%s', o.buttonsClass)}${Utils.sprintf(' btn-%s', o.iconSize)}"
type="button"
name="advancedSearch"
aria-label="advanced search"
title="${o.formatAdvancedSearch()}">
<i class="${o.iconsPrefix} ${o.icons.advancedSearchIcon}"></i>
</button>
`)
this.$toolbar.find('button[name="advancedSearch"]').off('click').on('click', () => this.showAvdSearch())
}
showAvdSearch () {
const o = this.options
if (!$(`#avdSearchModal_${o.idTable}`).hasClass('modal')) {
$('body').append(`
<div id="avdSearchModal_${o.idTable}" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xs">
<div class="modal-content">
${Utils.sprintf(bootstrap.html.modalHeader, o.formatAdvancedSearch())}
<div class="modal-body modal-body-custom">
<div class="container-fluid" id="avdSearchModalContent_${o.idTable}"
style="padding-right: 0px; padding-left: 0px;" >
</div>
</div>
<div class="modal-footer">
<button type="button" id="btnCloseAvd_${o.idTable}" class="btn btn-${o.buttonsClass}">
${o.formatAdvancedCloseButton()}
</button>
</div>
</div>
</div>
</div>
`)
let timeoutId = 0
$(`#avdSearchModalContent_${o.idTable}`).append(this.createFormAvd().join(''))
$(`#${o.idForm}`).off('keyup blur', 'input').on('keyup blur', 'input', e => {
if (o.sidePagination === 'server') {
this.onColumnAdvancedSearch(e)
} else {
clearTimeout(timeoutId)
timeoutId = setTimeout(() => {
this.onColumnAdvancedSearch(e)
}, o.searchTimeOut)
}
})
$(`#btnCloseAvd_${o.idTable}`).click(() => {
$(`#avdSearchModal_${o.idTable}`).modal('hide')
if (o.sidePagination === 'server') {
this.options.pageNumber = 1
this.updatePagination()
this.trigger('column-advanced-search', this.filterColumnsPartial)
}
})
$(`#avdSearchModal_${o.idTable}`).modal()
} else {
$(`#avdSearchModal_${o.idTable}`).modal()
}
}
createFormAvd () {
const o = this.options
const html = [`<form class="form-horizontal" id="${o.idForm}" action="${o.actionForm}">`]
for (const column of this.columns) {
if (!column.checkbox && column.visible && column.searchable) {
html.push(`
<div class="form-group row">
<label class="col-sm-4 control-label">${column.title}</label>
<div class="col-sm-6">
<input type="text" class="form-control input-md" name="${column.field}" placeholder="${column.title}" id="${column.field}">
</div>
</div>
`)
}
}
html.push('</form>')
return html
}
initSearch () {
super.initSearch()
if (!this.options.advancedSearch || this.options.sidePagination === 'server') {
return
}
const fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial
this.data = fp ? $.grep(this.data, (item, i) => {
for (const [key, v] of Object.entries(fp)) {
const fval = v.toLowerCase()
let value = item[key]
const index = this.header.fields.indexOf(key)
value = Utils.calculateObjectValue(this.header,
this.header.formatters[index], [value, item, i], value)
if (
!(index !== -1 &&
(typeof value === 'string' || typeof value === 'number') &&
(`${value}`).toLowerCase().includes(fval))
) {
return false
}
}
return true
}) : this.data
}
onColumnAdvancedSearch (e) {
const text = $.trim($(e.currentTarget).val())
const $field = $(e.currentTarget)[0].id
if ($.isEmptyObject(this.filterColumnsPartial)) {
this.filterColumnsPartial = {}
}
if (text) {
this.filterColumnsPartial[$field] = text
} else {
delete this.filterColumnsPartial[$field]
}
if (this.options.sidePagination !== 'server') {
this.options.pageNumber = 1
this.onSearch(e)
this.updatePagination()
this.trigger('column-advanced-search', $field, text)
}
}
}
})(jQuery)

View File

@ -0,0 +1,17 @@
{
"name": "Toolbar",
"version": "2.0.0",
"description": "Plugin to support the advanced search.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/toolbar",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/toolbar.html",
"plugins": [{
"name": "bootstrap-table-toolbar",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/toolbar"
}],
"author": {
"name": "djhvscf",
"image": "https://avatars1.githubusercontent.com/u/4496763"
}
}

View File

@ -0,0 +1 @@
.table:not(.table-condensed)>tbody>tr>td.treenode{padding-top:0;padding-bottom:0;border-bottom:solid #fff 1px}.table:not(.table-condensed)>tbody>tr:last-child>td.treenode{border-bottom:none}.treenode .text{float:left;display:block;padding-top:6px;padding-bottom:6px}.treenode .vertical,.treenode .vertical.last{float:left;display:block;width:1px;border-left:dashed silver 1px;height:38px;margin-left:8px}.treenode .vertical.last{height:15px}.treenode .space,.treenode .node{float:left;display:block;width:15px;height:5px;margin-top:15px}.treenode .node{border-top:dashed silver 1px}

View File

@ -0,0 +1,130 @@
/**
* @author: KingYang
* @webSite: https://github.com/kingyang
* @version: v1.0.0
*/
! function ($) {
'use strict';
$.extend($.fn.bootstrapTable.defaults, {
treeShowField: null,
idField: 'id',
parentIdField: 'pid',
treeVerticalcls: 'vertical',
treeVerticalLastcls: 'vertical last',
treeSpacecls: 'space',
treeNodecls: 'node',
treeCellcls: 'treenode',
treeTextcls: 'text',
onTreeFormatter: function (row) {
var that = this,
options = that.options,
level = row._level || 0,
plevel = row._parent && row._parent._level || 0,
paddings = [];
for (var i = 0; i < plevel; i++) {
paddings.push('<i class="' + options.treeVerticalcls + '"></i>');
paddings.push('<i class="' + options.treeSpacecls + '"></i>');
}
for (var i = plevel; i < level; i++) {
if (row._last && i === (level - 1)) {
paddings.push('<i class="' + options.treeVerticalLastcls + '"></i>');
} else {
paddings.push('<i class="' + options.treeVerticalcls + '"></i>');
}
paddings.push('<i class="' + options.treeNodecls + '"></i>');
}
return paddings.join('');
}, onGetNodes: function (row, data) {
var that = this;
var nodes = [];
$.each(data, function (i, item) {
if (row[that.options.idField] === item[that.options.parentIdField]) {
nodes.push(item);
}
});
return nodes;
},
onCheckLeaf: function (row, data) {
if (row.isLeaf !== undefined) {
return row.isLeaf;
}
return !row._nodes || !row._nodes.length;
}, onCheckRoot: function (row, data) {
var that = this;
return !row[that.options.parentIdField];
}
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_initRow = BootstrapTable.prototype.initRow,
_initHeader = BootstrapTable.prototype.initHeader;
BootstrapTable.prototype.initHeader = function () {
var that = this;
_initHeader.apply(that, Array.prototype.slice.apply(arguments));
var treeShowField = that.options.treeShowField;
if (treeShowField) {
$.each(this.header.fields, function (i, field) {
if (treeShowField === field) {
that.treeEnable = true;
var _formatter = that.header.formatters[i];
var _class = [that.options.treeCellcls];
if (that.header.classes[i]) {
_class.push(that.header.classes[i].split('"')[1] || '');
}
that.header.classes[i] = ' class="' + _class.join(' ') + '"';
that.header.formatters[i] = function (value, row, index) {
var colTree = [that.options.onTreeFormatter.apply(that, [row])];
colTree.push('<span class="' + that.options.treeTextcls + '">');
if (_formatter) {
colTree.push(_formatter.apply(this, Array.prototype.slice.apply(arguments)));
} else {
colTree.push(value);
}
colTree.push('</span>');
return colTree.join('');
};
return false;
}
});
}
};
var initNode = function (item, idx, data, parentDom) {
var that = this;
var nodes = that.options.onGetNodes.apply(that, [item, data]);
item._nodes = nodes;
parentDom.append(_initRow.apply(that, [item, idx, data, parentDom]));
var len = nodes.length - 1;
for (var i = 0; i <= len; i++) {
var node = nodes[i];
node._level = item._level + 1;
node._parent = item;
if (i === len)
node._last = 1;
initNode.apply(that, [node, $.inArray(node, data), data, parentDom]);
}
};
BootstrapTable.prototype.initRow = function (item, idx, data, parentDom) {
var that = this;
if (that.treeEnable) {
if (that.options.onCheckRoot.apply(that, [item, data])) {
if (item._level === undefined) {
item._level = 0;
}
initNode.apply(that, [item, idx, data, parentDom]);
return true;
}
return false;
}
return _initRow.apply(that, Array.prototype.slice.apply(arguments));
};
} (jQuery);

View File

@ -0,0 +1,43 @@
.table:not(.table-condensed) > tbody > tr > td.treenode {
padding-top: 0;
padding-bottom: 0;
border-bottom: solid #fff 1px;
}
.table:not(.table-condensed) > tbody > tr:last-child > td.treenode {
border-bottom: none;
}
.treenode {
.text {
float: left;
display: block;
padding-top: 6px;
padding-bottom: 6px;
}
.vertical,
.vertical.last {
float: left;
display: block;
width: 1px;
border-left: dashed silver 1px;
height: 38px;
margin-left: 8px;
}
.vertical.last {
height: 15px;
}
.space,
.node {
float: left;
display: block;
width: 15px;
height: 5px;
margin-top: 15px;
}
.node {
border-top: dashed silver 1px;
}
}

View File

@ -0,0 +1,17 @@
{
"name": "Tree column",
"version": "1.0.0",
"description": "Plugin to support display tree data column.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/tree-column",
"example": "http://issues.wenzhixin.net.cn/bootstrap-table/#extensions/tree-column.html",
"plugins": [{
"name": "bootstrap-table-reorder-rows",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/tree-column"
}],
"author": {
"name": "KingYang",
"image": "https://avatars3.githubusercontent.com/u/1540211"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

View File

@ -0,0 +1,111 @@
/**
* @author: YL
* @version: v1.0.0
*/
!function ($) {
'use strict';
$.extend($.fn.bootstrapTable.defaults, {
treeShowField: null,
idField: 'id',
parentIdField: 'pid',
rootParentId: null,
onGetNodes: function (row, data) {
var that = this;
var nodes = [];
$.each(data, function (i, item) {
if (row[that.options.idField] === item[that.options.parentIdField]) {
nodes.push(item);
}
});
return nodes;
},
onCheckRoot: function (row, data) {
var that = this;
return that.options.rootParentId === row[that.options.parentIdField] ||
!row[that.options.parentIdField];
}
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_init = BootstrapTable.prototype.init,
_initRow = BootstrapTable.prototype.initRow,
_initHeader = BootstrapTable.prototype.initHeader,
_rowStyle = null;
BootstrapTable.prototype.init = function () {
_rowStyle = this.options.rowStyle;
_init.apply(this, Array.prototype.slice.apply(arguments));
};
// td
BootstrapTable.prototype.initHeader = function () {
var that = this;
_initHeader.apply(that, Array.prototype.slice.apply(arguments));
var treeShowField = that.options.treeShowField;
if (treeShowField) {
$.each(this.header.fields, function (i, field) {
if (treeShowField === field) {
that.treeEnable = true;
return false;
}
});
}
};
var initTr = function (item, idx, data, parentDom) {
var that = this;
var nodes = that.options.onGetNodes.apply(that, [item, data]);
item._nodes = nodes;
parentDom.append(_initRow.apply(that, [item, idx, data, parentDom]));
// init sub node
var len = nodes.length - 1;
for (var i = 0; i <= len; i++) {
var node = nodes[i];
node._level = item._level + 1;
node._parent = item;
if (i === len)
node._last = 1;
// jquery.treegrid.js
that.options.rowStyle = function (item, idx) {
var res = _rowStyle.apply(that, Array.prototype.slice.apply(arguments));
var id = item[that.options.idField] ? item[that.options.idField] : 0;
var pid = item[that.options.parentIdField] ? item[that.options.parentIdField] : 0;
res.classes = [
res.classes || '',
'treegrid-' + id,
'treegrid-parent-' + pid
].join(' ');
return res;
};
initTr.apply(that, [node, $.inArray(node, data), data, parentDom]);
}
};
// tr
BootstrapTable.prototype.initRow = function (item, idx, data, parentDom) {
var that = this;
if (that.treeEnable) {
// init root node
if (that.options.onCheckRoot.apply(that, [item, data])) {
if (item._level === undefined) {
item._level = 0;
}
// jquery.treegrid.js
that.options.rowStyle = function (item, idx) {
var res = _rowStyle.apply(that, Array.prototype.slice.apply(arguments));
var x = item[that.options.idField] ? item[that.options.idField] : 0;
res.classes = [
res.classes || '',
'treegrid-' + x
].join(' ');
return res;
};
initTr.apply(that, [item, idx, data, parentDom]);
return true;
}
return false;
}
return _initRow.apply(that, Array.prototype.slice.apply(arguments));
};
}(jQuery);

View File

@ -0,0 +1,17 @@
{
"name": "treegrid",
"version": "1.0.0",
"description": "Plugin to support the jquery treegrid.",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/treegrid",
"example": "https://github.com/wenzhixin/bootstrap-table-examples/blob/master/extensions/treegrid.html",
"plugins": [{
"name": "bootstrap-table-treegrid",
"url": "https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/treegrid"
}],
"author": {
"name": "foreveryang321",
"image": "https://avatars0.githubusercontent.com/u/5868190"
}
}

View File

@ -0,0 +1,3 @@
/nbproject
/node_modules
/bower_modules

View File

@ -0,0 +1,43 @@
== 0.3.0 - 03 February 2015
* Perfomance optimization
* Bootstrap 3 update
* Add minifiyed js
* Add npm installation
* Add borew installation
== 0.2.1 - 21 January 2014
* Add events support
== 0.1.9 - 18 December 2013
* Fix table in table bug (thanks liuspcn)
== 0.1.8 - 16 December 2013
* Fix support alphanumeric id (you can use "-" symbol in id)
== 0.1.7 - 15 November 2013
* Fix isLast method. https://github.com/maxazan/jquery-treegrid/issues/4
* Add isFirst method
== 0.1.6 - 14 November 2013
* Add isNode method
* Add getAllNodes method
* Fix isLast method. Throw error if method is not node of tree.
== 0.1.5
* Add support alphanumeric id
== 0.1.4
* Add treeRow parameter
== 0.1.3 - 28 August 2013
* Added bootstrap examples
* Changed expander functionality
* Fixed $.data set and get
* Fixed $.extends settings
* Adding new test
== 0.1.2 - 26 August 2013
* Added save state
== 0.1.0 - 15 August 2013
* Public release

View File

@ -0,0 +1,23 @@
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= pkg.version %> */\n'
},
build: {
src: 'js/jquery.treegrid.js',
dest: 'js/jquery.treegrid.min.js'
}
}
});
// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');
// Default task(s).
grunt.registerTask('default', ['uglify']);
};

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,21 @@
TreeGrid plugin for jQuery
==========
See more information at http://maxazan.github.io/jquery-treegrid
## Installation
### Using npm
```
npm install jquery-treegrid
```
### Using bower
```
bower install jquery-treegrid
```
### From source
Download [source](https://github.com/maxazan/jquery-treegrid/archive/master.zip) from github.com

View File

@ -0,0 +1,33 @@
{
"name": "jquery-treegrid",
"description": "TreeGrid plugin for jQuery.",
"version": "0.3.0",
"homepage": "http://maxazan.github.io/jquery-treegrid",
"license": "MIT",
"ignore": [
"examples",
"tests",
"**/.*",
"composer.json",
"index.html",
"params.json",
"style.css",
"test.html",
"treegrid.jquery.json"
],
"keywords": [
"jquery",
"javascript",
"plugin",
"bootstrap",
"treegrid",
"treeview"
],
"dependencies": {
"jquery": ">= 1.9.1",
"jquery.cookie": ">= 1.4.1"
},
"authors": [
"Maksym Pomazan"
]
}

View File

@ -0,0 +1,12 @@
{
"name": "maxazan/jquery-treegrid",
"description": "jquery treegrid plugin",
"keywords": ["jquery", "grid", "treegrid", "tree"],
"homepage": "http://maxazan.github.io/jquery-treegrid",
"type": "library",
"license": "MIT",
"support": {
"issues": "https://github.com/maxazan/jquery-treegrid/issues",
"source": "https://github.com/maxazan/jquery-treegrid"
}
}

View File

@ -0,0 +1,6 @@
.treegrid-indent {width:16px; height: 16px; display: inline-block; position: relative;}
.treegrid-expander {width:16px; height: 16px; display: inline-block; position: relative; cursor: pointer;}
.treegrid-expander-expanded{background-image: url(../img/collapse.png); }
.treegrid-expander-collapsed{background-image: url(../img/expand.png);}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,131 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>Jquery-treegrid basic example</title>
<link rel="stylesheet" href="../styles.css">
<link rel="stylesheet" href="http://yandex.st/highlightjs/7.3/styles/default.min.css">
<link rel="stylesheet" href="../css/jquery.treegrid.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="../js/jquery.treegrid.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.tree').treegrid();
});
</script>
<script src="http://yandex.st/highlightjs/7.3/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script>
(function(i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function() {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-43342702-1', 'maxazan.github.io');
ga('send', 'pageview');
</script>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<h1><a href="http://maxazan.github.io/jquery-treegrid/">TreeGrid</a> Basic example</h1>
<table class="tree">
<tr class="treegrid-1">
<td>Root node</td><td>Additional info</td>
</tr>
<tr class="treegrid-2 treegrid-parent-1">
<td>Node 1-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-3 treegrid-parent-1">
<td>Node 1-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-4 treegrid-parent-3">
<td>Node 1-2-1</td><td>Additional info</td>
</tr>
</table>
<h2>Code</h2>
<pre>
<code class='html'>
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot;&gt;
&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;chrome=1&quot;&gt;
&lt;title&gt;Jquery-treegrid basic example&lt;/title&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;../css/jquery.treegrid.css&quot;&gt;
&lt;script src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function() {
$('.tree').treegrid();
});
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;table class=&quot;tree&quot;&gt;
&lt;tr class=&quot;treegrid-1&quot;&gt;
&lt;td&gt;Root node&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-2 treegrid-parent-1&quot;&gt;
&lt;td&gt;Node 1-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-3 treegrid-parent-1&quot;&gt;
&lt;td&gt;Node 1-2&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-4 treegrid-parent-3&quot;&gt;
&lt;td&gt;Node 1-2-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
</code>
</pre>
</div>
<script type="text/javascript">
var metas = document.getElementsByTagName('meta');
var i;
if (navigator.userAgent.match(/iPhone/i)) {
for (i = 0; i < metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
}
}
document.addEventListener("gesturestart", gestureStart, false);
}
function gestureStart() {
for (i = 0; i < metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
}
}
}</script>
</body>
</html>

View File

@ -0,0 +1,144 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="../../assets/ico/favicon.png">
<title>TreeGrid for Bootstrap 2.3.x</title>
<!-- Bootstrap core CSS -->
<link href="bootstrap-2.3.2/css/bootstrap.css" rel="stylesheet">
<link rel="stylesheet" href="../css/jquery.treegrid.css">
<link rel="stylesheet" href="http://yandex.st/highlightjs/7.3/styles/default.min.css">
<script src="http://yandex.st/highlightjs/7.3/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="../js/jquery.treegrid.js"></script>
<script type="text/javascript" src="../js/jquery.treegrid.bootstrap2.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.tree').treegrid();
$('.tree2').treegrid({
expanderExpandedClass: 'icon-minus-sign',
expanderCollapsedClass: 'icon-plus-sign'
});
});
</script>
<script>
(function(i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function() {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-43342702-1', 'maxazan.github.io');
ga('send', 'pageview');
</script>
</head>
<body>
<div class="container">
<h1><a href="http://maxazan.github.io/jquery-treegrid/">TreeGrid</a> Bootstrap 2.3.2 examples</h1>
<table class="table tree">
<tr class="treegrid-1">
<td>Root node 1</td><td>Additional info</td>
</tr>
<tr class="treegrid-2 treegrid-parent-1">
<td>Node 1-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-3 treegrid-parent-1">
<td>Node 1-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-4 treegrid-parent-3">
<td>Node 1-2-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-5">
<td>Root node 2</td><td>Additional info</td>
</tr>
<tr class="treegrid-6 treegrid-parent-5">
<td>Node 2-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-7 treegrid-parent-5">
<td>Node 2-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-8 treegrid-parent-7">
<td>Node 2-2-1</td><td>Additional info</td>
</tr>
</table>
<h3>Source</h3>
<pre><code class="html">&lt;link href=&quot;bootstrap-2.3.2/css/bootstrap.css&quot; rel=&quot;stylesheet&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;../css/jquery.treegrid.css&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.bootstrap2.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function() {
$(&#39;.tree&#39;).treegrid();
});
&lt;/script&gt;</code></pre>
<h2>Bootstrap grid example<br>
table-bordered table-striped table-condensed<br>
with custom expander</h2>
<table class="table tree2 table-bordered table-striped table-condensed">
<tr class="treegrid-1">
<td>Root node 1</td><td>Additional info</td>
</tr>
<tr class="treegrid-2 treegrid-parent-1">
<td>Node 1-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-3 treegrid-parent-1">
<td>Node 1-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-4 treegrid-parent-3">
<td>Node 1-2-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-5">
<td>Root node 2</td><td>Additional info</td>
</tr>
<tr class="treegrid-6 treegrid-parent-5">
<td>Node 2-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-7 treegrid-parent-5">
<td>Node 2-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-8 treegrid-parent-7">
<td>Node 2-2-1</td><td>Additional info</td>
</tr>
</table>
<h3>Source</h3>
<pre><code class="html">&lt;link href=&quot;bootstrap-2.3.2/css/bootstrap.css&quot; rel=&quot;stylesheet&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;../css/jquery.treegrid.css&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.bootstrap2.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function() {
$('.tree').treegrid({
expanderExpandedClass: 'icon-minus-sign',
expanderCollapsedClass: 'icon-plus-sign'
});
});
&lt;/script&gt;</code></pre>
</div> <!-- /container -->
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
</body>
</html>

View File

@ -0,0 +1,146 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="../../assets/ico/favicon.png">
<title>TreeGrid for Bootstrap 3.0.x</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="../css/jquery.treegrid.css">
<link rel="stylesheet" href="http://yandex.st/highlightjs/7.3/styles/default.min.css">
<script src="http://yandex.st/highlightjs/7.3/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="../js/jquery.treegrid.js"></script>
<script type="text/javascript" src="../js/jquery.treegrid.bootstrap3.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.tree').treegrid();
$('.tree-2').treegrid({
expanderExpandedClass: 'glyphicon glyphicon-minus',
expanderCollapsedClass: 'glyphicon glyphicon-plus'
});
});
</script>
<script>
(function(i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function() {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-43342702-1', 'maxazan.github.io');
ga('send', 'pageview');
</script>
</head>
<body>
<div class="container">
<h1><a href="http://maxazan.github.io/jquery-treegrid/">TreeGrid</a> Bootstrap 3 examples</h1>
<table class="table tree">
<tr class="treegrid-1">
<td>Root node 1</td><td>Additional info</td>
</tr>
<tr class="treegrid-2 treegrid-parent-1">
<td>Node 1-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-3 treegrid-parent-1">
<td>Node 1-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-4 treegrid-parent-3">
<td>Node 1-2-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-5">
<td>Root node 2</td><td>Additional info</td>
</tr>
<tr class="treegrid-6 treegrid-parent-5">
<td>Node 2-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-7 treegrid-parent-5">
<td>Node 2-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-8 treegrid-parent-7">
<td>Node 2-2-1</td><td>Additional info</td>
</tr>
</table>
<h3>Code</h3>
<pre><code class="html">&lt;link href=&quot;bootstrap-3.0.0/css/bootstrap.css&quot; rel=&quot;stylesheet&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;../css/jquery.treegrid.css&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.bootstrap3.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function() {
$(&#39;.tree&#39;).treegrid();
});
&lt;/script&gt;</code></pre>
<h2>Bootstrap TreeGrid example<br>
table-bordered table-striped table-condensed<br>
custom expander</h2>
<table class="table tree-2 table-bordered table-striped table-condensed">
<tr class="treegrid-1">
<td>Root node 1</td><td>Additional info</td>
</tr>
<tr class="treegrid-2 treegrid-parent-1">
<td>Node 1-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-3 treegrid-parent-1">
<td>Node 1-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-4 treegrid-parent-3">
<td>Node 1-2-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-5">
<td>Root node 2</td><td>Additional info</td>
</tr>
<tr class="treegrid-6 treegrid-parent-5">
<td>Node 2-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-7 treegrid-parent-5">
<td>Node 2-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-8 treegrid-parent-7">
<td>Node 2-2-1</td><td>Additional info</td>
</tr>
</table>
<h3>Code</h3>
<pre><code class="html">&lt;link href=&quot;bootstrap-3.0.0/css/bootstrap.css&quot; rel=&quot;stylesheet&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;../css/jquery.treegrid.css&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.bootstrap3.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function() {
$(&#39;.tree&#39;).treegrid({
expanderExpandedClass: &#39;glyphicon glyphicon-minus&#39;,
expanderCollapsedClass: &#39;glyphicon glyphicon-plus&#39;
});
});
&lt;/script&gt;</code></pre>
</div> <!-- /container -->
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
</body>
</html>

View File

@ -0,0 +1,146 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="../../assets/ico/favicon.png">
<title>TreeGrid for Bootstrap 3.0.x</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="../css/jquery.treegrid.css">
<link rel="stylesheet" href="http://yandex.st/highlightjs/7.3/styles/default.min.css">
<script src="http://yandex.st/highlightjs/7.3/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="../js/jquery.treegrid.js"></script>
<script type="text/javascript" src="../js/jquery.treegrid.bootstrap3.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.tree').treegrid();
$('.tree-2').treegrid({
expanderExpandedClass: 'glyphicon glyphicon-minus',
expanderCollapsedClass: 'glyphicon glyphicon-plus'
});
});
</script>
<script>
(function(i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function() {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-43342702-1', 'maxazan.github.io');
ga('send', 'pageview');
</script>
</head>
<body>
<div class="container">
<h1><a href="http://maxazan.github.io/jquery-treegrid/">TreeGrid</a> Bootstrap 3 resize examples</h1>
<table class="table tree">
<tr class="treegrid-1">
<td>Root node 1</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-2 treegrid-parent-1">
<td>Node 1-1</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-3 treegrid-parent-1">
<td>Node 1-2</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-4 treegrid-parent-3">
<td>Node 1-2-1</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-5">
<td>Root node 2</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-6 treegrid-parent-5">
<td>Node 2-1</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-7 treegrid-parent-5">
<td>Node 2-2</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-8 treegrid-parent-7">
<td>Node 2-2-1</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
</table>
<h3>Code</h3>
<pre><code class="html">&lt;link href=&quot;bootstrap-3.0.0/css/bootstrap.css&quot; rel=&quot;stylesheet&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;../css/jquery.treegrid.css&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.bootstrap3.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function() {
$(&#39;.tree&#39;).treegrid();
});
&lt;/script&gt;</code></pre>
<h2>Bootstrap TreeGrid example<br>
table-bordered table-striped table-condensed<br>
custom expander</h2>
<table class="table tree-2 table-bordered table-striped table-condensed">
<tr class="treegrid-1">
<td>Root node 1</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-2 treegrid-parent-1">
<td>Node 1-1</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-3 treegrid-parent-1">
<td>Node 1-2</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-4 treegrid-parent-3">
<td>Node 1-2-1</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-5">
<td>Root node 2</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-6 treegrid-parent-5">
<td>Node 2-1</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-7 treegrid-parent-5">
<td>Node 2-2</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
<tr class="treegrid-8 treegrid-parent-7">
<td>Node 2-2-1</td><td class="hidden-xs">Additional info</td><td class="hidden-xs hidden-sm">Additional info2</td><td class="hidden-xs hidden-sm hidden-md">Additional info3</td>
</tr>
</table>
<h3>Code</h3>
<pre><code class="html">&lt;link href=&quot;bootstrap-3.0.0/css/bootstrap.css&quot; rel=&quot;stylesheet&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;../css/jquery.treegrid.css&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.bootstrap3.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function() {
$(&#39;.tree&#39;).treegrid({
expanderExpandedClass: &#39;glyphicon glyphicon-minus&#39;,
expanderCollapsedClass: &#39;glyphicon glyphicon-plus&#39;
});
});
&lt;/script&gt;</code></pre>
</div> <!-- /container -->
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
</body>
</html>

View File

@ -0,0 +1,135 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>TreeGrid example with tree in 2nd column</title>
<link rel="stylesheet" href="../styles.css">
<link rel="stylesheet" href="http://yandex.st/highlightjs/7.3/styles/default.min.css">
<link rel="stylesheet" href="../css/jquery.treegrid.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="../js/jquery.treegrid.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.tree').treegrid({
treeColumn: 1
});
});
</script>
<script src="http://yandex.st/highlightjs/7.3/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script>
(function(i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function() {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-43342702-1', 'maxazan.github.io');
ga('send', 'pageview');
</script>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<h1><a href="http://maxazan.github.io/jquery-treegrid/">TreeGrid</a> example with tree in 2nd column</h1>
<table class="tree">
<tr class="treegrid-1">
<td>Root node</td><td>Additional info</td>
</tr>
<tr class="treegrid-2 treegrid-parent-1">
<td>Node 1-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-3 treegrid-parent-1">
<td>Node 1-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-4 treegrid-parent-3">
<td>Node 1-2-1</td><td>Additional info</td>
</tr>
</table>
<h2>Code</h2>
<pre>
<code class='html'>
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot;&gt;
&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;chrome=1&quot;&gt;
&lt;title&gt;Jquery-treegrid basic example&lt;/title&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;../css/jquery.treegrid.css&quot;&gt;
&lt;script src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function() {
$('.tree').treegrid({
treeColumn: 1
});
});
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;table class=&quot;tree&quot;&gt;
&lt;tr class=&quot;treegrid-1&quot;&gt;
&lt;td&gt;Root node&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-2 treegrid-parent-1&quot;&gt;
&lt;td&gt;Node 1-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-3 treegrid-parent-1&quot;&gt;
&lt;td&gt;Node 1-2&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-4 treegrid-parent-3&quot;&gt;
&lt;td&gt;Node 1-2-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
</code>
</pre>
</div>
<script type="text/javascript">
var metas = document.getElementsByTagName('meta');
var i;
if (navigator.userAgent.match(/iPhone/i)) {
for (i = 0; i < metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
}
}
document.addEventListener("gesturestart", gestureStart, false);
}
function gestureStart() {
for (i = 0; i < metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
}
}
}</script>
</body>
</html>

View File

@ -0,0 +1,155 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>TreeGrid events example</title>
<link rel="stylesheet" href="../styles.css">
<link rel="stylesheet" href="http://yandex.st/highlightjs/7.3/styles/default.min.css">
<link rel="stylesheet" href="../css/jquery.treegrid.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="../js/jquery.treegrid.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.tree').treegrid({
onChange: function() {
alert("Changed: " + $(this).attr("id"));
},
onCollapse: function() {
alert("Collapsed " + $(this).attr("id"));
},
onExpand: function() {
alert("Expanded: " + $(this).attr("id"));
}});
$('#node-1').on("change", function() {
alert("Event from " + $(this).attr("id"));
});
});
</script>
<script src="http://yandex.st/highlightjs/7.3/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script>
(function(i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function() {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-43342702-1', 'maxazan.github.io');
ga('send', 'pageview');
</script>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<h1><a href="http://maxazan.github.io/jquery-treegrid/">TreeGrid</a> events example</h1>
<table class="tree">
<tr id="node-1" class="treegrid-1">
<td>Root node</td><td>Additional info</td>
</tr>
<tr id="node-1-1" class="treegrid-2 treegrid-parent-1">
<td>Node 1-1</td><td>Additional info</td>
</tr>
<tr id="node-1-2" class="treegrid-3 treegrid-parent-1">
<td>Node 1-2</td><td>Additional info</td>
</tr>
<tr id="node-1-2-1" class="treegrid-4 treegrid-parent-3">
<td>Node 1-2-1</td><td>Additional info</td>
</tr>
</table>
<h2>Code</h2>
<pre>
<code class='html'>
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot;&gt;
&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;chrome=1&quot;&gt;
&lt;title&gt;Jquery-treegrid basic example&lt;/title&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;../css/jquery.treegrid.css&quot;&gt;
&lt;script src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function() {
$('.tree').treegrid({
onChange: function() {
alert("Changed: "+$(this).attr("id"));
},
onCollapse: function() {
alert("Collapsed: "+$(this).attr("id"));
},
onExpand: function() {
alert("Expanded "+$(this).attr("id"));
}});
$('#node-1').on("change", function() {
alert("Event from " + $(this).attr("id"));
});
});
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;table class=&quot;tree&quot;&gt;
&lt;tr class=&quot;treegrid-1&quot;&gt;
&lt;td&gt;Root node&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-2 treegrid-parent-1&quot;&gt;
&lt;td&gt;Node 1-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-3 treegrid-parent-1&quot;&gt;
&lt;td&gt;Node 1-2&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-4 treegrid-parent-3&quot;&gt;
&lt;td&gt;Node 1-2-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
</code>
</pre>
</div>
<script type="text/javascript">
var metas = document.getElementsByTagName('meta');
var i;
if (navigator.userAgent.match(/iPhone/i)) {
for (i = 0; i < metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
}
}
document.addEventListener("gesturestart", gestureStart, false);
}
function gestureStart() {
for (i = 0; i < metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
}
}
}</script>
</body>
</html>

View File

@ -0,0 +1,113 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>Jquery-treegrid basic example</title>
<link rel="stylesheet" href="../styles.css">
<link rel="stylesheet" href="../css/jquery.treegrid.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="../js/jquery.treegrid.js"></script>
<script type="text/javascript">
$(document).ready(function() {
//create huge treetable
var count_root_elements=100;
var count_deep=10;
console.log('init');
for(var i=0; i<count_root_elements; i++){
console.log('add');
var tr=$("<tr></tr>").addClass("treegrid-"+i+"-0").appendTo($('.tree')).html("<td>Root node "+i+"</td><td>Additional info</td>");
for(var j=1; j<count_deep; j++){
$("<tr></tr>").addClass("treegrid-"+i+"-"+j).addClass("treegrid-parent-"+i+"-"+(j-1)).appendTo($('.tree')).html("<td>Child node "+i+"-"+j+"</td><td>Additional info</td>");
}
}
$('.tree').treegrid();
});
</script>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<h1><a href="http://maxazan.github.io/jquery-treegrid/">TreeGrid</a> Big data example</h1>
<table class="tree"></table>
<h2>Code</h2>
<pre>
<code class='html'>
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot;&gt;
&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;chrome=1&quot;&gt;
&lt;title&gt;Jquery-treegrid basic example&lt;/title&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;../css/jquery.treegrid.css&quot;&gt;
&lt;script src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function() {
$('.tree').treegrid();
});
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;table class=&quot;tree&quot;&gt;
&lt;tr class=&quot;treegrid-1&quot;&gt;
&lt;td&gt;Root node&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-2 treegrid-parent-1&quot;&gt;
&lt;td&gt;Node 1-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-3 treegrid-parent-1&quot;&gt;
&lt;td&gt;Node 1-2&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-4 treegrid-parent-3&quot;&gt;
&lt;td&gt;Node 1-2-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
</code>
</pre>
</div>
<script type="text/javascript">
var metas = document.getElementsByTagName('meta');
var i;
if (navigator.userAgent.match(/iPhone/i)) {
for (i = 0; i < metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
}
}
document.addEventListener("gesturestart", gestureStart, false);
}
function gestureStart() {
for (i = 0; i < metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
}
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,162 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>Jquery-treegrid save state example</title>
<link rel="stylesheet" href="../styles.css">
<link rel="stylesheet" href="http://yandex.st/highlightjs/7.3/styles/default.min.css">
<link rel="stylesheet" href="../css/jquery.treegrid.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="../js/jquery.treegrid.js"></script>
<script type="text/javascript" src="../js/jquery.cookie.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.tree').treegrid({
'initialState': 'collapsed',
'saveState': true,
});
});
</script>
<script src="http://yandex.st/highlightjs/7.3/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script>
(function(i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function() {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-43342702-1', 'maxazan.github.io');
ga('send', 'pageview');
</script>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<h1><a href="http://maxazan.github.io/jquery-treegrid/">TreeGrid</a> save state example</h1>
<p>You can reload page. The tree state is saved.</p>
<table class="tree">
<tr class="treegrid-1">
<td>Root node 1</td><td>Additional info</td>
</tr>
<tr class="treegrid-2 treegrid-parent-1">
<td>Node 1-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-3 treegrid-parent-1">
<td>Node 1-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-4 treegrid-parent-3">
<td>Node 1-2-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-5">
<td>Root node 2</td><td>Additional info</td>
</tr>
<tr class="treegrid-6 treegrid-parent-5">
<td>Node 2-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-7 treegrid-parent-5">
<td>Node 2-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-8 treegrid-parent-7">
<td>Node 2-2-1</td><td>Additional info</td>
</tr>
</table>
<h2>Code</h2>
<pre>
<code class='html'>
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot;&gt;
&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;chrome=1&quot;&gt;
&lt;title&gt;Jquery-treegrid basic example&lt;/title&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;../css/jquery.treegrid.css&quot;&gt;
&lt;script src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../js/jquery.treegrid.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function() {
$('.tree').treegrid({
'initialState': 'collapsed',
'saveState': true,
});
});
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;table class=&quot;tree&quot;&gt;
&lt;tr class=&quot;treegrid-1&quot;&gt;
&lt;td&gt;Root node 1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-2 treegrid-parent-1&quot;&gt;
&lt;td&gt;Node 1-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-3 treegrid-parent-1&quot;&gt;
&lt;td&gt;Node 1-2&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-4 treegrid-parent-3&quot;&gt;
&lt;td&gt;Node 1-2-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-5&quot;&gt;
&lt;td&gt;Root node 2&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-6 treegrid-parent-5&quot;&gt;
&lt;td&gt;Node 2-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-7 treegrid-parent-5&quot;&gt;
&lt;td&gt;Node 2-2&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;treegrid-8 treegrid-parent-7&quot;&gt;
&lt;td&gt;Node 2-2-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
</code>
</pre>
</div>
<script type="text/javascript">
var metas = document.getElementsByTagName('meta');
var i;
if (navigator.userAgent.match(/iPhone/i)) {
for (i = 0; i < metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
}
}
document.addEventListener("gesturestart", gestureStart, false);
}
function gestureStart() {
for (i = 0; i < metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
}
}
}</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

View File

@ -0,0 +1,478 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="google-site-verification" content="Qsvvve1CBtl2_PikToO7CdVGsY7bwLrjc_9AgZtt_bk" />
<title>Treegrid jquery plugin</title>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="http://yandex.st/highlightjs/7.3/styles/default.min.css">
<link rel="stylesheet" href="css/jquery.treegrid.css">
<script src="http://yandex.st/highlightjs/7.3/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script>
(function(i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function() {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-43342702-1', 'maxazan.github.io');
ga('send', 'pageview');
</script>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<ul class="download" style="float:right;">
<li><a href="https://github.com/maxazan/jquery-treegrid/zipball/master">Download <br><strong>ZIP File</strong></a></li>
<li><a href="https://github.com/maxazan/jquery-treegrid/tarball/master">Download <br><strong>TAR Ball</strong></a></li>
<li><a href="https://github.com/maxazan/jquery-treegrid">View On <br><strong>GitHub</strong></a></li>
</ul>
<h1>TreeGrid jQuery plugin</h1>
<h2>Features</h2>
<ul>
<li>Create TreeGrid from HTML table</li>
<li>Simple and flexible javascript</li>
<li>Compatible with bootstrap</li>
<li>Ability to save the state of the tree</li>
<li>Events support</li>
</ul>
<h2>Usage</h2>
<p>Step 1. Initialize plugin</p>
<pre><code>
&lt;script type="text/javascript" src="js/jquery.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="js/jquery.treegrid.js"&gt;&lt;/script&gt;
&lt;link rel="stylesheet" href="css/jquery.treegrid.css"&gt;
&lt;script type="text/javascript"&gt;
$('.tree').treegrid();
&lt;/script&gt;</code></pre>
<p>Step 2. Make table</p>
<pre><code class="html">
&lt;table class="tree"&gt;
&lt;tr class="treegrid-1"&gt;
&lt;td&gt;Root node&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="treegrid-2 treegrid-parent-1"&gt;
&lt;td&gt;Node 1-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="treegrid-3 treegrid-parent-1"&gt;
&lt;td&gt;Node 1-2&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="treegrid-4 treegrid-parent-3"&gt;
&lt;td&gt;Node 1-2-1&lt;/td&gt;&lt;td&gt;Additional info&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
</code></pre>
<p>Step 3. See result</p>
<table class="tree">
<tr class="treegrid-1">
<td>Root node</td><td>Additional info</td>
</tr>
<tr class="treegrid-2 treegrid-parent-1">
<td>Node 1-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-3 treegrid-parent-1">
<td>Node 1-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-4 treegrid-parent-3">
<td>Node 1-2-1</td><td>Additional info</td>
</tr>
</table>
<h2>Other examples</h2>
<p><a href="examples/example-basic.html" target="_blank">Basic example</a></p>
<p><a href="examples/example-column.html" target="_blank">Tree on 2nd column example</a></p>
<p><a href="examples/example-save-state.html" target="_blank">Save state example</a></p>
<p><a href="examples/example-bootstrap-2.html" target="_blank">TreeGrid for bootstrap 2.x</a></p>
<p><a href="examples/example-bootstrap-3.html" target="_blank">TreeGrid for bootstrap 3.x</a></p>
<p><a href="examples/example-bootstrap-resize.html" target="_blank">TreeGrid for bootstrap 3.x resize demo</a></p>
<p><a href="examples/example-events.html" target="_blank">Events examples</a></p>
<p><a href="examples/example-huge.html" target="_blank">Big data example</a></p>
<h2>Configuration Settings</h2>
<h3>Settings</h3>
<table>
<tr><th>Parameter</th><th>Type</th><th>Default value</th><th>Description</th></tr>
<tr>
<td>treeColumn</td>
<td>Numeric</td>
<td>0</td>
<td>Number of column using for tree</td>
</tr>
<tr>
<td>initialState</td>
<td>String</td>
<td>expanded</td>
<td>Initial state of tree<br>
'expanded' - all nodes will be expanded<br>
'collapsed' - all nodes will be collapsed<br>
</td>
</tr>
<tr>
<td>saveState</td>
<td>Boolean</td>
<td>false</td>
<td>If true you can reload page and tree state was saved</td>
</tr>
<tr>
<td>saveStateMethod</td>
<td>String</td>
<td>cookie</td>
<td>
'cookie' - save state to cookie<br>
'hash' - save state to hash<br>
</td>
</tr>
<tr>
<td>saveStateName</td>
<td>String</td>
<td>tree-grid-state</td>
<td>
Name of cookie or hash to save state.
</td>
</tr>
<tr>
<td>expanderTemplate</td>
<td>String</td>
<td>&lt;span class="treegrid-expander"&gt;&lt;/span&gt;</td>
<td>HTML Element when you click on that will be collapse/expand branches</td>
</tr>
<tr>
<td>expanderExpandedClass</td>
<td>String</td>
<td>treegrid-expander-expanded</td>
<td>Class using for expander element when it expanded</td>
</tr>
<tr>
<td>expanderCollapsedClass</td>
<td>String</td>
<td>treegrid-expander-collapsed</td>
<td>Class using for expander element when it collapsed</td>
</tr>
<tr>
<td>indentTemplate</td>
<td>String</td>
<td>&lt;span class="treegrid-indent"&gt;&lt;/span&gt;</td>
<td>HTML Element that will be placed as padding, depending on the depth of nesting node</td>
</tr>
<tr>
<td>onCollapse</td>
<td>Function</td>
<td>null</td>
<td>Function, which will be executed when one of node will be collapsed</td>
</tr>
<tr>
<td>onExpand</td>
<td>Function</td>
<td>null</td>
<td>Function, which will be executed when one of node will be expanded</td>
</tr>
<tr>
<td>onChange</td>
<td>Function</td>
<td>null</td>
<td>Function, which will be executed when one of node will be expanded or collapsed</td>
</tr>
</table>
<h3>Public methods</h3>
<table>
<tr>
<th>Method name</th>
<th>Description</th>
<th>Example</th>
</tr>
<tr>
<td>getRootNodes</td>
<td>Returns the root branches</td>
<td>
<pre><code class="javascript">// Expand all root nodes
$('.tree').treegrid('getRootNodes').treegrid('expand');</code></pre>
</td>
</tr>
<tr>
<td>getNodeId</td>
<td>Return the id of node</td>
<td>
<pre><code class="javascript">if($('#node-2').treegrid('getNodeId')===2){
// Do something with node 2
};</code></pre>
</td>
</tr>
<tr>
<td>getParentNodeId</td>
<td>Return the id of parent node or null if node is root</td>
<td>
<pre><code class="javascript">if($('#node-2').treegrid('getParentNodeId')===2){
// Do something if parent node Id is 2
};</code></pre>
</td>
</tr>
<tr>
<td>getAllNodes</td>
<td>Return the all nodes of tree</td>
<td>
<pre><code class="javascript">// Find all nodes
$('#tree-1').treegrid('getAllNodes').each(function() {
if ($(this).treegrid("isLast")) {
//Do something with all last nodes
}
});
</code></pre>
</td>
</tr>
<tr>
<td>getParentNode</td>
<td>Return the parent node or null if node is root</td>
<td>
<pre><code class="javascript">// Expand parent node
$('#node-2').treegrid('getParentNode').treegrid('collapse');
</code></pre>
</td>
</tr>
<tr>
<td>getChildNodes</td>
<td>Return the child nodes or null if node is leaf</td>
<td>
<pre><code class="javascript">// Expand child nodes
$('#node-2').treegrid('getChildNodes').treegrid('expand');
</code></pre>
</td>
</tr>
<tr>
<td>getDepth</td>
<td>Returns the depth of nested branch</td>
<td>
<pre><code class="javascript">// Expand all nodes 2nd nesting
$('.tree').find('tr').each(function(){
if ($(this).treegrid('getDepth')<2){
$(this).treegrid('expand');
}
});</code></pre>
</td>
<tr>
<td>isNode</td>
<td>return true if element is node</td>
<td>
<pre><code class="javascript">
$('#tree-1').find('tr').each(function() {
if ($(this).treegrid("isNode")) {
//Do something
}
});
</code></pre>
</td>
</tr>
<tr>
<td>isLeaf</td>
<td>Is there a node leaf</td>
<td>
<pre><code class="javascript">// hide all files
$('.tree').find('tr').each(function(){
if ($(this).treegrid('isLeaf')){
$(this).hide();
}
});</code></pre>
</td>
</tr>
<tr>
<td>isLast</td>
<td>Return true if node is last in branch</td>
<td>
<pre><code class="javascript">// hide all last elements
$('.tree').find('tr').each(function(){
if ($(this).treegrid('isLast')){
$(this).hide();
}
});</code></pre>
</td>
</tr>
<tr>
<td>isFirst</td>
<td>Return true if node is first in branch</td>
<td>
<pre><code class="javascript">// hide all last elements
$('.tree').find('tr').each(function(){
if ($(this).treegrid('isFirst')){
$(this).hide();
}
});</code></pre>
</td>
</tr>
<tr>
<td>isExpanded</td>
<td>Is node expanded</td>
<td>
<pre><code class="javascript">if($('#node-2').treegrid('isExpanded')){
// Do something if node expanded
};</code></pre>
</td>
</tr>
<tr>
<td>isCollapsed</td>
<td>Is node collapsed</td>
<td>
<pre><code class="javascript">if($('#node-2').treegrid('isCollapsed')){
// Do something if node collapsed
};</code></pre>
</td>
</tr>
<tr>
<td>isOneOfParentsCollapsed</td>
<td>Is at least one of the parent nodes is collapsed</td>
<td>
<pre><code class="javascript">if($('#node-2').treegrid('isOneOfParentCollapsed')){
// Do something if one of parent collapsed
};</code></pre>
</td>
</tr>
<tr>
<td>expand</td>
<td>Expand node</td>
<td>
<pre><code class="javascript">$('#node-2').treegrid('expand');</code></pre>
</td>
</tr>
<tr>
<td>collapse</td>
<td>Collapse node</td>
<td>
<pre><code class="javascript">$('#node-2').treegrid('collapse');</code></pre>
</td>
</tr>
<tr>
<td>expandRecursive</td>
<td>Expand nodes recursively</td>
<td>
<pre><code class="javascript">$('#node-2').treegrid('expandRecursive');</code></pre>
</td>
</tr>
<tr>
<td>collapseRecursive</td>
<td>Collapse nodes recursively</td>
<td>
<pre><code class="javascript">$('#node-2').treegrid('collapseRecursive');</code></pre>
</td>
</tr>
<tr>
<td>expandAll</td>
<td>Expand all nodes</td>
<td>
<pre><code class="javascript">$('#tree').treegrid('expandAll');</code></pre>
</td>
</tr>
<tr>
<td>collapseAll</td>
<td>Collapse all nodes</td>
<td>
<pre><code class="javascript">$('#tree').treegrid('collapseAll');</code></pre>
</td>
</tr>
<tr>
<td>toggle</td>
<td>Collapse node if it expanded and expand when collapsed</td>
<td>
<pre><code class="javascript">$('#node-2').treegrid('toggle');</code></pre>
</td>
</tr>
<tr>
<td>render</td>
<td>Redraw the node and all its children</td>
<td>
<pre><code class="javascript">$('#node-2').treegrid('render');</code></pre>
</td>
</tr>
</table>
<h3>Events</h3>
<table>
<tr>
<th>Event name</th>
<th>Description</th>
<th>Example</th>
</tr>
<tr>
<td>collapse</td>
<td>Will fire when node collapsed</td>
<td>
<pre><code class="javascript">//Alert when node in treegrid with class "tree" collapsed
$('.tree').treegrid('getRootNodes').on('collapse', function(){
alert(this);
});</code></pre>
</td>
</tr>
<tr>
<td>expand</td>
<td>Will fire when node expanded</td>
<td>
<pre><code class="javascript">//Alert when node with id "node1" expanded
$('#node1').on('expand', function(){
alert(this);
});</code></pre>
</td>
</tr>
<tr>
<td>change</td>
<td>Will fire when node changed. Expanded or collapsed</td>
<td>
<pre><code class="javascript">//Alert when node in treegrid with class "tree" changed.
$('.tree').treegrid('getRootNodes').on('change', function(){
alert(this);
});</code></pre>
</td>
</tr>
</table>
<h2><a href="test.html">Unit Tests</a></h2>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.treegrid.min.js"></script>
<script type="text/javascript">
$('.tree').treegrid();
</script>
<script type="text/javascript">
var metas = document.getElementsByTagName('meta');
var i;
if (navigator.userAgent.match(/iPhone/i)) {
for (i = 0; i < metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
}
}
document.addEventListener("gesturestart", gestureStart, false);
}
function gestureStart() {
for (i = 0; i < metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
}
}
}</script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More